Snippet Multiple Instance Attachment System

Dirac

22710180
Reaction score
147
This can be very useful, and it's quite simple (description at code)

Reasons of why this snippet:
- Let's say you're trying to handle multiple units in a single spell, instead of occupying 1 instance per unit, like AIDS would do, you store all the units in the same instance avoiding creating a doubly linked list and the extra instance creation.
- Allows you to decide when to index the unit
- Allows you to index dead units (corpses)

JASS:
library MIAS //Multiple Instance Attachment System
//by Dirac

//this snippet alows you to attach multiple units to each instance of each struct.
//you can't attach the same unit to 2 different instances of the same struct.
//it does not modify the UnitUserData

//how to use?:
//  Implement MIA at the top of your struct
//  -method IndexUnit takes unit u returns integer
//      Indexes the unit given to your struct instance, use the operator to return the
//      instance. Ex:
//      yourstruct[whichUnit]=instance the unit is attached to

    globals
        private hashtable MIAh=InitHashtable()
        private integer COUNT=0
    endglobals
    
    module MIA
    
        private static integer struct_index
            
        private static method onInit takes nothing returns nothing
            set COUNT=COUNT+1
            set thistype.struct_index=COUNT
        endmethod
        
        private static method Flush takes nothing returns nothing
            call RemoveSavedInteger(MIAh,thistype.struct_index,GetHandleId(GetEnumUnit()))
        endmethod
        
        private method onDestroy takes nothing returns nothing
            call ForGroup(LoadGroupHandle(MIAh,-thistype.struct_index,this),function thistype.Flush)
            call RemoveSavedHandle(MIAh,-thistype.struct_index,this)
        endmethod
    
        method IndexUnit takes unit u returns integer
            local integer HID=GetHandleId(u)
            if HaveSavedHandle(MIAh,-thistype.struct_index,this)==false then
                call SaveGroupHandle(MIAh,-thistype.struct_index,this,CreateGroup())
            endif
            
            if HaveSavedInteger(MIAh,thistype.struct_index,HID)==false then
                call GroupAddUnit(LoadGroupHandle(MIAh,-thistype.struct_index,this),u)
                call SaveInteger(MIAh,thistype.struct_index,HID,this)
            endif
            return HID
        endmethod
        
        static method operator[] takes unit u returns thistype
            return LoadInteger(MIAh,thistype.struct_index,GetHandleId(u))
        endmethod
    endmodule
endlibrary


Changelog:
v0.01
-Initial Release
v0.02
-Instead of Unit Groups uses a second hashtable to deattach units to structs
-Has safety methods to prevent indexing the same unit twice
v0.03
-Removed the use of a second hashtable
-This can now be used in array structs
 

Bribe

vJass errors are legion
Reaction score
67
This really doesn't do anything better than a unit indexer. It
looks like you're just trying to make it more complicated than
it has to be.

Instead of hashing a struct instance to the unit, a proper struct
just gets its instance from the unit indexer (doesn't use
normal vJass struct allocators, instead structs extends array).

call SaveInteger(MIAh,GetHandleId(GetEnumUnit()),thistype.struct_index,0)

^ The above should be RemoveSavedInteger, it does the same
thing but takes up less memory.
 

Dirac

22710180
Reaction score
147
The whole idea of this snippet is to be able to attach multiple units to a single struct instance, different from AIDS that only allows 1 unit per instance, this could be very useful for handling multiple dummies at spell making

If i create the struct from the indexer it would have to use unit groups, and then how to add others units to them? It's not practical.

About the SaveInteger, i'll change that right away
 

Bribe

vJass errors are legion
Reaction score
67
You can use a negative integer (negate one of these indices) instead of creating an entirely seperate hashtable.

You should also mention that this cannot be used in array structs.

What would this be useful for? I guess I get what it does, but why would it be used? That should be included with the description.
 

Nestharus

o-o
Reaction score
84
Referencing multiple units to multiple structs just means a linked list. When the unit is deindexed, remove it from the list.

A struct stores a list, and that list stores the units.


I can't think of any reason why anyone would ever want to use this over AutoIndex, AIDS, or UnitIndexer.
 

Dirac

22710180
Reaction score
147
I'll tweak this so it can be used in structs that extends arrays.

The thing is that LinkedList (the system made by kenny) cannot be used in array structs, and doubly linked lists consume lots of struct instances,the whole thing about this snippet is to avoid that.

>You can use a negative integer (negate one of these indices) instead of creating an entirely seperate hashtable.
I didn't get this. Care to explain more? - The second hashtable stores each unit attached to the struct, making the deattachment possible
 

Bribe

vJass errors are legion
Reaction score
67
Negative integer as a key:

This is what you have:

call SaveInteger(MIAh, HID, thistype.struct_index, this)

You could change it to this:

call SaveInteger(MIAf, -HID, thistype.struct_index, this)
 

tooltiperror

Super Moderator
Reaction score
231
>The thing is that LinkedList (the system made by kenny) cannot be used in array structs,
Then make your own Linked List snippet that does the job better.

>and doubly linked lists consume lots of struct instances,the whole thing about this snippet is to avoid that.
If it contains any more than a singly linked list then you're doing it wrong.

Why not just use AIDS for this? Really no reason to use this when you can use AIDS.
 

Sevion

The DIY Ninja
Reaction score
424
Since when does a doubly-linked-list consume more instances than a singly-linked-list?

JASS:
struct a extends array
    readonly thistype next
    readonly thistype prev

    public method link takes nothing returns nothing
        set thistype(0).next.prev = this
        set this.next = thistype(0).next
        set thistype(0).next = this
        set this.prev = thistype(0)
    endmethod

    public method unlink takes nothing returns nothing
        set this.next.prev = this.prev
        set this.prev.next = this.next
    endmethod
endstruct


o_O'
 

Bribe

vJass errors are legion
Reaction score
67
I think that's for the silly cases where people do this:

JASS:
readonly thistype array next[10]
readonly thistype array prev[10]


Really, since hashtables were made we can deprecate the use of
big/dynamic arrays in favor of the limitless size of hashtables.
 

Dirac

22710180
Reaction score
147
Really, since hashtables were made we can deprecate the use of
big/dynamic arrays in favor of the limitless size of hashtables.
yes!

Also, update. Didn't make it based off AIDS because it's intended to index more than one unit per index, it makes no sense to use both this and AIDS in the same struct
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
Wait, isn't this system more like a unit group system? The more I think about it, the more this system resembles a unit group.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top