- Joined
- Sep 9, 2007
- Messages
- 6,759
JASS:
/**
* CodeStack
* by Anachron
*
* requires
* - Table by Bribe
* - HandleObject by Anachron
*
* This library is a solution to generate dynamic code constructs that
* can be modified whenever required. They provide a very easy and flexible
* interface that can be used to get almost any functionality that you could need.
*
* This system also is able to clear the whole stack and remove all actions from it.
*
* CodeStack.create() --> Creates a stack of actions with a new trigger
* CodeStack.createEx(triggerVariable) --> Create a stack of actions with your custom trigger
* {var}.addCode(function xyz) --> Add something to your codestack
* {var}.remCode(function zyx) --> Remove something from your codestack
* {var}.remCodeByIndex(index) --> Remove code when you know which index it has
* {var}.execute() --> Run all actions defined in your codestack
* {var}.clear() --> Remove every existing action from you stack
*
*/
library CodeStack requires Table, HandleObject
struct Code
implement HandleObject
public conditionfunc CondFunc = null
public static method create takes code theCode returns thistype
local conditionfunc theCondFunc = Condition(theCode)
local thistype this = thistype.new(theCondFunc)
set .CondFunc = theCondFunc
return this
endmethod
endstruct
struct CodeTrigger
implement HandleObject
public trigger SelfHandle = null
public static method create takes trigger theTrigger returns thistype
local thistype this = thistype.new(theTrigger)
set .SelfHandle = theTrigger
return this
endmethod
endstruct
module CodeStackModule
private Table CodeTable = 0
private Table IdTable = 0
private integer CodeAmount = 0
private CodeTrigger ExecTrigger = 0
public static method create takes nothing returns thistype
return thistype.createEx(CreateTrigger())
endmethod
public static method createEx takes trigger theTrigger returns thistype
local thistype this = thistype.allocate()
set .CodeTable = Table.create()
set .IdTable = Table.create()
set .ExecTrigger = CodeTrigger.create(theTrigger)
return this
endmethod
public method addCode takes code theCode returns Code
local Code theRealCode = Code.create(theCode)
local integer triggerId = GetHandleId(.ExecTrigger.SelfHandle)
local triggercondition condTrigCond = null
if not theRealCode.INSTANCES.has(triggerId) then
set condTrigCond = TriggerAddCondition(.ExecTrigger.SelfHandle, theRealCode.CondFunc)
set theRealCode.INSTANCES.triggercondition[triggerId] = condTrigCond
set .CodeTable[.CodeAmount] = theRealCode
set .IdTable[integer(theRealCode)] = .CodeAmount
endif
return theRealCode
endmethod
public method remCode takes code theCode returns boolean
local Code theRealCode = Code.create(theCode)
if not .IdTable.has(integer(theRealCode)) then
return false
endif
return .remCodeByIndex(.CodeTable[integer(theRealCode)])
endmethod
public method remCodeByIndex takes integer index returns boolean
local Code theRealCode = .CodeTable[index]
local integer triggerId = GetHandleId(.ExecTrigger.SelfHandle)
local triggercondition codeTrigCond = null
set codeTrigCond = theRealCode.INSTANCES.triggercondition[triggerId]
call TriggerRemoveCondition(.ExecTrigger.SelfHandle, codeTrigCond)
call theRealCode.INSTANCES.remove(triggerId)
call .CodeTable.remove(index)
set .IdTable[.CodeTable[.CodeAmount -1]] = index
set .CodeTable[index] = .CodeTable[.CodeAmount -1]
set .CodeAmount = .CodeAmount -1
return true
endmethod
public method execute takes nothing returns boolean
return TriggerEvaluate(.ExecTrigger.SelfHandle)
endmethod
public method clear takes nothing returns nothing
local integer codeId = 0
loop
exitwhen .CodeAmount <= 0
call .remCodeByIndex(.CodeAmount -1)
endloop
endmethod
endmodule
struct CodeStack
implement CodeStackModule
endstruct
endlibrary
Requirements:
New Table by Bribe
JASS:
library SaveableStruct requires Table
module SaveableStruct
public static Table INSTANCES = 0
public static integer NOT_EXISTING = -1
public integer id = -1
public static integer SELF = 0
public method save takes nothing returns nothing
set thistype.INSTANCES[.id] = integer(this)
endmethod
public method clear takes nothing returns nothing
call thistype.INSTANCES.flush()
endmethod
public method remove takes nothing returns boolean
local boolean exists = thistype.exists(.id)
call thistype.INSTANCES.remove(.id)
return exists
endmethod
public static method exists takes integer id returns boolean
return thistype.INSTANCES.has(id)
endmethod
public static method load takes integer id returns thistype
if not thistype.exists(id) then
return thistype.NOT_EXISTING
endif
return thistype(thistype.INSTANCES[id])
endmethod
private static method onInit takes nothing returns nothing
set thistype.INSTANCES = Table.create()
endmethod
endmodule
endlibrary
JASS:
library HandleObject
module HandleObject
implement SaveableStruct
public handle myHandle = null
public static method new takes handle theHandle returns thistype
local integer handleId = GetHandleId(theHandle)
local thistype this = thistype.load(handleId)
if this == thistype.NOT_EXISTING then
set this = thistype.allocate()
set this.myHandle = theHandle
set this.id = handleId
call .save()
endif
return this
endmethod
private method onDestroy takes nothing returns nothing
call .remove()
endmethod
endmodule
endlibrary
Example (+ Map)
JASS:
library Event initializer test requires CodeStack
struct Event
private CodeStack funcs = 0
public string name = null
public static method create takes string theName returns thistype
local thistype this = thistype.allocate()
set .name = theName
set .funcs = CodeStack.create()
return this
endmethod
public method register takes code theCode returns Code
return .funcs.addCode(theCode)
endmethod
public method unregister takes code theCode returns boolean
return .funcs.remCode(theCode)
endmethod
public method fire takes nothing returns boolean
return .funcs.execute()
endmethod
endstruct
globals
unit testUnit = null
endglobals
private function createUnit takes nothing returns boolean
call BJDebugMsg("Create Unit")
set testUnit = CreateUnit(Player(0), 'hpea', 0., 0., 0.)
return true
endfunction
private function killUnit takes nothing returns boolean
call BJDebugMsg("Kill Unit")
call KillUnit(testUnit)
return true
endfunction
private function test takes nothing returns nothing
local Event myEvent = Event.create("AwesomeEvent")
call myEvent.register(function createUnit)
call myEvent.register(function killUnit)
call myEvent.fire()
call myEvent.unregister(function killUnit)
call myEvent.fire()
endfunction
endlibrary
What do you guys think about it?