- Joined
- Sep 26, 2009
- Messages
- 9,521
It's like Event, but with the best API and functionality.
JASS:
library Advent requires LinkedListModule /*
==========================================================================
Advent v3.1.0.1
--------------------------------------------------------------------------
Easy, light, dynamic & complete event registration
==========================================================================
Credits:
--------------------------------------------------------------------------
Created by Bribe
Idea by Jesus4Lyf and Nestharus
Many API additions thanks to Dirac
==========================================================================
Requirements:
--------------------------------------------------------------------------
LinkedListModule by Dirac: hiveworkshop.com/forums/showthread.php?t=206552
==========================================================================
Intro:
--------------------------------------------------------------------------
Advent allows you to create an Advent, add code to its execution queue,
remove certain code from its queue, fire all added codes, fire just one
single code and even destroy the Advent should its task be finished.
I created this library for some key reasons. For one, the existing Event
libraries have quite verbose API and their cross compatibility has quite
large problems. Nestharus wanted a fast solution and Jesus4Lyf wanted a
fully-dynamic solution.
Why not have both?
Advent combines tight code with complex functionality while not adding any
unnecessary performance overhead. If you know your code will run at any
point in the game, you can add permanent code that runs more quickly. If
you need dynamic code, you can take advantage of the AdventReg type which
allows you to do so.
You can also destroy Advents which completely destroys any & all code reg-
istered to them. I imagine this would only be used for some really complex
systems; it's mostly here for completeness.
==========================================================================
API Guide:
--------------------------------------------------------------------------
function CreateAdvent
takes nothing
returns Advent
Create a new Advent instance. You must create it before anything else.
* Advent adv = Advent.create()
function DestroyAdvent
takes Advent adv
returns nothing
Perhaps this is here just for completeness but it effectively allows
the system to be completely dynamic.
* call adv.destroy()
function RegisterAdvent
takes Advent adv, code c, boolean permanent
returns AdventReg
Register some code to be run when the Advent is fired. If you want to
be able to unregister the code at some point, set the permanent* flag
to false. If false, the function returns an AdventReg that is used to
identify it.
* AdventReg adreg = adv.registerEx(code) //Dynamic
* call adv.register(code) //Permanent
function UnregisterAdventReg
takes AdventReg node
returns nothing
Unregister an AdventReg from an Advent.
* call adreg.unregister()
function FireAdvent
takes Advent adv
returns nothing
Run all code that was registered to the Advent.
* call adv.fire()
function FireAdventData
takes Advent adv, integer data
returns nothing
Run all code that was registered to the Advent with an extra parameter
to pass a data integer. This is useful for certain systems to support
a single integer as a piece of data.
* call adv.fireData(data)
function GetAdventData
takes nothing
returns integer
Returns the data specified by FireAdventData.
* set data = Advent.data
function GetAdventReg
takes nothing
returns AdventReg
Returns the registry of the AdventReg that is currently firing. It is
pointless to use this if you aren't using dynamic Advent registries.
* set data = Advent.reg.data
- Yeah AdventReg has a data member now, thanks to Dirac.
function FireCode
takes code c, integer data
returns nothing
Call the code directly. This is useful if you are late registering an
Advent and you want this code to fire anyway, without firing the full
Advent. This function also helps to keep Advent.data readonly because
that is a very sensitive variable.
* Advent.fireCode(code, data)
*/
globals
private force f
private trigger array trig
endglobals
private module Init
private static method onInit takes nothing returns nothing
set f = bj_FORCE_PLAYER[0]
endmethod
endmodule
private struct List extends array
implement LinkedList
implement Init
endstruct
struct Advent extends array
//Data attached to the currently-firing Advent.
readonly static integer data = 0
//The AdventReg which is currently firing.
readonly static AdventReg reg = 0
static method create takes nothing returns thistype
return List.createNode()
endmethod
method destroy takes nothing returns nothing
local List node = List(this).next
if not List(this).head then
loop
call DestroyTrigger(trig[node])
set trig[node] = null
exitwhen node == this
set node = node.next
endloop
call List(this).flushNode()
debug else
debug call BJDebugMsg("[Advent] Attempt to destroy invalid instance: " + I2S(this))
endif
endmethod
method register takes code c returns nothing
if trig[this] == null then
set trig[this] = CreateTrigger()
endif
call TriggerAddCondition(trig[this], Filter(c))
endmethod
method registerEx takes code c returns AdventReg
local AdventReg node = List.allocate()
call List(this).insertNode(node)
set trig[node] = CreateTrigger()
call TriggerAddCondition(trig[node], Filter(c))
return node
endmethod
method fire takes nothing returns nothing
local integer r = .reg
set .reg = List(this).next
loop
call TriggerEvaluate(trig[.reg])
exitwhen .reg == this
set .reg = List(.reg).next
endloop
set .reg = r
endmethod
method fireData takes integer whichData returns nothing
local integer pdat = .data
set .data = whichData
call this.fire()
set .data = pdat
endmethod
static method fireCode takes code c, integer whichData returns nothing
local integer pdat = .data
set .data = whichData
call ForForce(f, c)
set .data = pdat
endmethod
endstruct
struct AdventReg extends array
//For attaching data to registries, for example a struct instance.
integer data
method unregister takes nothing returns nothing
if trig[this] != null and not List(this).head then
call DestroyTrigger(trig[this])
set trig[this] = null
call List(this).removeNode()
call List(this).deallocate()
debug else
debug call BJDebugMsg("[Advent] Attempt to unregister invalid AdventReg: " + I2S(this))
endif
endmethod
endstruct
function CreateAdvent takes nothing returns Advent
return Advent.create()
endfunction
function DestroyAdvent takes Advent adv returns nothing
call adv.destroy()
endfunction
function FireAdvent takes Advent adv returns nothing
call adv.fire()
endfunction
function FireAdventData takes Advent adv, integer data returns nothing
call adv.fireData(data)
endfunction
function FireCode takes code c, integer data returns nothing
call Advent.fireCode(c, data)
endfunction
function RegisterAdvent takes Advent adv, code c, boolean permanent returns AdventReg
if permanent then
call adv.register(c)
return 0
endif
return adv.registerEx(c)
endfunction
function UnregisterAdvent takes AdventReg reg returns nothing
call reg.unregister()
endfunction
function GetAdventData takes nothing returns integer
return Advent.data
endfunction
function GetAdventReg takes nothing returns AdventReg
return Advent.reg
endfunction
endlibrary
Last edited: