Real Time Example
You can easily write a real-time scripting engine. Here's a settings file:
# init.bsd
: MODE = (STRICT, TRUE)
# Init
$ win_apptitle = Real Time Scripting Example
! win_width = 640
! win_height = 480
! win_depth = 32
? win_mode = CONST_WIN_WINDOWED
! win_flags = CONST_WIN_SHOWBORDER + CONST_WIN_SHOWMINIMIZE + CONST_WIN_SHOWCLOSE
# Real Time
! rtv_width = win_width
! rtv_height = win_height
$ rtv_message = Hello#COMMA# World!
: MODE = (STRICT, FALSE)
: DUMP = (vvars.txt)
And here's a real-time script that our program will read:
Don't worry about reading it all - it just contains some conditions, and some functions with parameters to execute if those conditions are true.
# script.brt
# listener condition="expression" compare="type" priority="int"
# Compare is the sort of comparasion that is done
# on the expression - string, integer, real or boolean
# Priority is how often the script is executed,
# e.g. 1 is once per loop (always)
# 10 is once every 10 loops, (less often)
<listener condition="TRUE" compare="boolean" priority="1">
<function name="cls" params="" />
</listener>
<listener condition="MOUSEX < 200" compare="integer" priority="1">
<function name="rect" params="0,0,200,rtv_height, 255,0,0" />
</listener>
<listener condition="MOUSEX < 100" compare="integer" priority="1">
<function name="rect" params="0,0,100,rtv_height, 255,255,0" />
</listener>
<listener condition="MOUSEX > (rtv_width - 200)" compare="integer" priority="1">
<function name="rect" params="rtv_width - 200,0,200,rtv_height, 255,0,0" />
</listener>
<listener condition="MOUSEX > (rtv_width - 100)" compare="integer" priority="1">
<function name="rect" params="rtv_width - 100,0,100,rtv_height, 255,255,0" />
</listener>
<listener condition="TRUE" compare="boolean" priority="1">
<function name="text" params="10,10,This is all scripted in real-time" />
<function name="text" params="10,30,Move the mouse to the left or right to see the scripted program in action" />
<function name="text" params="10,50,MouseX: MOUSEX, MouseY: MOUSEY" />
<function name="text" params="10,70,Screen Width: [rtv_width]#COMMA# Height: [rtv_height]" />
<function name="text" params="MOUSEX + 20,MOUSEY+10,[rtv_message]" />
</listener>
If you notice, it can use variables from the settings file.
Here's a program to put the two together:
Program
Uses pure2d, basilisk, keyset
Const
MAX_SCRIPT_LENGTH = 20
Type Listeners = Record
ListenerFunc : Array [MAX_SCRIPT_LENGTH] of String
ListenerParams : Array [MAX_SCRIPT_LENGTH] of String
ListenerPriority : Integer
ListenerCondition : String
ListenerCompare : Integer
ListenerLength : Integer
EndType
Procedure Error(msg: String)
Begin
MessageBox(msg,"Real Time Scripting Example Error")
End
Procedure LoadRealTimeScript(fname: String)
Var
myfile : Element
fileIn : String
ladddone : Boolean
laddcount : Integer
laddcomp : String
Begin
myfile = ReadFile(fname)
While Not EOF(myfile)
fileIn = TrimSpaces(ReadLn(myfile))
Conditions
(Left(fileIn,1) = "#"):
(fileIn=""):
(Left(fileIn,10)="<listener "):
Listener = NewItem(ListenerList)
Listener.ListenerCondition = AttributeAsString(fileIn,"condition")
Listener.ListenerPriority = AttributeAsInteger(fileIn,"priority")
laddcomp = Lower(AttributeAsString(fileIn,"compare"))
Conditions
(laddcomp="integer"): Listener.ListenerCompare = VVAR_INTEGER
(laddcomp="real"): Listener.ListenerCompare = VVAR_REAL
(laddcomp="string"): Listener.ListenerCompare = VVAR_STRING
(laddcomp="boolean"): Listener.ListenerCompare = VVAR_BOOLEAN
Default: Error("Unknown comparason mode: "+laddcomp)
EndConditions
ladddone = FALSE
laddcount = 0
While ladddone=FALSE
If EOF(myfile) then ladddone=TRUE
fileIn = TrimSpaces(ReadLn(myfile))
If fileIn = "</listener>" then
ladddone = TRUE
Else
If fileIn <> "" then
Listener.ListenerFunc[laddcount] = AttributeAsString(fileIn,"name")
Listener.ListenerParams[laddcount] = ","+AttributeAsString(fileIn,"params")
Inc(laddcount)
Endif
Endif
Wend
Listener.ListenerLength = laddcount - 1
Default:
Error("Error reading script instrucion: "+fileIn)
EndConditions
Wend
CloseFile(myfile)
End
Procedure UpdateListeners()
Var
count : static Integer
sdo : Boolean
i : Integer
lfunc, lparams : String
Begin
Inc(count)
If (count>10000) then count = 1
Loop Listener Through ListenerList
If (count Mod Listener.ListenerPriority = 0) then
sdo = FALSE
Case Listener.ListenerCompare of
(VVAR_INTEGER): If IntegerExpressionIsTrue(ListenerVarReplace(Listener.ListenerCondition)) then sdo=TRUE
(VVAR_REAL): If RealExpressionIsTrue(ListenerVarReplace(Listener.ListenerCondition)) then sdo=TRUE
(VVAR_STRING): If StringExpressionIsTrue(ListenerVarReplace(Listener.ListenerCondition)) then sdo=TRUE
(VVAR_BOOLEAN): If BooleanExpressionIsTrue(ListenerVarReplace(Listener.ListenerCondition)) then sdo=TRUE
EndCase
If sdo Then
For i = 0 to Listener.ListenerLength
lfunc = Listener.ListenerFunc[i]
lparams = ListenerVarReplace(Listener.ListenerParams[i])
Conditions
(lfunc="cls"): Cls
(lfunc="text"):
Text(ParameterAsInteger(lparams,1,TRUE),ParameterAsInteger(lparams,2,TRUE),NiceText(ParameterAsString(lparams,3,TRUE)))
(lfunc="rect"):
Rect(ParameterAsInteger(lparams,1,TRUE), ParameterAsInteger(lparams,2,TRUE), ParameterAsInteger(lparams,3,TRUE), ParameterAsInteger(lparams,4,TRUE), ToRGBA(ParameterAsInteger(lparams,5,TRUE),ParameterAsInteger(lparams,6,TRUE),ParameterAsInteger(lparams,7,TRUE)),TRUE)
Default: Error("Unknown function: '"+lfunc+"'")
EndConditions
Next
Endif
Endif
EndLoop
End
Function ListenerVarReplace(str: String) : String
Begin
str = Replace(str, "MOUSEX", MouseX, FALSE)
str = Replace(str, "MOUSEY", MouseY, FALSE)
result = str
End
Function NiceText(str: String) : String
Begin
str = Replace(str, "#COMMA#",",", FALSE)
result = str
End
Var
ListenerList : List of Listeners
Listener : ^Listeners
Begin
InitBasilisk(TRUE)
ReadSettings("init.bsd")
SetAppName(VirtualString("win_apptitle"))
OpenScreen(VirtualInteger("win_width"),VirtualInteger("win_height"),VirtualInteger("win_depth"),VirtualBoolean("win_mode"),VirtualInteger("win_flags"))
FreeVirtualVariablesPrefixed("win_")
LoadRealTimeScript("script.brt")
While Not ExitRequested
UpdateListeners()
Flip
Pause(1)
If (KeyHits(VK_ESCAPE) > 0) then RequestExit
Wend
End