| 02-28-2009, 02:04 AM | #1 |
Hi... Due to this comments, I was thinking in how we can do a script which allows an easy way to attach multiple data to one unit. I tinkered this option and I'd like to know if I'm wasting my time or if it could work more efficient than Table. I based several parts of the code in CSData, so for this part I consider it safer. JASS:library UnitUtils globals private constant integer MAX_UNIT_ID_COUNT = 408000 // private constant integer ARRAY_SIZE = 10 // Sets the maximum number of values that a unit can have stored endglobals private struct data [MAX_UNIT_ID_COUNT] static constant integer MIN_UNIT_ID = 0x100000 static group G = CreateGroup() static integer index = 0 integer array d [ARRAY_SIZE] endstruct private function U2I takes unit u returns integer return u return 0 endfunction function GetUnitIndex takes unit u returns integer debug if(U2I(u) - data.MIN_UNIT_ID >= MAX_UNIT_ID_COUNT) then debug call BJDebugMsg(SCOPE_PREFIX + ": Unit id too big, increase the MAX_UNIT_ID_COUNT constant or use gamecache instead") debug endif if not IsUnitInGroup(u, data.G) then call GroupAddUnit(data.G, u) debug call DisplayTimedTextFromPlayer(Player(0), 0,0,2, I2S(U2I(u) - data.MIN_UNIT_ID)) set data(U2I(u) - data.MIN_UNIT_ID).d[0] = data.index set data.index = data.index + 1 return data.index endif return data(U2I(u) - data.MIN_UNIT_ID).d[0] endfunction function GetUnitData takes unit u, integer id returns integer if id <= ARRAY_SIZE then return data(GetUnitIndex(u)).d[id] endif return 0 endfunction function SetUnitData takes unit u, integer id, integer value returns nothing if id <= ARRAY_SIZE then set data(GetUnitIndex(u)).d[id] = value endif endfunction endlibrary As you can see, by setting the ARRAY_SIZE constant, we can allow to each unit in a game to store a struct which can relate a bunch of other data. You know the drill: comments, suggestions, improvements, benchmarks, kisses are welcome. |
| 02-28-2009, 02:19 AM | #2 |
i dont like that .id / array stuff ..its not useful ..really.. ..and it doesnt favor Modularity at all... - Or - Use string-keys as function parameters (pretty similar to gamecache-stuff) SetUnitData(u,"mySpellXY) ...but i dont know if that is possible without having ...O(n) stuff.. |
| 02-28-2009, 02:39 AM | #3 | ||
That id stuff is not going to work, 10 is an absolutely low amount, and increasing it will decrease robustness. You'll need a different method, one that I am not knowledgeable off. Or to just remove that id thing. Quote:
Quote:
|
| 02-28-2009, 02:40 AM | #4 | ||
Quote:
Quote:
EDIT: Code updated a little bit: JASS:library UnitUtils globals private constant integer MAX_UNIT_ID_COUNT = 408000 private constant integer ARRAY_SIZE = 10 // Sets the maximum number of values that a unit can have stored endglobals private struct data [MAX_UNIT_ID_COUNT] static constant integer MIN_UNIT_ID = 0x100000 static group G = CreateGroup() static integer index = 0 integer id integer array d [ARRAY_SIZE] endstruct private function U2I takes unit u returns integer return u return 0 endfunction function GetUnitIndex takes unit u returns integer debug if(U2I(u) - data.MIN_UNIT_ID >= MAX_UNIT_ID_COUNT) then debug call BJDebugMsg(SCOPE_PREFIX + ": Unit id too big, increase the MAX_UNIT_ID_COUNT constant or use gamecache instead") debug endif if not IsUnitInGroup(u, data.G) then call GroupAddUnit(data.G, u) set data(U2I(u) - data.MIN_UNIT_ID).id = data.index set data.index = data.index + 1 return data.index endif return data(U2I(u) - data.MIN_UNIT_ID).id endfunction function GetUnitData takes unit u, integer id returns integer if id <= ARRAY_SIZE then return data(GetUnitIndex(u)).d[id] endif return 0 endfunction function SetUnitData takes unit u, integer id, integer value returns nothing if id <= ARRAY_SIZE then set data(GetUnitIndex(u)).d[id] = value endif endfunction endlibrary |
| 02-28-2009, 02:57 AM | #5 | |
Quote:
There's a reason they use indexing/gamecache for units this sort of thing doesn't work too well when just using arrays. You should though take a look at PUI 's textmacro for structs if you really want to add something table-like but keeping the speed. |
| 02-28-2009, 02:57 AM | #6 |
Oh, I see... I'm just doing my tests to get something as more inlined as possible. JASS:library UnitUtils globals private constant integer MAX_UNIT_ID_COUNT = 408000 private constant integer ARRAY_SIZE = 10 // Sets the maximum number of values that a unit can have stored endglobals private struct data [MAX_UNIT_ID_COUNT] static constant integer MIN_UNIT_ID = 0x100000 integer id integer array d [ARRAY_SIZE] endstruct private function U2I takes unit u returns integer return u return 0 endfunction function GetUnitIndex takes unit u returns integer debug if U2I(u) - data.MIN_UNIT_ID >= MAX_UNIT_ID_COUNT then debug call BJDebugMsg(SCOPE_PREFIX + ": Unit id too big, increase the MAX_UNIT_ID_COUNT constant or use gamecache instead") debug endif return U2I(u) - data.MIN_UNIT_ID endfunction function GetUnitData takes unit u, integer id returns integer if id <= ARRAY_SIZE then return data(GetUnitIndex(u)).d[id] endif return 0 endfunction function SetUnitData takes unit u, integer id, integer value returns nothing if id <= ARRAY_SIZE then set data(GetUnitIndex(u)).d[id] = value endif endfunction endlibrary right now it's overwriting the ids... bad thing :( I'll work on it tomorrow, I can't keep me awake more time. |
| 02-28-2009, 03:05 AM | #7 |
You know GetUnitIndex won't replace all those indexing stuff? they will have to add [MAX_UNIT_ID_COUNT] |
| 02-28-2009, 03:21 AM | #8 |
If multiple things try to use this at the same time they will trip over each other. |
| 02-28-2009, 03:26 AM | #9 |
You should probably look at this: http://www.wc3c.net/showthread.php?t=101440 |
| 02-28-2009, 03:32 AM | #10 |
In my opinion, I don't think this would be more viable than UnitIndexingUtils/PUI/whatever. The bigger the size you give "d", the less struct instances will be available. While if you use an indexing library like UnitIndexingUtils or PUI, you can attach stuff to a unit with an infinite amount but it would require you to declare a global array for each data(MYGLOBALARRAY[UNITINDEX]). I'd say that's a good tradeoff. Just sharing my two cents. |
| 02-28-2009, 03:53 AM | #11 |
Check this total variation: JASS:library UnitUtils initializer init globals private constant integer ARRAY_SIZE = 10 // Sets the maximum number of values that a unit can have stored endglobals private struct data static integer index = 0 integer array d [ARRAY_SIZE] static method Set takes unit u returns integer local data D = data.allocate() call SetUnitUserData(u, integer(D)) set data.index = data.index + 1 return data.index endmethod endstruct function GetUnitIndex takes unit u returns integer if GetUnitUserData(u) < 1 then return data.Set(u) endif return GetUnitUserData(u) endfunction function GetUnitData takes unit u, integer id returns integer if id <= ARRAY_SIZE then return data(GetUnitIndex(u)).d[id] endif return 0 endfunction function SetUnitData takes unit u, integer id, integer value returns nothing if id <= ARRAY_SIZE then set data(GetUnitIndex(u)).d[id] = value endif endfunction private function clean takes nothing returns nothing call data(GetUnitIndex(GetTriggerUnit())).destroy() endfunction private function init takes nothing returns nothing local trigger t = CreateTrigger() call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH) call TriggerAddAction(t, function clean) set t = null endfunction endlibrary Works perfectly, now each unit can store ARRAY_SIZE values. should I add a custom destroy method to clean the values from the array? |
| 02-28-2009, 04:01 AM | #12 | |
Quote:
|
| 02-28-2009, 12:01 PM | #13 | |
Quote:
Well, it worked with few units, but with 1200 units this code would do funny things :( One question Vex... if I do this: JASS:globals private constant integer ARRAY_SIZE = 10 // Sets the maximum number of values that a unit can have stored private constant integer AMPLIFIER = ARRAY_SIZE * 8190 endglobals private struct data [AMPLIFIER] //... endstruct |
| 02-28-2009, 12:49 PM | #14 |
it would slow down the system obviously... |
| 02-28-2009, 01:40 PM | #15 | |
Quote:
|
