- Joined
- May 9, 2014
- Messages
- 1,819
After looking at the Hive for possible conflicts with existing libraries on the purpose of this library, I now give the user the following snippet:
If there are existing libraries that do conflict with this, I will be more than happy to accept proposed changes to this.
JASS:
library Eval /*
*/ requires /*
------------------
*/ Table /*
------------------
-> Bribe
link: www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
---------------------------------------------------
Eval
- Run dynamic code without hassle.
---------------------------------------------------
Objectives:
- To make dynamic handler functions as
lightweight as possible (in implementation).
---------------------------------------------------
Overview:
- This basically abstracts the creation of
triggers for the purpose of dynamic code
to the system here.
- Such a concrete example would be to create
a Missile system that has an onHit handler
function and an onMove handler. It would be
cumbersome to manually create the triggers
that would be used to allow such dynamism.
- Instead, the System does all of the trigger
creation and destruction for the user,
freeing him or her of the responsibilities
of declaring variables.
- A hardcoded manner of allocation is implemented
so having an Allocator library is not needed
for this.
----------------------------------------------------
Struct Usage:
struct EvalCode extends array
----------------------------------------------
|
| static method getExecutable()
| Gets the current EvalCode that ran.
| Useful for dynamic reference.
|
| method destroy()
| Destroys an EvalCode instance.
| Double-free safe.
|
| method getEvalCount() -> int {DEBUG}
| Gets the number of times the script
| was evaluated.
|
| method run()
| Evaluates the code. Also destroys the
| instance if destroy was called inter
| nally. (Within the running method)
|
| method operator code= (code func)
| Sets which code will be evaluated.
|
| method operator add(code func)
| A method which adds code to the list
| of evaluations when ran.
|
---------------------------------------------
--------------
Example usage:
--------------
*/
-------------------------------------------------------
//! novjass
function foo takes nothing returns nothing
endfunction
function bar takes nothing returns nothing
endfunction
function asd takes nothing returns nothing
endfunction
function lrv takes nothing returns nothing
endfunction
function handler takes nothing returns nothing
local EvalCode eval = EvalCode.create()
set eval.code = function foo
call eval.run() // Runs code
call eval.add(function bar)
call eval.run() // Runs function foo, then bar.
call eval.add(function asd)
endfunction
//! endnovjass
--------------------------------------------------------
/*
*/
private keyword EvalCodeM
struct EvalCode extends array
private static TableArray metaData = 0
static method getExecutable takes nothing returns EvalCode
return EvalCode.metaData[3].integer[-1]
endmethod
method destroy takes nothing returns nothing
// Double-free protection!
if not EvalCode.metaData[1].integer.has(this) or EvalCode.metaData[1].integer[this] != 0 then
return
endif
// Cannot destroy while an instance is running
if EvalCode.metaData[3].integer[this] > 0 then
if not EvalCode.metaData[4].boolean[this] then
set EvalCode.metaData[4].boolean[this] = true
endif
return
endif
if EvalCode.metaData[2].trigger.has(this) then
call DestroyTrigger(EvalCode.metaData[2].trigger[this])
call EvalCode.metaData[2].trigger.remove(this)
endif
set EvalCode.metaData[1].integer[this] = EvalCode.metaData[1].integer[0]
set EvalCode.metaData[1].integer[0] = this
call EvalCode.metaData[3].integer.remove(this)
call EvalCode.metaData[4].boolean.remove(this)
endmethod
debug method getEvalCount takes nothing returns integer
debug return GetTriggerEvalCount(EvalCode.metaData[2].trigger[this])
debug endmethod
method run takes nothing returns nothing
local EvalCode lastEval = EvalCode.getExecutable()
set EvalCode.metaData[3].integer[-1] = this
set EvalCode.metaData[3].integer[this] = EvalCode.metaData[3].integer[this] + 1
call TriggerEvaluate(EvalCode.metaData[2].trigger[this])
set EvalCode.metaData[3].integer[this] = EvalCode.metaData[3].integer[this] - 1
set EvalCode.metaData[3].integer[-1] = lastEval
if EvalCode.metaData[3].integer[this] <= 0 and EvalCode.metaData[4].boolean[this] then
call this.destroy()
endif
endmethod
method operator code= takes code func returns nothing
if EvalCode.metaData[2].trigger.has(this) then
call DestroyTrigger(EvalCode.metaData[2].trigger[this])
endif
set EvalCode.metaData[2].trigger[this] = CreateTrigger()
call TriggerAddCondition(EvalCode.metaData[2].trigger[this], Condition(func))
endmethod
method add takes code func returns nothing
if not EvalCode.metaData[2].trigger.has(this) then
set this.code = func
else
call TriggerAddCondition(EvalCode.metaData[2].trigger[this], Condition(func))
endif
endmethod
static method create takes nothing returns EvalCode
local EvalCode temp = EvalCode.metaData[1].integer[0]
if EvalCode.metaData[1].integer[temp] == 0 then
set temp = temp + 1
set EvalCode.metaData[1].integer[0] = temp
set EvalCode.metaData[1].integer[temp] = 0
else
set EvalCode.metaData[1].integer[0] = EvalCode.metaData[1].integer[temp]
set EvalCode.metaData[1].integer[temp] = 0
endif
set EvalCode.metaData[3].integer[temp] = 0
set EvalCode.metaData[4].boolean[temp] = false
return temp
endmethod
private static method init takes nothing returns nothing
set EvalCode.metaData = TableArray[5]
endmethod
implement EvalCodeM
endstruct
private module EvalCodeM
private static method onInit takes nothing returns nothing
call thistype.init()
endmethod
endmodule
endlibrary
library_once EvalCode requires Eval
endlibrary
If there are existing libraries that do conflict with this, I will be more than happy to accept proposed changes to this.