- Joined
- May 9, 2014
- Messages
- 1,806
Good day, everyone.
The TriggerAction in the JASS world had seen better days, but when triggerconditions came into light, it was discovered that triggeractions leaked (caused handle-id count to increase), even when
In the test environment of the making of this thread, (v.1.29+ onwards), it was found that triggeractions alone do not cause leaks when destroyed, but when triggerconditions are introduced, the resulting effect would be that triggeractions ended up leaking. This suggests that the list of triggeractions is possibly nested within the list of triggerconditions, if the list of triggerconditions exists in the first place (e.g. there is at least one triggercondition).
For the reason why they (the lists) could not possibly be separate from each other, the presence of leaks reaffirms the stance above, once triggerconditions are added. If they are separate from each other, then the exposed native
NOTE: Pseudo-code below
This is not a new finding, as some have discovered this before me, but this hopes to improve on how triggers and their subsets, triggeractions and triggerconditions, are internally handled.
EDIT:
Added a Test Map
The TriggerAction in the JASS world had seen better days, but when triggerconditions came into light, it was discovered that triggeractions leaked (caused handle-id count to increase), even when
DestroyTrigger
was invoked. This led to a radical shift in JASS, from the usage of triggeraction, to a merged triggercondition.In the test environment of the making of this thread, (v.1.29+ onwards), it was found that triggeractions alone do not cause leaks when destroyed, but when triggerconditions are introduced, the resulting effect would be that triggeractions ended up leaking. This suggests that the list of triggeractions is possibly nested within the list of triggerconditions, if the list of triggerconditions exists in the first place (e.g. there is at least one triggercondition).
For the reason why they (the lists) could not possibly be separate from each other, the presence of leaks reaffirms the stance above, once triggerconditions are added. If they are separate from each other, then the exposed native
DestroyTrigger
would destroy both lists without much trouble. This leads to a possible data structure of a trigger:NOTE: Pseudo-code below
JASS:
import GenericList // Design of pseudo-code inspired by Bannar's ListT
// classes in this context are considered Abstract Classes
class Callback
readonly functionPointer func
stub method execute takes nothing returns nothing
delete
this.func = null
enddelete
construct takes functionPointer func
this.func = func
endconstruct
endclass
struct TriggerAction extends Callback
override method execute takes nothing returns nothing
this.func()
endmethod
endstruct
struct TriggerCondition extends Callback
override method execute takes nothing returns Boolean
return this.func()
endmethod
endstruct
struct Trigger
List<T> executeList
method evaluate takes nothing returns boolean
if (executeList.typeOf == TriggerAction)
return true
ListIterator<TriggerCondition> iter = executeList.first
while (iter.data.execute()) or (iter.next != 0)
// As the list of triggeractions is contained in the last node, exclude it, as it can cause issues
iter = iter.next
return true
endmethod
method execute takes nothing returns nothing
let tempList = (List<TriggerAction>) executeList.last.data
ListIterator<TriggerAction> iter = tempList.first
while (iter != 0)
iter.data.execute()
iter = iter.next
endmethod
method clearConditions takes nothing returns nothing
if (executeList.typeOf == TriggerAction)
return
ListIterator<TriggerCondition> iter = executeList.first
while (iter != 0)
if (iter.typeOf == TriggerCondition>
del iter.data // destroy iter.data
executeList.erase(iter)
iter = executeList.first
endmethod
method clearActions takes nothing returns nothing
if (executeList.typeOf == TriggerAction)
ListIterator<TriggerAction> iter = executeList.first
while (iter != 0)
del iter.data
executeList.erase(iter)
iter = executeList.first
endmethod
method addCondition takes functionPointer func returns TriggerCondition
if (executeList.typeOf == TriggerAction)
let newList = new List<TriggerCondition>()
newList<T>.unshift( (TriggerCondition) executeList)
executeList = newList
let tempListTypeCast = executeList.last
let result = new TriggerCondition(func)
newList.erase(tempListTypeCast)
newList.push(result)
newList.push(tempListTypeCast)
return result
endmethod
method addAction takes functionPointer func returns TriggerAction
let result = new TriggerAction(func)
if (executeList.typeOf == TriggerCondition)
let tempList = (List<TriggerAction>) executeList.last.data
tempList.push(result)
else
executeList.push(result)
return result
endmethod
method removeCondition takes TriggerCondition cond returns boolean
if (executeList.typeOf == TriggerAction)
return false
let removedNode = executeList.find(cond) // type is ListIterator<TriggerCondition>
if removedNode == null
return false
del removedNode.data
executeList.erase(removedNode)
return true
endmethod
method removeAction takes TriggerAction act returns boolean
if (executeList.typeOf == TriggerCondition)
let tempList = (List<TriggerAction>) executeList.last.data
else
let tempList = executeList
let removedNode = tempList.find(act) // type is ListIterator<TriggerAction>
if removedNode == null
return false
del removedNode.data
tempList.erase(removedNode)
return true
endmethod
delete
.clearConditions()
.clearActions()
del .executeList
.executeList = null[/COLOR][/FONT][/LEFT]
enddelete
construct
executeList = new List<TriggerAction>()
endconstruct
endstruct
This is not a new finding, as some have discovered this before me, but this hopes to improve on how triggers and their subsets, triggeractions and triggerconditions, are internally handled.
EDIT:
Added a Test Map
Attachments
Last edited: