jp-embedded / scxmlcc Goto Github PK
View Code? Open in Web Editor NEWThe SCXML state machine to C++ compiler
License: GNU General Public License v3.0
The SCXML state machine to C++ compiler
License: GNU General Public License v3.0
In the README.md, you mention LCA:
LCA calculation is done (mostly) compile time.
I've been trying to figure out what is meant by LCA... Do you mean LCCA (Least Common Compound Ancestor) that is mentioned in https://www.w3.org/TR/scxml/#LCCA ?
At least one of the attributes event, cond or target must be specified
If a signal is triggered with <raise>
, but it has no matching transition in the SM, it leads to a compile error.
The solution should be similar to the fix for #69
Example:
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="raise" datamodel="cplusplus">
<state id="State_1">
<onentry>
<raise event="ev1"/>
</onentry>
</state>
</scxml>
Result:
raise.h: In member function ‘void sc_raise::state_actions<C>::enter(sc_raise::data_model&) [with C = sc_raise::state_State_1]::with::operator()()’:
raise.h:163:46: error: ‘event_ev1’ is not a member of ‘sc_raise::state’
event_queue.emplace_back(&sc_raise::state::event_ev1);
^~~~~~~~~
Could you give me a example about get_state,this function has a "public" in class sc, how can i use it to get the current state,thanks
The README mentions that "However, the generated state machine code is not covered by license." What does that mean. Does this mean that the generated code's license is up to the user? He can license the way he wants.
or the user needs to obtain some special license if his code is not going to be open source.
This is a suggestion for improvement:
It would be nice if it was possible to pass additional data when dispatching an event. I currently get around this by placing data in the user_model area, but it complicates control of the access in a multi-threaded environment. It would be much simpler if one could pass payload data alongside the event instance when firing events.
scxmlcc version should be generated equally on windows/linux with make and cmake
note from pull request 55:
Well the version is/should be the same on windows and unix. The thing is, the autorevision tool is currently not used on windows and therefore the postfix part of the version is currently left out on windows (in version.cpp) - I am mainly using linux. If it is possible to use the autorevision tool on windows I think that would be the best solution since autorevision is a more generic way of doing it. Anyway, the goal must be to use the same method on windows/unix/make/cmake. Note that the current method will work also when build from a zip file or even if the source is checked out using subversion.
Is there really a way to run these tests, or are they broken?
if condition of all transitions evaluates to false, search parent
For each atomic state , find a transition whose 'event' attribute matches event
and whose condition evaluates to true. If multiple matching transitions are
present, take the first in document order. If none are present, search in the
state's ancestors in ancestry order until one is found.
Original issue reported on code.google.com by [email protected]
on 9 Jan 2015 at 3:54
I've tried compiling the attached file that was created with the QtCreator editor and got the following error:
error: parse_log: No such node ()
It's not really clear to me if this is an unsupported attribute , a bug , or if the file generated but QtCreator is invalid.
It seems impossible to put your own type for the entries - float, std::vector, some custom structure (#include "custom_struct.h" prior to), etc.
Data in SCXML like that:
<!-- trivial 5 second microwave oven example -->
<datamodel>
<data id="cook_time" expr="5"/>
<data id="door_closed" expr="true"/>
<data id="timer" expr="0"/>
</datamodel>
produce the following snippet:
//...
int cook_time;
int door_closed;
int timer;
data_model() : cook_time(5), door_closed(true), timer(0) {}
//...
Is it known to fixing it or how to workaround it in a different way?
For example if have something like that:
<!-- trivial 5 second microwave oven example -->
<datamodel>
<data id="CustomStruct1 cust" expr=""/>
<data id="float flt" expr="0.5"/>
</datamodel>
how the output will become (or anything compilable close to):
//...
#include "<path_to_my_custom_header.h>"
CustomStruct1 cust;
float flt;
data_model() : cust(), flt(0.5) {}
//...
I'm trying to implement a persistent state machine. One of the requirements is on powerup the state machine goes straight into the last saved state, without any on-entry actions being invoked. Looking into the implementation, I can't see how this can be done with scxmlcc generated state machine directly.
I can think of work-arounds, but it would greatly simplify things if the state machine constructor could accept the initial state as a parameter.
I have a problem with the type of data_model::user
:
user_model
- and it can not be fully declared by a userreinterpret_cast
must be used in the constructor of the state machineWouldn't it be better to use void* user
, as done in other libraries?
Note that the child transition must not contain cond
or event
attributes, and must specify a target
whose value is state(s) consisting solely of descendants of the containing state
At least for non-parallel machines.
To avoid the RTTI overhead on eg embedded systems
is the fsm thread safe?can i run it in multiple thread safety
What do you think about a logging function, defined by the user?
In my case the logs of the state machine do not fit into the logging concept. The logs shall be sent to stderr or to a logging server depending on the current log level.
Before I add something, I'd like to know what other people think about it.
The readme.md you write:
For a chat, you can also write to me on messenger here
Just wondering if this is still valid?
The text inside <script> ... </script>
is modified resulting in uncompilable code.
Example:
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="script">
<state id="State_1">
<onentry>
<script>auto str = new std::string("Hello");
str->append(" world");
std::cout << *str << '\n';
delete str;</script>
</onentry>
</state>
<script>#include <iostream></script>
</scxml>
In the generated code, the text str->append
is replaced by str_>append
instead of str->append
Compiler error:
parallel.h: In member function ‘void sc_parallel::state_P1::parallel_enter_final(sc_parallel::data_model&)’:
parallel.h:268:98: error: ‘event_done_state_P1’ is not a member of ‘sc_parallel::state’
void parallel_enter_final(data_model &m) { if (++m.finals.P1 == 2) m.event_queue.emplace_back(&sc_parallel::state::event_done_state_P1), parent_t::parallel_enter_final(m); }
Example scxml:
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="parallel" initial="P1">
<parallel id="P1">
<state id="P1S1">
<onentry/>
<onexit/>
<state id="P1S11">
<onentry/>
<transition type="external" event="ev" target="P1S11"/>
</state>
</state>
<state id="P1S2">
<onentry/>
<state id="P1S21">
<onentry/>
<onexit/>
<transition type="external" event="ev" target="Final"/>
</state>
<onexit/>
<final id="Final">
</final>
</state>
<onentry/>
<transition type="external" event="ev2" target="S1">
</transition>
<onexit/>
</parallel>
<state id="S1">
<onentry/>
</state>
</scxml>
Hi,
First, thank you for sxcmlcc, it is a great tool!
I was wondering if you could document what scxml tags are currently implemented. In particular I am interested in the following
Thanks
Christophe
'sc::state::unconditional' is bad naming. The transition is not unconditional, but eventless. Consider to change this to for example 'sc::state::eventless' or 'sc::state::none'
when compiling the project "example/hello_world.cpp" error pops up:
Error[Pe1449]: explicit specialization of function "sc_hello_world::state_actions::enter [with C=sc_hello_world::state_hello]" must precede its first use
Using the latest release, 0.8.7 the cmake compilation fails with:
CMake Error at src/test/CMakeLists.txt:6 (add_subdirectory):
The source directory
/home/marius/kit/scxmlcc-0.8.7/src/test/gtest
does not contain a CMakeLists.txt file.
Hello, hope that the invoker attribute of external interaction can be added later.
It is decided that this is also one of the basic functions
Thanks
I get the following error when building
cmake ..
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
ma-- Detecting CXX compile features - done
k-- Boost version: 1.58.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- program_options
eCMake Error at src/test/CMakeLists.txt:6 (add_subdirectory):
The source directory
/home/jdamon/Downloads/scxmlcc/src/test/gtest
does not contain a CMakeLists.txt file.
-- Configuring incomplete, errors occurred!
If I run
touch ../src/test/gtest/CMakeLists.txt
nice build (master)% cmake ..
-- Boost version: 1.58.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- program_options
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jdamon/Downloads/scxmlcc/build
nice build (master)% make
[ 1%] Generating ../version_auto.h
...
Then it works
multiple targets must be a valid configuration
Hello,
I've downloaded the project and all of the required libraries, but when I tried to build it I got the following errors:
autorevision -tsh > autorevision.mk && sh makerevision.sh || truncate -s0 autorevision_postfix.h
warning: Counting the number of revisions may be slower due to an outdated git version less than 1.7.2.3. If something breaks, please update it.
g++ -Wall -O2 -MD -MP -c -o main.o main.cpp
main.cpp: In function ‘void scxmlcc(const options&)’:
main.cpp:41: error: ‘struct std::basic_string<char, std::char_traits, std::allocator >’ has no member named ‘string’
main.cpp:44: error: ‘const struct boost::filesystem::path’ has no member named ‘c_str’
main.cpp: In function ‘int main(int, char*)’:
main.cpp:69: error: ‘cerr’ was not declared in this scope
main.cpp:86: error: ‘cout’ was not declared in this scope
main.cpp:108: error: ‘cout’ was not declared in this scope
main.cpp:117: error: ‘cerr’ was not declared in this scope
make: ** [main.o] Error 1
If a parallel state and one of its descendants have a transition with the same event, the wrong transition is executed.
At least I understand the algorithm in this way:
selectTransitions(event)
selects both transitions and calls removeConflictingTransitions
removeConflictingTransitions
removes the transition with the source P1
because P1S1S1
is a descendant of P1
P1S1S1
) is executed.Behavior of the state machine generated by scxmlcc:
P1
) is executed.The SCXML code:
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="parallelevent">
<parallel id="P1">
<state id="P1S1">
<state id="P1S1S1">
<transition type="external" event="ev1" target="P1S1S2"/>
</state>
<state id="P1S1S2">
</state>
</state>
<state id="P1S2">
<state id="P1S2S1">
</state>
</state>
<transition type="external" event="ev1" target="Final_1"/>
</parallel>
<final id="Final_1">
</final>
</scxml>
Test program:
#include <iostream>
#include "parallelevent.h"
using namespace std;
typedef sc_parallelevent sc;
int main(int argc, char *argv[])
{
sc sc;
sc.init();
std::clog << "event here\n";
sc.dispatch("ev1");
return 0;
}
scxmlcc command line:
scxmlcc -d clog --cpp14 --stringevents -o parallelevent.h parallelevent.scxml
log:
$ ./parallelevent
sc_parallelevent: transition [initial] sc_parallelevent::scxml -> sc_parallelevent::state_P1
sc_parallelevent: enter sc_parallelevent::state_P1
sc_parallelevent: transition [initial] sc_parallelevent::state_P1 -> sc_parallelevent::state_P1S1
sc_parallelevent: enter sc_parallelevent::state_P1S1
sc_parallelevent: enter sc_parallelevent::state_P1S2
sc_parallelevent: transition [initial] sc_parallelevent::state_P1S2 -> sc_parallelevent::state_P1S2S1
sc_parallelevent: enter sc_parallelevent::state_P1S2S1
sc_parallelevent: transition [initial] sc_parallelevent::state_P1S1 -> sc_parallelevent::state_P1S1S1
sc_parallelevent: enter sc_parallelevent::state_P1S1S1
event here
sc_parallelevent: transition [event_ev1] sc_parallelevent::state_P1 -> sc_parallelevent::state_Final_1
sc_parallelevent: exit sc_parallelevent::state_P1S1S1
sc_parallelevent: exit sc_parallelevent::state_P1S1
sc_parallelevent: exit sc_parallelevent::state_P1S2S1
sc_parallelevent: exit sc_parallelevent::state_P1S2
sc_parallelevent: exit sc_parallelevent::state_P1
sc_parallelevent: enter sc_parallelevent::state_Final_1
There may be more than one event - separated with space - in a transition
definition. This case not handled in the r90 version.
Original issue reported on code.google.com by [email protected]
on 11 Feb 2014 at 10:25
Hello,
In cpp_output.cpp, there is the following code (line 887):
// new_state
out << tab << "template<class T> T* new_state()" << endl;
out << tab << '{' << endl;
out << tab << tab << "static T t;" << endl;
out << tab << tab << "return &t;" << endl;
out << tab << "};" << endl;
out << "};" << endl;
out << endl;
The last ; is not necessary. GCC warns about this extra ; if the -Wpedantic option is used.
Is there any good reason not to remove it?
Best regards,
Bktero
r90
Original issue reported on code.google.com by [email protected]
on 11 Feb 2014 at 10:19
Probably related to #56
I can't build scxmlcc using tar package. It is failing on Generating ../version_auto.h
.
Steps to reproduce:
wget https://github.com/jp-embedded/scxmlcc/archive/0.9.tar.gz
tar axf 0.9.tar.gz
mkdir build && cd build
cmake ../scxmlcc-0.9
make
Output:
$ make
[ 16%] Generating ../version_auto.h
error: No repo or cache detected.
src/CMakeFiles/scxmlcc.dir/build.make:61: recipe for target 'version_auto.h' failed
make[2]: *** [version_auto.h] Error 1
CMakeFiles/Makefile2:85: recipe for target 'src/CMakeFiles/scxmlcc.dir/all' failed
make[1]: *** [src/CMakeFiles/scxmlcc.dir/all] Error 2
Makefile:129: recipe for target 'all' failed
make: *** [all] Error 2
Tested on ubutnu 16.04 and 18.04.
standard says:
When the state machine reaches the child of an element, it must terminate
support for multiple transitions for same event:
For each atomic state , find a transition whose 'event' attribute matches event
and whose condition evaluates to true. If multiple matching transitions are
present, take the first in document order. If none are present, search in the
state's ancestors in ancestry order until one is found.
Original issue reported on code.google.com by [email protected]
on 9 Jan 2015 at 3:45
Some states (children of parallel) are left if another parallel state is entered.
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="multiparallel" initial="P1">
<parallel id="P1">
<state id="P1S1">
</state>
<parallel id="P1P1">
<state id="P1P1S1">
</state>
<state id="P1P1S2">
</state>
</parallel>
</parallel>
</scxml>
C++ code:
#include "multi-parallel.h"
int main(int argc, char *argv[])
{
sc_multiparallel sc;
sc.init();
return 0;
}
On start, all the states should be active, but as you can see, when entering P1P1S1
, the state P1S1
is left:
sc_multiparallel: transition [initial] sc_multiparallel::scxml -> sc_multiparallel::state_P1
sc_multiparallel: enter sc_multiparallel::state_P1
sc_multiparallel: transition [initial] sc_multiparallel::state_P1 -> sc_multiparallel::state_P1S1
sc_multiparallel: enter sc_multiparallel::state_P1S1
sc_multiparallel: enter sc_multiparallel::state_P1P1
sc_multiparallel: transition [initial] sc_multiparallel::state_P1P1 -> sc_multiparallel::state_P1P1S1
sc_multiparallel: exit sc_multiparallel::state_P1S1
sc_multiparallel: enter sc_multiparallel::state_P1P1S1
sc_multiparallel: enter sc_multiparallel::state_P1P1S2
Hello,
version.h contains 0.8.3 in both master/head and tag for version 0.8.5. I guess this is obviously wrong ;)
Best regards,
Bktero
If empty <raise/>
actions exist in the document, scxmlcc gives up:
error: parse_raise: No such node (<xmlattr>)
The same problem seems to exist for other elements, too.
See also #62
Example:
<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="raise_err" initial="State_1">
<state id="State_1">
<onentry>
<raise/>
</onentry>
</state>
</scxml>
@aboseley I'm trying to use the cmake build procedure you added. I'm getting the following error:
$ cmake ..
-- The C compiler identification is GNU 7.2.0
-- The CXX compiler identification is GNU 7.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.66.0
-- Found the following Boost libraries:
-- filesystem
-- system
-- program_options
CMake Error at src/test/CMakeLists.txt:6 (add_subdirectory):
The source directory
/home/jringle-admin/git/scxmlcc/src/test/gtest
does not contain a CMakeLists.txt file.
-- Configuring incomplete, errors occurred!
See also "/home/jringle-admin/git/scxmlcc/build/CMakeFiles/CMakeOutput.log".
Are there instructions that can be added to the getting-started.md to properly populate src/test/gtest/
?
Is there a way to get the dispatch to evaluate all conditional transitions in a state to see if any of them are true?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.