Examples
========
Timer
-----
This example demonstrates the timed behavior of SCCD. It does not have dynamic structure.
We model a clock which prints the current time every 0.05 seconds. Two clocks are printed: the current wall-clock time and the current simulated time. We expect both to (almost) be the same. The user can interrupt the clock by sending an "interrupt" event. The user can resume the clock by sending a "resume" event.
Threads (Python)
^^^^^^^^^^^^^^^^
In this version, the model sends the current times to an output port, on which the user listens, to print out these times. *self.getSimulatedTime()* and *time()* return the current time in milliseconds, which we have to convert to seconds.
The SCCD model::
from sccd.runtime.accurate_time import time
To compile, save this in a file called ``timer.xml`` and run ``python -m sccd.compiler.sccdc -p threads -l python timer.xml``
Then, the following file will run the model::
import timer
from sccd.runtime.statecharts_core import Event
import threading
if __name__ == '__main__':
controller = timer.Controller()
def raw_inputter():
while 1:
controller.addInput(Event(raw_input(), "input", []))
input_thread = threading.Thread(target=raw_inputter)
input_thread.daemon = True
input_thread.start()
output_listener = controller.addOutputListener(["output"])
def outputter():
while 1:
event = output_listener.fetch(-1)
print "SIMTIME: %.2fs" % (event.getParameters()[0] / 1000.0)
print "ACTTIME: %.2fs" % (event.getParameters()[1] / 1000.0)
output_thread = threading.Thread(target=outputter)
output_thread.daemon = True
output_thread.start()
controller.start()
The time will be printed to the console. The user can send events by typing the string "interrupt" or "continue" in the console.
Eventloop (Python)
^^^^^^^^^^^^^^^^^^
The SCCD model::
from sccd.runtime.libs.ui import ui
from sccd.runtime.accurate_time import time
self.canvas.element.itemconfigure(self.clock_text, text=str('%.2f' % (self.getSimulatedTime() / 1000.0)))
self.canvas.element.itemconfigure(self.actual_clock_text, text='%.2f' % (time() / 1000.0))
To compile, save this in a file called ``timer.xml`` and run ``python -m sccd.compiler.sccdc -p eventloop -l python timer.xml``
Then, the following file will run the model::
import Tkinter as tk
import timer
from sccd.runtime.libs.ui import ui
from sccd.runtime.statecharts_core import Event
from sccd.runtime.tkinter_eventloop import *
if __name__ == '__main__':
ui.window = tk.Tk()
controller = timer.Controller(TkEventLoop(ui.window))
controller.start()
ui.window.mainloop()
Eventloop (Javascript)
^^^^^^^^^^^^^^^^^^^^^^
The SCCD model::
this.clock_text.set_text((this.getSimulatedTime() / 1000).toFixed(2));
this.actual_clock_text.set_text((this.getSimulatedTime() / 1000).toFixed(2));
To compile, save this in a file called ``timer.xml`` and run ``python -m sccd.compiler.sccdc -p eventloop -l javascript timer.xml``
Then, the following file will run the model::
Traffic Lights
--------------
The traffic lights example demonstrates most functionality of SCCD. There are three lights (green, yellow, and red). The traffic light autonomously switches between them, but also listens for a police interrupt, which will flash the yellow light. When a second interrupt comes in, the light returns to its last configuration (using a history state).
Python
^^^^^^
The SCCD model::
from sccd.runtime.libs.ui import ui
To compile, save this in a file called ``trafficlight.xml`` and run ``python -m sccd.compiler.sccdc -p eventloop -l python trafficlight.xml``
Then, the following file will run the model::
import Tkinter as tk
import trafficlight
from sccd.runtime.libs.ui import ui
from sccd.runtime.statecharts_core import Event
from sccd.runtime.tkinter_eventloop import *
if __name__ == '__main__':
ui.window = tk.Tk()
controller = trafficlight.Controller(TkEventLoop(ui.window))
controller.start()
ui.window.mainloop()
Javascript
^^^^^^^^^^
The SCCD model::
To compile, save this in a file called ``trafficlight.xml`` and run ``python -m sccd.compiler.sccdc -p eventloop -l javascript trafficlight.xml``
Then, the following file will run the model::