Permalink
Browse files

Merge pull request #87 from sstiller/event-data

Add _event system variable if string events enabled
  • Loading branch information...
jp-embedded committed Dec 6, 2018
2 parents d89a661 + 54ba49e commit 8a5802176aa8a88e6f8692bd7bab26733e5becbb
Showing with 47 additions and 14 deletions.
  1. +29 −9 src/cpp_output.cpp
  2. +10 −1 src/cpp_output.h
  3. +1 −1 src/examples/CMakeLists.txt
  4. +4 −1 src/main.cpp
  5. +1 −0 src/options.h
  6. +2 −2 src/test/CMakeLists.txt
@@ -444,11 +444,19 @@ void cpp_output::gen_model_base_data()

constructs.push_back(make_pair("user", "user"));

if(!opt.bare_metal) {
if(!opt.bare_metal) {
out << tab << tab << "const std::string _sessionid;\n";
constructs.push_back(make_pair("_sessionid", "std::to_string(reinterpret_cast<long long unsigned int>(this))"));
out << tab << tab << "const std::string _name;\n";
constructs.push_back(make_pair("_name", "\"" + sc.sc().name + "\""));
if(opt.string_events) {
// _event
out << tab << tab << "struct EventStruct {\n";
out << tab << tab << tab << "std::string name;\n";
out << tab << tab << tab << any_ns << "any data;\n";
out << tab << tab << tab << "void clear () { name.clear(); data = " << any_ns << "any(); };\n";
out << tab << tab << "} _event;\n";
}
}
for (scxml_parser::data_list::const_iterator i_data = datamodel.begin(); i_data != datamodel.end(); ++i_data) {
string id = i_data->get()->id;
@@ -605,12 +613,12 @@ void cpp_output::gen_model_base()
out << tab << tab << tab << "lock.unlock();" << endl;
out << tab << tab << tab << "cv.notify_one();" << endl;
out << tab << tab << "}" << endl;
out << tab << tab << "std::optional<event> pop_event()" << endl;
out << tab << tab << optional_ns << "optional<event> pop_event()" << endl;
out << tab << tab << "{" << endl;
out << tab << tab << tab << "std::lock_guard<std::mutex> lock(queue_mutex);" << endl;
out << tab << tab << tab << "return pop_event_no_lock();" << endl;
out << tab << tab << "}" << endl;
out << tab << tab << "std::optional<event> wait_event()" << endl;
out << tab << tab << optional_ns << "optional<event> wait_event()" << endl;
out << tab << tab << "{" << endl;
out << tab << tab << tab << "std::unique_lock<std::mutex> lock(queue_mutex);" << endl;
out << tab << tab << tab << "cv.wait(lock, [this]{ return !event_queue.empty() || cancel_wait_; });" << endl;
@@ -625,7 +633,7 @@ void cpp_output::gen_model_base()
out << tab << tab << "bool is_canceled() const { return cancel_wait_; }" << endl;
out << tab << "private:" << endl;
out << tab << tab << "friend void " << classname() << "::dispatch(event);" << endl;
out << tab << tab << "std::optional<event> pop_event_no_lock()" << endl;
out << tab << tab << optional_ns << "optional<event> pop_event_no_lock()" << endl;
out << tab << tab << "{" << endl;
out << tab << tab << tab << "if (event_queue.empty()) return std::nullopt;" << endl;
out << tab << tab << tab << "event e = event_queue.front();" << endl;
@@ -966,11 +974,14 @@ void cpp_output::gen_sc()
out << tab << "}" << endl;
// dispatch by name
if(opt.string_events) {
out << tab << "public: void dispatch(const std::string& ev_name)" << endl;
out << tab << "public: void dispatch(const std::string& ev_name, " << any_ns << "any data = " << any_ns << "any())" << endl;
out << tab << "{" << endl;
if(opt.thread_safe) {
out << tab << tab << "event_map_mutex.lock();" << endl;
}
out << tab << tab << "model._event.name = ev_name;\n";
out << tab << tab << "model._event.data = data;\n";

out << tab << tab << "auto event_it = event_map.find(ev_name);" << endl;
out << tab << tab << "if(event_it != event_map.end()) {" << endl;
if(opt.thread_safe) {
@@ -1350,13 +1361,22 @@ void cpp_output::gen()
}
if(opt.thread_safe) {
out << "#include <condition_variable>" << endl;
out << "#include <optional>" << endl;
if(opt.cpp14) {
out << "#include <boost/optional.hpp>\n";
} else {
out << "#include <optional>\n";
}
}
if(opt.string_events) {
out << "#include <unordered_map>" << endl;
if(opt.thread_safe) {
out << "#include <mutex>" << endl;
}
if(opt.cpp14) {
out << "#include <boost/any.hpp>\n";
} else {
out << "#include <any>\n";
}
if(opt.thread_safe) {
out << "#include <mutex>" << endl;
}
}
if(sc.using_log || opt.debug) {
out << "#include <iostream>" << endl;
@@ -30,9 +30,18 @@ class cpp_output {
const scxml_parser &sc;
const options &opt;
std::string tab;
const std::string any_ns; // namespace for any in generated code
const std::string optional_ns;

public:
cpp_output(std::ostream &ofs, const scxml_parser &sc, const options &op) : out(ofs), sc(sc), opt(op), tab("\t") {};
cpp_output(std::ostream &ofs, const scxml_parser &sc, const options &op)
: out(ofs)
, sc(sc)
, opt(op)
, tab("\t")
, any_ns(op.cpp14 ? "boost::" : "std::")
, optional_ns(any_ns)
{};

void gen();

@@ -11,7 +11,7 @@ scxmlcc_generator( ${S}/microwave-01-cplusplus.scxml microwave_gen_src )
scxmlcc_generator( ${S}/microwave-02-cplusplus.scxml microwave_gen_src )
scxmlcc_generator( ${S}/vending_machine/vending_machine.scxml vending_gen_src )

set (CMAKE_CXX_STANDARD 11)
set (CMAKE_CXX_STANDARD 17)

add_executable( hello_world
hello_world.cpp
@@ -59,9 +59,10 @@ int main(int argc, char *argv[])
("debug,d", "Enable debug output")
("ignore-unknown,u", value<string>(), "ignore unknown xml elements matching regex")
("baremetal,b", "Generate code for bare metal C++")
("threadsafe,t", "Generate threadsafe code for event_queue (requires c++17)")
("threadsafe,t", "Generate threadsafe code for event_queue")
("stringevents,s", "Enable triggering events by name")
("namespace,n", value<string>(), "Generate code in given namespace")
("cpp14", "Generate code for C++14 instead of C++17, needs boost")
("version,v", "Version and copyright information");
positional_options_description pdesc;
pdesc.add("input", -1);
@@ -85,6 +86,8 @@ int main(int argc, char *argv[])
if(vm.count("baremetal")) opt.bare_metal = true;
if(vm.count("threadsafe")) opt.thread_safe = true;
if(vm.count("stringevents")) opt.string_events = true;
opt.cpp14 = (vm.count("cpp14") != 0);

if(vm.count("namespace")) opt.ns = vm["namespace"].as<string>();

if(!opt.input.empty() && opt.output.empty()) {
@@ -29,6 +29,7 @@ struct options
bool bare_metal = false;
bool thread_safe = false;
bool string_events = false;
bool cpp14 = false;
std::string ns = "";
};

@@ -32,7 +32,7 @@ add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
EXCLUDE_FROM_ALL)

set( CMAKE_INCLUDE_CURRENT_DIR ON )
set( CMAKE_CXX_STANDARD 11 )
set( CMAKE_CXX_STANDARD 17 )


############################################
@@ -67,8 +67,8 @@ scxmlcc_generator( ${CMAKE_CURRENT_SOURCE_DIR}/stringevents.scxml gen_src )
add_executable( test_scxml
${gen_src}
test.cpp
test_t.cpp
)
# test_t.cpp currently disabled because dies not work with scxmlcc_generator

target_link_libraries(test_scxml
gtest_main

0 comments on commit 8a58021

Please sign in to comment.