Temp - Sets

GLL - Ordered Sets v1.2.0

This system facilitates the creation of Ordered Sets, which, unlike generic Sets, have their elements in a specific order.

NOTE: You cannot add or remove 0 from a GLL set. If you do, you will break everything! You have been warned.

Why is this system's acronym GLL instead of GOS or literally anything else that's sensible?
When I was implementing this system, I wanted to create a linked list. But I saw a good opportunity to implement something that has O(1) speed to check if an element is inside it. However, this obviously makes the Data Structure resemble a Set much more than it does a List. I didn't notice this at first, so I ended up publishing it as GLL, for Linked Lists. Now, I don't want to change the function names as to not break compatibility.

Technical details:
GLL implements head-tail linked lists in which all elements have links to their previous and next elements. The list is actually a circular structure, but we use 0 to define the beginning (next element from 0) and the end (previous element from 0). Because of this, you cannot add 0 as an element of the linked list (if you are using the included loop function). The lists don't actually store any data, only the order of the elements (integers) in the list.

Ordered Sets:

Each set has a unique ID, which is an integer generated by GMUI. You will need this ID to manipulate the sets and destroy them when you don't need them anymore.

As for the "Lists_Hashtable" hashtable, the order of the elements is stored in two child hashtables, one equal to the ID and one equal to the opposite (negative) of the ID. Each element of a set has a link to its next element and a link to its previous element. For the included Loop function, the next element after 0 is considered the first element and the one previous to 0 is considered the last one.

Because of the way the values are stored, you can add either negative or positive data to the set and it will still work.
Hashtable addresses:
Each Child Hashtable is a Set ID
Positive Child Hashtable -> Data : Next value in set
Negative Chiled Hashtable -> Data : Previous value in set

How to Import:
  1. Open World Editor. File -> Preferences -> Tick box for "Automatically create unknown variables (...)"
  2. Copy the "GUI MUI Engine" category into your map.
  3. Open the "GMUI Header" trigger and copy its contents into your map header.
  4. Copy the "GUI Ordered Sets" category into your map.
  5. Open the "GLL Header" trigger and copy its contents into your map header.
  6. Done!

Using the System:


Add Data

Remove Data

Create Set

Destroy Set

Set Loop

Check Data

Advanced Loop

JASS API


This function adds Data to the last position of an existing set. Please note that conditions should be checked when executing the trigger. If the value specified in Lists_Data already exists in the Set, the Data will be removed from the Set instead (see Remove Data function).

Variables before execution:

Lists_ListID

The ID of the set we want to add data to.

Lists_Instance

The data before which we want to insert new data. Set this to 0 to insert data at the end of the set.

Lists_Data

The Data we want to add to the set.

GUI-only method:
  • Actions
    • Set Lists_ListID = YourListID
    • Set Lists_Instance = 0
    • Set Lists_Data = YourData
    • Trigger - Run GLL Main <gen> (checking conditions)
Custom Script method (more efficient):
  • Actions
    • Custom script: set udg_Lists_Instance = GLL_AddData(udg_Lists_ListID, udg_Lists_Data)
If you want to add Data in a different position, simply specify Lists_Instance as some Data that is already in the Set. The new data you specify will be added just before the old data in the Set.

Variables after execution:

Lists_ListID

Same as before.

Lists_Instance

Same as before.

Lists_Data

Same as before.


This function removes data from a certain address of a set. Please not you should check conditions when executing the trigger. If the value specified in Lists_Data does not already exist in the Set, the Data will be added from the Set instead (see Add Data function).

Variables before execution:

Lists_ListID

The ID of the set list we want to remove data from.

Lists_Data

The Data we want to remove from the set.

GUI-only method:
  • Actions
    • Set Lists_ListID = YourListID
    • Set Lists_Data = YourData
    • Trigger - Run GLL Main <gen> (checking conditions)
Custom Script method (more efficient):
  • Actions
    • Custom script: set udg_Lists_Instance = GLL_RemoveData(udg_Lists_ListID, udg_Lists_Data)
Variables after execution:

Lists_ListID

Same as before.

Lists_Data

Same as before.

This function allows you to create a new set, which you can add data to. Please note that you need to ignore conditions when executing the "GLL Main" trigger.

Variables before execution:

Lists_ListID

We set this to zero because we want to create a new set.

GUI-only method:
  • Actions
    • Set Lists_ListID = 0
    • Trigger - Run GLL Main <gen> (ignoring conditions)
Custom Script method (more efficient):
  • Actions
    • Custom script: set udg_Lists_ListID = GLL_CreateList()
Variables after execution:

Lists_ListID

The ID of our newly created set.

This function allows you to destroy a set that you have created. Please note that you need to ignore conditions when executing the "GLL Main" trigger.

Variables before execution:

Lists_ListID

The ID of the set we want to destroy.

GUI-only method:
  • Actions
    • Set Lists_ListID = YourListID
    • Trigger - Run GLL Main <gen> (ignoring conditions)
Custom Script method (more efficient):
  • Actions
    • Custom script: call GLL_DestroyList(udg_Lists_ListID)
Variables after execution:

Lists_ListID

Same as before.

This function allows you to iterate over a set like a normal loop, allowing you to manipulate each element in the set. It also allows you to specify how many elements you want to iterate through, and the loop will stop after it reaches that number.

Variable parameters:

Lists_ID

The ID of the set you want to iterate over.

Lists_Trigger

The trigger that should be executed for each element.

Lists_LoopUntil

How many elements should the loop iterate over before it stops

GUI-only method:
  • Actions
    • Set Lists_ListID = YourSetId
    • Set Lists_Trigger = YourTrigger
    • Set Lists_LoopUntil = (negative integer for infinite or non-negative for limited)
    • Trigger - Run GLL Loop <gen> (ignoring conditions)
Custom Script method (more efficient):
  • Actions
    • Custom script: call GLL_Loop(udg_Lists_ListID, udg_Lists_Trigger, udg_Lists_LoopUntil)
For each element, the specified trigger will be executed. When the loop executes a trigger, the variables GLL_Data and GLL_ListID will be set to the relevant values, so they can be used to access other data.

Variable values at each execution of Lists_Trigger:

Lists_ID

The ID of the set being iterated over.

Lists_LoopUntil

The data of the current iteration.

This is a method of checking if data is in set by using custom script. It is an O(1) operation, which means it will take the same amount of time to be executed, independently of the size of the Set.

  • Actions
    • Custom script: set udg_YourBoolean = GLL_ListHasData(udg_Lists_ListID, udg_Lists_Data)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • YourBoolean Equal to True
      • Then - Actions
        • -------- SET CONTAINS ELEMENT --------
      • Else - Actions
        • -------- SET DOES NOT CONTAIN ELEMENT --------

This is a guide on how to loop through a Set without using the included function (see Set Loop). For GUI, looping through a set is somewhat weird and requires some workarounds, since GUI only supports for-type loops, not while-type loops.

  • Actions
    • Set Lists_Data = (Load 0 of Lists_ListID from Lists_Hashtable)
    • For each (Integer Lists_LoopUntil) from 0 to 0, do (Actions)
      • Loop - Actions
        • -------- ------------ --------
        • -------- DO STUFF HERE --------
        • -------- ------------ --------
        • -------- GET NEXT ELEMENT AND REMOVE DATA IF DESIRED --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
          • Then - Actions
            • Set Lists_Instance = Lists_Data
            • Set Lists_Data = (Load Lists_Data of Lists_ListID from Lists_Hashtable)
            • Custom script: call GLL_RemoveData(udg_Lists_ListID, udg_Lists_Instance)
          • Else - Actions
            • Set Lists_Data = (Load Lists_Data of Lists_ListID from Lists_Hashtable)
        • -------- ------------ --------
        • -------- MAKE SURE THE LOOP DOESN'T STOP UNTIL END OF SET IS REACHED --------
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • Lists_Data Equal to 0
          • Then - Actions
            • Set Lists_LoopUntil = (Lists_LoopUntil - 1)
          • Else - Actions

This is the API provided for JASS users.

JASS:
//Returns the next element after the specified "data" in the set
//To get the first element, pass "0" as the parameter "data"
function GLL_GetNext takes integer listKey, integer data returns integer

//Returns the element that preceeds the specified "data" in the set
//To get the last element, pass "0" as the parameter "data"
function GLL_GetPrev takes integer listKey, integer data returns integer

//Returns wether a list contains the specified data or not
function GLL_ListHasData takes integer listKey, integer data returns boolean

//Adds data to a list
//If data is already present in list, behaviour is undefined
function GLL_AddData takes integer listKey, integer next, integer data returns nothing

//Removes the given Data from a list
//If data is not present in List, behaviour is undefined
function GLL_RemoveData takes integer listKey, integer data returns nothing

//Creates a new list and returns its ID/key
function GLL_CreateList takes nothing returns integer

//Destroys the specified list
function GLL_DestroyList takes integer listId returns nothing

//This function loops through a List and executes a trigger for each element, setting the list variables to their relevant equivalents each time
function GLL_Loop takes integer listKey, trigger trig, integer until returns nothing

//Same as GLL_Loop, however, you may specify a code that will run in a ForPlayer loop instead of a trigger
//Added in version 1.1.0
function GLL_CodeLoop takes integer listKey, code func, integer until returns nothing

//Loops over a list from the value following "start" to the value preceding "finish" (or 0, whichever comes first)
//Each iteration sets Lists_Data to the current value and then runs the specified code in a ForPlayer loop
//If you specify a negative listKey, the loop will execute backwards
//Added in version 1.1.0
function GLL_ClearList takes integer listKey, integer start, integer finish, code func returns integer

//This function initializes GLL if it has not yet been initialized
function GLL_Initialize takes nothing returns nothing

Updates and Version History:

v1:
1.0.0 > Initial Release
1.1.0 > Added GLL_CodeLoop and GLL_ClearList for JASS users
1.2.0 > Added FirstOf, LastOf, IsEmpty, SizeOf, AddDataAfter, Append, Prepend, LoopAll, CodeLoopAll​

Upcoming:
Last edited:
Top