Dia is a nice cross platform application
for diagram drawing. It can be scripted via Python,
which opens the possibility to generate code from Dia diagrams.
Below we’ll create a python plugin that generates C code from UML state
machine diagrams. Doing the same for other languages should be trivial.
The first thing you need is Unai Estébanez Sevilla’s nice finite state
machine code generator. The version
that we are using here has been abstracted in order to be able to produce
code in various languages.
This python plugin implements an exporter
to C code. To use it, you need to put
it, along with the
base exporter into your local
plugins directory under ~/.dia/python.
Let’s have a quick look at the code.
First we import the dia python module and the exporter base functionality:
import dia
import uml_stm_export
Then we create our C exporter class that inherits from the generic
exporter:
class CDiagramRenderer(uml_stm_export.SimpleSTM):
Next we define how the beginning of our generated code file should look
like. That could include general infrastructure independent of the
state machine diagram at hand. In our case, we want to encapsulate the
generated state machine code within a function:
CODE_PREAMBLE="void config_stm(STM_t* stm) {"
We also define the postamble to close the function. After that come
generic functions that implement the class constructor
init(self)
and functions responsible for calling
the dia object parser begin_render(self,data,filename)
.
Now we define our output generator end_render(self)
. We
first traverse dia’s objects in order to find the state machine’s
initial state:
for transition in self.transitions:
if(transition.source == "INITIAL_STATE"):
The initial state state gets a special treatment: we have a special
function call generated for it:
f.write(" add_initial_state( stm, %s, %s );\n" %
(initial_state.name, initial_state.doaction))
Next we traverse all states and output code that will create them,
along with functions to be called within that state to decide on where
to transition next:
for key in self.states.keys():
f.write(" add_state( stm, %s, %s );\n"
% (state.name, state.doaction))
And finally we output all the transitions between states:
for transition in self.transitions:
f.write(" add_transition( stm, %s, %s, %s );\n" %
(transition.source, transition.trigger, transition.target))
and that’s nearly it. At the end of our generator we make sure to register it
with dia:
dia.register_export("State Machine Cstma Dump", "c", CDiagramRenderer())
Done! Simple, isn’t it?
Finally please permit me to thank all the people that created such a powerful
tool free for us to use:
- Unai Estébanez Sevilla for the original STM generator
- Steffen Macke and Hans Breuer, Dia’s current busy maintaners
- Alexander Larsson, Dia’s original author
- all the other contributors to Dia and free software
- Panter for inviting me to their fabulous work week in
Greece where most of the hacking on the generator was done and
Combitool who supported this work by needing
a state machine generator in their current project.
PS: Unai’s original text generator is now also “just” a “simple” addon