Scripts
From Plasmaworks
Overview
A Plasmacore Script is an object-oriented list of commands that are sequentially executed. A Script is used to enqueue a series of actions to be executed over time and is better suited to modeling pre-planned actions than a state machine.
To use scripts:
- [include "script.slag"]
- Add a Script property to any and all classes that could make use of it.
- Extend "Cmd", override on_activate() to perform setup, and override execute().Cmd to perform an action whenever Script::update() is called; return "this" to execute the same command on the next update() or return "next" to continue executing the next command.
- Add extended Cmd objects to a script with Script::add(Cmd).
- Add "CmdFn<<arbitrary code>>()" objects that execute a small piece of arbitrary code without having to create an entire class.
- Add predefined CmdWait(seconds) objects to pause script execution.
- Call Script::update().Logical to update a script. It will return "false" if there are no remaining commands.
- Use a CmdGroup object to execute multiple commands simultaneously. Each command can be its own Script if desired.
- Instead of returning "this" or "next" from Command::execute(), you can return a new Cmd object or chain of objects to be the next command.
Examples
# Test app that cycles the background color through red, green, and blue, changing every second.
# A debug message is printed out when the script is finished.
[include "script.slag"]
class Test : Screen
PROPERTIES
script() : Script
METHODS
method init
script.add( CmdWait(1) )
script.add( CmdBGColor(Color.red) )
script.add( CmdWait(1) )
script.add( CmdBGColor(Color.green) )
script.add( CmdWait(1) )
script.add( CmdBGColor(Color.blue) )
script.add( CmdFn<<println("Script finished")>>() )
method update
script.update
endClass
class CmdBGColor( Color color ) : Cmd
METHODS
method on_activate
Display.background_color = color
endClass
# Test app that moves a box to four corners of the screen
# over and over, changing the color of the box after every
# cycle.
[include "script.slag"]
singleton class Test : Screen
PROPERTIES
script() : Script
square(0,0,64,64) : Box
color=Color.red : Color
METHODS
method update
if (not script.update)
local var x2 = Display.size.x - 64
local var y2 = Display.size.y - 64
script.add( CmdMoveSquare( x2, 0, 1.0 ) )
script.add( CmdMoveSquare( x2, y2, 1.0 ) )
script.add( CmdMoveSquare( 0, y2, 1.0 ) )
script.add( CmdMoveSquare( 0, 0, 1.0 ) )
script.add( CmdFn<<Test.color=random_Color>>() )
endIf
method draw
square.fill( color )
endClass
class CmdMoveSquare( Real64 dest_x, Real64 dest_y, Real64 interval ) : Cmd
PROPERTIES
ticks : Int32
delta : Vector2
METHODS
method on_activate
ticks = interval * 60
delta = (Vector2(dest_x,dest_y) - Test.square.position) / ticks
method execute.Cmd
Test.square += delta
--ticks
if (ticks?) return this
else return next
endClass
# This script-based example types out a message, blinks
# it three times, and repeats.
[include "script.slag"]
singleton class Test : Screen
PROPERTIES
message : Message
script() : Script
METHODS
method init
message = Message( "Scripts are cool.", Display.center )
method update
if (not script.update)
script.add( CmdWaitFor(message) )
script.add( CmdFlash(message,3) )
script.add( CmdReset(message) )
endIf
method draw
message.draw
method on( MouseEvent e )
if (e.is_button_press) message.reset
endClass
class Message( String text, Vector2 position )
PROPERTIES
count : Int32
visible=true : Logical
script() : Script
METHODS
method reset
visible = true
count = 0
script.clear
method revealed.Logical
return (count == text.count)
method update
if (not script.update)
if (count < text.count)
++count
else
visible = not visible
endIf
script.add( CmdWait(0.20) )
endIf
method draw
if (visible)
SystemFont.handle = Handle.center
SystemFont.draw( text.leftmost(count), position )
endIf
endClass
class MessageCmd( Message message ) : Cmd;
class CmdWaitFor : MessageCmd
method execute.Cmd
message.update
if (message.revealed) return next
return this
endClass
class CmdFlash : Cmd
PROPERTIES
message : Message
times : Int32
METHODS
method init( message, times )
times = times * 2 + 1
method execute.Cmd
message.visible = not message.visible
--times
if (times?)
return CmdWait(0.2).chain(this)
else
return next
endIf
endClass
class CmdReset : MessageCmd
method on_activate
message.reset
endClass
Credits
The Plasmacore Script system is based on Paul Stevens's (Riverman Media) Action Queue system.