Nestharus
o-o
- Reaction score
- 84
So.. while working on Spawn 2.0 I got tired of writing this same sort of code over and over again : D. Ended up making a little scripty thing.
Normally collections are not boxed and their type is themselves. This may seem like a wonderful design, but for some cases it is not so wonderful =P, especially when you want to overwrite values and then undo those writes.
The goal of the script is to allow a struct to have values that can revert themselves. For example
and demo code
eh?
also you can do some very crazy objects
demo
I would specifically use this for mimicing data ^.^... for example, if you wanted a unit to mimic another unit for like a special Mimic spell that lasted bleh seconds, you could store the unit data, destroy your unit, and then clone the target.
If the target had like mimic health, you could overwrite health and w/e.
Normally collections are not boxed and their type is themselves. This may seem like a wonderful design, but for some cases it is not so wonderful =P, especially when you want to overwrite values and then undo those writes.
JASS:
//! textmacro MAKE_BOX_STACK takes DATA
private struct NodeX extends array
public thistype next
public static method create takes nothing returns thistype
return $DATA$.create()
endmethod
public method destroy takes nothing returns nothing
call $DATA$(this).destroy()
endmethod
endstruct
private keyword allocate
private keyword hasNext
private keyword push
private keyword pop
private keyword deallocate
private keyword clear
private module Stack
private static integer instanceCount = 0
private static thistype array recycle
private static integer recycleCount = 0
//stack pointer
private delegate $DATA$ first
public static method allocate takes nothing returns thistype
local thistype this
if (recycleCount != 0) then
set recycleCount = recycleCount - 1
set this = recycle[recycleCount]
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
set first = NodeX.create()
set NodeX(first).next = 0
return this
endmethod
public method operator hasNext takes nothing returns boolean
return NodeX(first).next != 0
endmethod
public method operator empty takes nothing returns boolean
return NodeX(first).next == 0
endmethod
public method push takes nothing returns nothing
local NodeX new = NodeX.create()
set new.next = first
set first = new
endmethod
public method pop takes nothing returns nothing
if (hasNext) then
call NodeX(first).destroy()
set first = NodeX(first).next
endif
endmethod
public method deallocate takes nothing returns nothing
loop
exitwhen first == 0
call NodeX(first).destroy()
set first = NodeX(first).next
endloop
set recycle[recycleCount] = this
set recycleCount = recycleCount + 1
endmethod
public method clear takes nothing returns nothing
loop
exitwhen empty
call NodeX(first).destroy()
set first = NodeX(first).next
endloop
endmethod
endmodule
//! endtextmacro
The goal of the script is to allow a struct to have values that can revert themselves. For example
JASS:
/////
private scope Origin
private struct Data extends array
private static integer instanceCount = 0
private static thistype array recycle
private static integer recycleCount = 0
public integer testData
public static method create takes nothing returns thistype
local thistype this
if (recycleCount != 0) then
set recycleCount = recycleCount - 1
set this = recycle[recycleCount]
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
return this
endmethod
public method destroy takes nothing returns nothing
set recycle[recycleCount] = this
set recycleCount = recycleCount + 1
endmethod
endstruct
//! runtextmacro MAKE_BOX_STACK("Data")
struct Origin extends array
implement Stack
public static method create takes nothing returns thistype
return allocate()
endmethod
public method overwrite takes nothing returns nothing
call push()
endmethod
public method revert takes nothing returns nothing
call pop()
endmethod
public method original takes nothing returns nothing
call clear()
endmethod
public method operator isSelf takes nothing returns boolean
return empty
endmethod
public method destroy takes nothing returns nothing
call deallocate()
endmethod
endstruct
endscope
and demo code
JASS:
scope TestCode
private struct Tester extends array
private static method onInit takes nothing returns nothing
local Origin origin = Origin.create()
set origin.testData = 5
call origin.overwrite()
set origin.testData = 12
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, I2S(origin.testData))
call origin.revert()
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, I2S(origin.testData))
//this commented code will not compile ^_^
//call origin.push()
endmethod
endstruct
endscope
eh?
also you can do some very crazy objects
JASS:
private scope Origin
private scope X
private struct Data extends array
private static integer instanceCount = 0
private static thistype array recycle
private static integer recycleCount = 0
public real x
public static method create takes nothing returns thistype
local thistype this
if (recycleCount != 0) then
set recycleCount = recycleCount - 1
set this = recycle[recycleCount]
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
return this
endmethod
public method destroy takes nothing returns nothing
set recycle[recycleCount] = this
set recycleCount = recycleCount + 1
endmethod
endstruct
//! runtextmacro MAKE_BOX_STACK("Data")
public struct Origin extends array
implement Stack
public static method create takes nothing returns thistype
return allocate()
endmethod
public method overwrite takes nothing returns nothing
call push()
endmethod
public method revert takes nothing returns nothing
call pop()
endmethod
public method original takes nothing returns nothing
call clear()
endmethod
public method operator isSelf takes nothing returns boolean
return empty
endmethod
public method destroy takes nothing returns nothing
call deallocate()
endmethod
endstruct
endscope
private scope Y
private struct Data extends array
private static integer instanceCount = 0
private static thistype array recycle
private static integer recycleCount = 0
public real y
public static method create takes nothing returns thistype
local thistype this
if (recycleCount != 0) then
set recycleCount = recycleCount - 1
set this = recycle[recycleCount]
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
return this
endmethod
public method destroy takes nothing returns nothing
set recycle[recycleCount] = this
set recycleCount = recycleCount + 1
endmethod
endstruct
//! runtextmacro MAKE_BOX_STACK("Data")
public struct Origin extends array
implement Stack
public static method create takes nothing returns thistype
return allocate()
endmethod
public method overwrite takes nothing returns nothing
call push()
endmethod
public method revert takes nothing returns nothing
call pop()
endmethod
public method original takes nothing returns nothing
call clear()
endmethod
public method operator isSelf takes nothing returns boolean
return empty
endmethod
public method destroy takes nothing returns nothing
call deallocate()
endmethod
endstruct
endscope
private struct Data extends array
private static integer instanceCount = 0
private static thistype array recycle
private static integer recycleCount = 0
private delegate X_Origin originx
private delegate Y_Origin originy
public static method create takes nothing returns thistype
local thistype this
if (recycleCount != 0) then
set recycleCount = recycleCount - 1
set this = recycle[recycleCount]
else
set instanceCount = instanceCount + 1
set this = instanceCount
endif
set originx = X_Origin.create()
set originy = Y_Origin.create()
return this
endmethod
public method operator xObj takes nothing returns X_Origin
return originx
endmethod
public method operator yObj takes nothing returns Y_Origin
return originy
endmethod
public method destroy takes nothing returns nothing
set recycle[recycleCount] = this
set recycleCount = recycleCount + 1
endmethod
endstruct
//! runtextmacro MAKE_BOX_STACK("Data")
struct Origin extends array
implement Stack
public static method create takes nothing returns thistype
return allocate()
endmethod
public method overwrite takes nothing returns nothing
call push()
endmethod
public method revert takes nothing returns nothing
call pop()
endmethod
public method original takes nothing returns nothing
call clear()
endmethod
public method operator isSelf takes nothing returns boolean
return empty
endmethod
public method destroy takes nothing returns nothing
call deallocate()
endmethod
endstruct
endscope
demo
JASS:
scope TestCode
private struct Tester extends array
private static method onInit takes nothing returns nothing
local Origin origin = Origin.create()
set origin.x = 1
set origin.y = 1
call origin.xObj.overwrite()
call origin.yObj.overwrite()
set origin.x = 2
set origin.y = 2
call origin.overwrite()
set origin.x = 3
set origin.y = 3
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.x))
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.y))
call origin.revert()
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.x))
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.y))
call origin.xObj.revert()
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.x))
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.y))
call origin.yObj.revert()
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.x))
call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(origin.y))
//this commented code will not compile ^_^
//call origin.push()
endmethod
endstruct
endscope
I would specifically use this for mimicing data ^.^... for example, if you wanted a unit to mimic another unit for like a special Mimic spell that lasted bleh seconds, you could store the unit data, destroy your unit, and then clone the target.
If the target had like mimic health, you could overwrite health and w/e.