• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[GUI-Friendly] Allocator Engine

  • Like
Reactions: _Guhun_
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)

Features

Code API

Usage

Compatibility

Changelog


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).

JASS:
//! 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...
Level 12
Joined
Jun 12, 2010
Messages
413
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.

JASS:
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.

JASS:
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:
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:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
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.​
 
Top