1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  5. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  8. The raddest synthwave tracks were chosen - Check out our Music Contest #12 - Results and congratulate the winners!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[GUI-Friendly] Allocator Engine

Submitted by MyPad
This bundle is marked as approved. It works and satisfies the submission rules.
GUI Allocator Engine:

An allocator that does the unique index production for you!
Seize the means of index production!

Got something needs unique indexing? Don't wanna do it?
Pass it on to the working engine, and let it bear fruit. (Pray it does not revolt)


  • A standard allocation system, along with a debug message and some GUI variables.

    Eight functions; two allocators, two deallocators, one instance checker, two size checkers, and one size manipulator.

    This system also features a spell that utilizes the system in indexing. (Periodic Stun).

  • Code (vJASS):

    //! novjass
    udg_Allocator_HASH
        A hashtable variable that holds all instances. Must not be used externally, as these could jack up the system.

    udg_Allocator_DEBUG_MODE
        A simple flag variable that enables and disables debug messages. Useful in certain situations wherein you found some sort of critical bugs.

    udg_Allocator_NewKey
        An integer variable returned either when executing the Allocator Main trigger or directly calling the function Allocator_Main__allocate()

    udg_Allocator_NewIndex
        An integer variable returned either when executing the Allocator Engine trigger or directly calling the function Allocator_Engine__allocate(integer param). Expects a key to be specified.

    udg_Allocator_MainKey
        An integer variable that is specified before executing the Allocator Engine trigger.

    udg_Allocator_MainIndex
        An integer variable that is specified before executing the Allocator Engine trigger when instruction is specified to be 2.

    udg_Allocator_Instruction
        An integer variable that specifies which function to call when executing either the Allocator Main or Allocator Engine trigger. Available instructions are 2, 1 and 0, which mean validation of allocation, allocation and deallocation respectively.

    udg_Allocator_deIndex
        An integer variable parameter that is specified before executing the Allocator Engine trigger with the deallocation instruction. Requires udg_Allocator_MainKey

    udg_Allocator_deKey
        An integer variable parameter that is specified before executing the Allocator Main trigger with the deallocation instruction.

    udg_Allocator_isAllocated
        A boolean variable that is returned when calling the function Allocator_Main__IsInstanceAllocated.

    udg_Allocator_Instruction_ALLOC
        An integer variable that acts as an enum type. Use this instead of 1 for clarity.

    udg_Allocator_Instruction_DEALLOC
        An integer variable that acts as an enum type. Use this instead of 0 for clarity.

    udg_Allocator_Instruction_IS_ALLOC
        An integer variable that acts as an enum type. Use this instead of 2 for clarity.

    udg_Allocator_Instruction_RESIZE
        An integer variable that acts as an enum type. Use this instead of 3 for clarity.

    Functions:

    AllocMain_allocate() -> integer
        - Generates a new key for unique allocation.

    AllocMain_deallocate(integer i)
        - Deallocates a specified key, flushing out its' contents too.

    AllocEngine_allocate(integer k) -> integer
        - Generates a new instance from the key.
        - Does not allow mimicking of behavior in Allocator_Main__allocate()
            // e.g. specifying 0 or less as a key.

    AllocEngine_deallocate(integer k, integer i)
        - Deallocates an instance within the space of the key.

    IsInstanceAllocated(integer k, integer i) -> boolean
        - Returns the result when an instance is allocated or not.

    GetKeySize(integer k) -> integer
        - Returns the amount of active instances within a key.

    SizeOfKey(integer k) -> integer
        - (Deprecated) returns GetKeySize(k)

    GetKeyBounds(integer k) -> integer
        - Returns the maximum amount of instances within a key.

    SetKeyBounds(integer k, integer new)
        - Modifies the maximum amount of instances within a key. If done to reduce instance count, does not automatically flush excess instances.

    Instructions:

    /*
    3 -> Resize procedure. Only applicable to Allocator_Engine trigger.
    2 -> Check procedure. Only applicable to Allocator_Engine trigger.
    1 -> Allocate procedure. Applicable to both Allocator_Engine and Allocator_Main
    0 -> Deallocation procedure. Applicable to both Allocator_Engine and Allocator_Main

    In addition, when executing Allocator_Engine, the variable udg_Allocator_MainKey must be specified.
    When executing Allocator_Main and the instruction is to deallocate, the variable udg_Allocator_deKey must be specified.
    */

    //! endnovjass


  • The system can go from GUI to JASS and back. For GUI users, just follow the instruction portion of the Code API. These are delimited for you (mostly in green).

    For JASS users, you have the option to call those functions directly and I recommend such usage of said functions.

  • This version is compatible with game versions that already have hashtable API. (v.1.23.b+ or was it v.1.24?)

    This version, system-wise, complements the GUI-Friendly Linked List system.

  • Patch History:
    • v.1.0.0.0 - Release
    • v.1.1.0.0 - Exposed SizeOfKey as a convenience function.
    • v.1.2.0.0 - Added GetKeyBounds and SetKeyBounds as well as adding debug functionality to SizeOfKey. (Deprecated SizeOfKey in favor of GetKeySize)
    • v.1.2.1.0 - Renamed the allocator and deallocator functions, as well as IsInstanceAllocated. Kept backwards-compatibility by adding wrapper functions to them.


Disclaimer:

Blacksmith structure not included in Test Map! (It was sent to Gulag)
Contents

[GUI-Friendly] Allocator Engine (Map)

Reviews
Dr Super Good
Comments and Suggestions: Potentially useful for people using GUI. Dynamic indexing logic is a common problem people encounter and often come up with incorrect or buggy solutions. That said this has limited usefulness now that Lua exists since one can...
  1. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    351
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    Hmmm, so this works like GMUI but also applies an index counter? I never applied a debug/index counter to GMUI because I wanted it to be as optimized as possible, but it's certainly useful to have these features. You also built it in a manner that is a lot safer, since you made checks for the validity of the parameters.

    With this I think I can add a configuration for advanced users in my systems, so they can define which index generator system they want to use. I should also post GMUI on the spell section, since it has been in the pastebin since forever.

    Anyways, this is something that's really useful, so obviously 5 stars.

    EDIT: My only suggestion would be adding an in-lineable function that returns how many indexes exist for a given main key.

    Code (vJASS):

    function SizeOfKey takes integer mainKey returns integer
        return LoadInteger(udg_Allocator_HASH, mainKey, -1)
    endfunction
     


    EDIT2: Since you are making functions that are safe, then maybe you can make it not inlineable and have it check if the mainKey is valid.

    Code (vJASS):

    function SizeOfKey takes integer mainKey returns integer
        if HaveSavedInteger(udg_Allocator_Hash, mainKey, -1) then
            return LoadInteger(udg_Allocator_HASH, mainKey, -1)
        else
            // ... Debug ...
            return -1
        endif
    endfunction
     
     
    Last edited: May 22, 2018
  2. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,305
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    That would be a nice function to include, though I wasn't planning on adding that.

    I'll see if I can add that function, and include a little bit more in the test map.

    EDIT:

    - Added SizeOfKey as a function. Credits go to @_Guhun_ for that suggestion.
     
    Last edited: May 25, 2018
  3. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,611
    Resources:
    18
    Maps:
    1
    Spells:
    11
    Tutorials:
    6
    Resources:
    18
    Isn't this basically a unit indexer?

    You'd do:
    id = allocate()
    unit[id] = triggering unit
    dope[id] = true

    Instead of
    id = custom value of triggering unit
    dope[id] = true
     
  4. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,305
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    No, it isn't. It is functionally similar to constructors in Wurst, and allocators in vJASS.

    More on why this isn't a Unit Indexer; Unit Indexers require one to modify the unit's user data, which this does not. Rather, this enables one to generate indices without having to create variables specifically designed for allocation.
     
  5. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,611
    Resources:
    18
    Maps:
    1
    Spells:
    11
    Tutorials:
    6
    Resources:
    18
    I know that.

    But the actual usage would be similar.
    If I were to use this to make a spell in GUI it'd basically be a unit indexer where you use the generated id as index for arrays
     
  6. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,305
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    Welp, it can't be helped. This is an allocator engine, after all, and allocators and indexers are quite closely-connected.

    You have my thanks for pointing that out. I will attempt to clarify this resource being considered a Unit Indexer.

    In addition, I will add a possibility for limiting the amount of indices that one can allocate. By default (from next update), it will be 2^31 - 1

    EDIT:

    I will also update my Omnislash-Template using this.

     
    Last edited: Jun 1, 2018
  7. Somebassoon

    Somebassoon

    Joined:
    Jan 27, 2016
    Messages:
    135
    Resources:
    0
    Resources:
    0
    Is this faster than using hashtables?
     
  8. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,305
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    No, since it uses a hashtable, but operations shouldn't really have much of an impact on it, since it is O(c) where c is he number of function calls (constant).
     
  9. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,543
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Comments and Suggestions:
    Potentially useful for people using GUI. Dynamic indexing logic is a common problem people encounter and often come up with incorrect or buggy solutions. That said this has limited usefulness now that Lua exists since one can dynamically create tables to manage all instance data and these will be automatically garbage collected at end of life.

    Test map could do with some improvements. The terrain should be revealed so the player knows where the enemies are. All non-triggered abilities should be removed to avoid confusion. When the ability is cast it would be nice to print when indices are created and destroyed along with their key and number. Maybe another example spell to show that the system can cope with both abilities.​