- Reaction score
- 333
I previously had a bulky and non-dynamic system which could perform this sort of stuff, but this one is better. You can attach functions to an "event" string, and then you can broadcast the event in order to call all functions associated with it.
Pros:
1. Dynamic - can attach or remove actions associated with any string at any time.
2. Scalable - as long as you stay below the limit of around 8190 associations, there is no fixed limit on how many associations a single event can have. 800 events with 10 actions each is just as possible as 10 events with 800 actions each.
3. Multiple usages - can be used to attach actions to a unit type, a handle. Anything that can be expressed in string form somehow can have actions attached.
Cons:
1. Slow.
2. Can't pass arguments to associated functions. You'll have to attach data to event-responses or use globals.
Copy into map header or put in empty trigger to use:
Usage details:
Use Event_AddAction(string event, string action) to associate an event with an action. Event_RemoveAction removes an action from an event. Call Event_Broadcast(string event) to run the associated actions.
Update: I have added a test map.
Pros:
1. Dynamic - can attach or remove actions associated with any string at any time.
2. Scalable - as long as you stay below the limit of around 8190 associations, there is no fixed limit on how many associations a single event can have. 800 events with 10 actions each is just as possible as 10 events with 800 actions each.
3. Multiple usages - can be used to attach actions to a unit type, a handle. Anything that can be expressed in string form somehow can have actions attached.
Cons:
1. Slow.
2. Can't pass arguments to associated functions. You'll have to attach data to event-responses or use globals.
Copy into map header or put in empty trigger to use:
JASS:
library Event initializer DeclareCache
globals
private gamecache gc
endglobals
private struct link
string str
link parent = 0
link child = 0
static method create takes string str returns link
local link li = link.allocate()
set li.str = str
return li
endmethod
endstruct
private function DeclareCache takes nothing returns nothing
set gc = InitGameCache(SCOPE_PRIVATE+"vars.w3v")
endfunction
private function FindLastLink takes link li returns link
if (li.child == 0) then
return li
endif
return FindLastLink.evaluate(li.child)
endfunction
private function DeleteLink takes link li returns nothing
set li.parent.child = li.child
set li.child.parent = li.parent
call li.destroy()
endfunction
private function GetLink takes link li, string str returns link
if (li.str == str) then
return li
elseif (li.child == 0) then
return 0
endif
return GetLink.evaluate(li.child, str)
endfunction
public function AddAction takes string ev, string ac returns nothing
local link li = GetStoredInteger(gc, SCOPE_PRIVATE+"event", ev)
if (li == 0) then
set li = link.create(ac)
call StoreInteger(gc, SCOPE_PRIVATE+"event", ev, li)
else
set li = FindLastLink(li)
set li.child = link.create(ac)
set li.child.parent = li
endif
endfunction
public function RemoveAction takes string ev, string ac returns nothing
local link li = GetStoredInteger(gc, SCOPE_PRIVATE+"event", ev)
if (li != 0 and li.str != ac) then
call DeleteLink(GetLink(li, ac))
elseif (li != 0) then
if (li.child != 0) then
call StoreInteger(gc, SCOPE_PRIVATE+"event", ev, li.child)
else
call FlushStoredInteger(gc, SCOPE_PRIVATE+"event", ev)
endif
call DeleteLink(GetLink(li, ac))
endif
endfunction
public function Broadcast takes string ev returns nothing
local link li = GetStoredInteger(gc, SCOPE_PRIVATE+"event", ev)
if (li != 0) then
loop
call ExecuteFunc(li.str)
exitwhen li.child == 0
set li = li.child
endloop
endif
endfunction
endlibrary
Usage details:
Use Event_AddAction(string event, string action) to associate an event with an action. Event_RemoveAction removes an action from an event. Call Event_Broadcast(string event) to run the associated actions.
Update: I have added a test map.