Observer is an alternative to global IF statements that are often used as Gamestate = #SOMETHING.
I might write a tutorial regarding this one day.
Code: Select all
Observer = { table = {} }
Function Observer:Add(name, message, func, ...) /* ... part are possible arguments */
self.table[name] = { message=message, func=func, arg=arg }
EndFunction
Function Observer:Remove(name)
self.table[name] = Nil
EndFunction
Function Observer:Execute(name)
subtable = self.table[name]
arg = subtable.arg
subtable.func(Unpack(arg))
EndFunction
Function Observer:Inform(message)
For name, itemtable In Pairs(self.table)
If itemtable.message = message Then observer:execute(name)
Next
EndFunction
Function Observer:ListObservers() /* This is simply for debugging reasons */
ForEach(observer.table, DebugPrint)
EndFunction
Code: Select all
Function card1(n)
Local temptable = {
[1] = { funcinadvance = init_up, name="card1", message="up is done", func=card1, arg=2, },
[2] = { funcinadvance = Init_down, name="card1", message="down is done", func=card1, arg=3, },
[3] = { funcinadvance = init_up, name="card1", message="up is done", func=card1, arg=4, },
[4] = { funcinadvance = Init_down, name="card1", message="down is done", func=card1, arg=5, },
[5] = { funcinadvance = init_up, name="card1", message="up is done", func=card1, arg=6, },
[6] = { funcinadvance = Init_down, name="card1", message="down is done", func=card1, arg=7, },
[7] = { funcinadvance = init_up, name="card1", message="up is done", func=card1, arg=8, },
[8] = { funcinadvance = Init_down, name="card1", message="down is done", func=card1, arg=9, },
[9] = { funcinadvance = init_up, name="card1", message="up is done", func=card1, arg=10, }
}
If n = 0 Then n=1
observer:remove("card1")
If n < 10
temptable[n].funcinadvance()
name="card1"
message = temptable[n].message
func = temptable[n].func
arg = temptable[n].arg
observer:add(name, message, func, arg)
EndIf
EndFunction
Function init_upcounter()
var_upcounter = 0
TextOut(100, 300, "upcounter: "..var_upcounter, {name="upcounterlayer"} )
observer:add("upcounter", "up is done", upcounter)
EndFunction
Function upcounter()
var_upcounter=var_upcounter + 1
SetLayerStyle("upcounterlayer", {text="upcounter: "..var_upcounter} )
If var_upcounter = 3
observer:remove("upcounter")
EndIf
EndFunction
Function init_up()
TextOut(300, 300, "press up", {name="up"})
SetInterval(2, up, 15)
EndFunction
Function up()
Local pressed = False
If IsKeyDown("UP") = True Then pressed = True
If pressed = True
RemoveLayer("up")
ClearInterval(2)
Observer:inform("up is done")
EndIf
EndFunction
Function init_down()
TextOut(300, 400, "press down", {name="down"})
SetInterval(3, down, 15)
EndFunction
Function Down()
Local pressed = False
If IsKeyDown("DOWN") = True Then pressed = True
If pressed = True
RemoveLayer("down")
ClearInterval(3)
Observer:inform("down is done")
EndIf
EndFunction
Function updategraphics()
If dir = 0 Then x=x-3
If dir = 1 Then x=x+3
If x <100 Then dir = 1
If x >500 Then dir = 0
SetLayerStyle("text1", {x=x})
EndFunction
EnableLayers
TextOut(100, 100, "moving text", {name="text1"})
SetInterval(1, UpdateGraphics, 15)
card1()
init_upcounter()
Repeat
WaitEvent()
Forever
This works the following.
To add something to be Observed, is to use:
Code: Select all
Observer:Add(name, message, function, args)
MESSAGE is the message that this observer is waiting for before it starts executing its FUNCTION.
FUNCTION is the function that will be executed if observer receives the MESSAGE.
ARGS are one or more args (it uses ...) that are going to be passed to the FUNCTION when MESSAGE is received.
then somewhere in your code needs to be:
Code: Select all
Observer:Inform(message)
Code: Select all
Observer:Remove(name)
Code: Select all
Observer:ListObservers()