From e8062df3404532433d73593aa71720e71ca4b0a3 Mon Sep 17 00:00:00 2001 From: Thomas Horstink Date: Sun, 12 Nov 2023 21:25:37 +0100 Subject: [PATCH] move traits to symmetri namespace --- CMakeLists.txt | 2 +- Doxyfile | 2 +- examples/flight/flight.cc | 30 ++++++++------------- examples/performance/performance.cpp | 2 +- symmetri/include/symmetri/callback.h | 39 +++++++++++++++++----------- symmetri/include/symmetri/parsers.h | 2 +- symmetri/include/symmetri/symmetri.h | 14 +++++----- symmetri/include/symmetri/tasks.h | 2 +- symmetri/include/symmetri/types.h | 9 ++++++- symmetri/petri.cc | 9 ++----- symmetri/petri.h | 6 ++--- symmetri/symmetri.cc | 13 +++++----- symmetri/tasks.cpp | 10 +++++++ symmetri/tests/test_callback.cc | 6 ++--- symmetri/types.cpp | 5 ++++ 15 files changed, 85 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 274bd77..d73fd6e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ add_subdirectory(symmetri) # some examples using the lib if(BUILD_EXAMPLES) - # add_subdirectory(examples/flight) + add_subdirectory(examples/flight) add_subdirectory(examples/hello_world) add_subdirectory(examples/combinations) add_subdirectory(examples/performance) diff --git a/Doxyfile b/Doxyfile index 6972fca..b46d44c 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1017,7 +1017,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = symmetri/submodules symmetri/small_vector.hpp symmetri/include/symmetri/maxplus.hpp symmetri/tests symmetri/queue +EXCLUDE = symmetri/submodules symmetri/small_vector.hpp symmetri/include/symmetri/maxplus.hpp symmetri/tests symmetri/queue symmetri/gui # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/examples/flight/flight.cc b/examples/flight/flight.cc index 39a8152..f84b248 100644 --- a/examples/flight/flight.cc +++ b/examples/flight/flight.cc @@ -1,15 +1,13 @@ #include +#include +#include #include #include +#include -#include "symmetri/parsers.h" -#include "symmetri/symmetri.h" -#include "symmetri/utilities.hpp" #include "transition.hpp" -using namespace symmetri; - /** * @brief We want to use the Foo class with Symmetri; Foo has nice * functionalities such as Pause and Resume and it can also get @@ -19,10 +17,11 @@ using namespace symmetri; * all - if nothing is defined, a default version is used. * */ +const static symmetri::Token FooFail(symmetri::Color::registerToken("FooFail")); -const static Token FooFail(Color::registerToken("FooFail")); - -Token fire(const Foo &f) { return f.fire() ? FooFail : Color::Success; } +symmetri::Token fire(const Foo &f) { + return f.fire() ? FooFail : symmetri::Color::Success; +} void cancel(const Foo &f) { f.cancel(); } @@ -37,21 +36,14 @@ void resume(const Foo &f) { f.resume(); } */ void printLog(const symmetri::Eventlog &eventlog) { for (const auto &[caseid, t, s, c] : eventlog) { - spdlog::info("EventLog: {0}, {1}, {2}, {3}", caseid, t, Color::toString(s), - c.time_since_epoch().count()); + spdlog::info("EventLog: {0}, {1}, {2}, {3}", caseid, t, + symmetri::Color::toString(s), c.time_since_epoch().count()); } } -void writeMermaidHtmlToFile(const std::string &mermaid) { - std::ofstream mermaid_file; - mermaid_file.open("examples/flight/mermaid.html"); - mermaid_file << "
" + mermaid + "
"; - mermaid_file.close(); - - return; -} - int main(int, char *argv[]) { + using namespace symmetri; + spdlog::set_pattern("[%Y-%m-%d %H:%M:%S.%f] [%^%l%$] [thread %t] %v"); // We get some paths to PNML-files diff --git a/examples/performance/performance.cpp b/examples/performance/performance.cpp index 3d64db9..6e9b349 100644 --- a/examples/performance/performance.cpp +++ b/examples/performance/performance.cpp @@ -9,9 +9,9 @@ symmetri::Token fire(const Simple &) { i++; return symmetri::Color::Success; } -using namespace symmetri; int main(int argc, char *argv[]) { + using namespace symmetri; auto pool = std::make_shared(1); PetriNet petri = [=] { if (argc > 1) { diff --git a/symmetri/include/symmetri/callback.h b/symmetri/include/symmetri/callback.h index 7ee6f0f..7c217ab 100644 --- a/symmetri/include/symmetri/callback.h +++ b/symmetri/include/symmetri/callback.h @@ -6,6 +6,8 @@ #include "symmetri/types.h" +namespace symmetri { + /** * @brief Checks if the callback is synchronous. Synchronous callbacks are * immediately executed inside the Petri net executor. Asynchronous callbacks @@ -81,8 +83,6 @@ symmetri::Eventlog getLog(const T &) { return {}; } -namespace symmetri { - /** * @brief Callback is a wrapper around any type that you to tie to a * transition. Typically this is an invokable object, such as a function, that @@ -101,21 +101,30 @@ class Callback { /** * @brief Construct a new Callback object * - * @param cb is the Callback instance + * @param callback is the Callback instance */ - Callback(Transition cb) - : self_(std::make_shared>(std::move(cb))) {} - - Token operator()() const { return this->self_->fire_(); } - void operator()(Eventlog &el) const { el = this->self_->get_log_(); } - friend Token fire(const Callback &cb) { return cb.self_->fire_(); } - friend Eventlog getLog(const Callback &cb) { return cb.self_->get_log_(); } - friend bool isSynchronous(const Callback &cb) { - return cb.self_->is_synchronous_(); + Callback(Transition callback) + : self_(std::make_shared>(std::move(callback))) {} + + // void operator()(Eventlog &el) const { el = this->self_->get_log_(); } + friend Token fire(const Callback &callback) { + return callback.self_->fire_(); + } + friend Eventlog getLog(const Callback &callback) { + return callback.self_->get_log_(); + } + friend bool isSynchronous(const Callback &callback) { + return callback.self_->is_synchronous_(); + } + friend void cancel(const Callback &callback) { + return callback.self_->cancel_(); + } + friend void pause(const Callback &callback) { + return callback.self_->pause_(); + } + friend void resume(const Callback &callback) { + return callback.self_->resume_(); } - friend void cancel(const Callback &cb) { return cb.self_->cancel_(); } - friend void pause(const Callback &cb) { return cb.self_->pause_(); } - friend void resume(const Callback &cb) { return cb.self_->resume_(); } private: struct concept_t { diff --git a/symmetri/include/symmetri/parsers.h b/symmetri/include/symmetri/parsers.h index bc7f047..15a0d9c 100644 --- a/symmetri/include/symmetri/parsers.h +++ b/symmetri/include/symmetri/parsers.h @@ -32,7 +32,7 @@ std::tuple readGrml( * register tokens for the color attributes that are in the arcs that go from a * place to a transition. * - * @param files + * @param pnml-files * @return std::tuple */ std::tuple readPnml( diff --git a/symmetri/include/symmetri/symmetri.h b/symmetri/include/symmetri/symmetri.h index 043aede..f70f40f 100644 --- a/symmetri/include/symmetri/symmetri.h +++ b/symmetri/include/symmetri/symmetri.h @@ -19,7 +19,9 @@ namespace symmetri { struct Petri; /** - * @brief PetriNet exposes the possible constructors to create PetriNets. + * @brief PetriNet exposes the possible constructors to create PetriNets. It + * also allows the user to register a Callback to a transition, or to get a + * handle for input-transitions. * */ class PetriNet final { @@ -98,11 +100,11 @@ class PetriNet final { */ bool reuseApplication(const std::string &case_id); - friend symmetri::Token(::fire)(const PetriNet &); - friend void(::cancel)(const PetriNet &); - friend void(::pause)(const PetriNet &); - friend void(::resume)(const PetriNet &); - friend symmetri::Eventlog(::getLog)(const PetriNet &); + friend symmetri::Token(symmetri::fire)(const PetriNet &); + friend void(symmetri::cancel)(const PetriNet &); + friend void(symmetri::pause)(const PetriNet &); + friend void(symmetri::resume)(const PetriNet &); + friend symmetri::Eventlog(symmetri::getLog)(const PetriNet &); private: const std::shared_ptr diff --git a/symmetri/include/symmetri/tasks.h b/symmetri/include/symmetri/tasks.h index 7487b6d..dbbf904 100644 --- a/symmetri/include/symmetri/tasks.h +++ b/symmetri/include/symmetri/tasks.h @@ -45,7 +45,7 @@ class TaskSystem { TaskSystem& operator=(TaskSystem&&) noexcept = delete; /** - * @brief push tasks the the queue for later execution on the thread pool. + * @brief push tasks the queue for later execution on the thread pool. * * @param p */ diff --git a/symmetri/include/symmetri/types.h b/symmetri/include/symmetri/types.h index c2744c3..e8d8f80 100644 --- a/symmetri/include/symmetri/types.h +++ b/symmetri/include/symmetri/types.h @@ -49,10 +49,15 @@ using PriorityTable = std::vector>; ///< Priority is limited from ///< -128 to 127 +/** + * @brief A DirectMutation is a synchronous no-operation function. It simply + * mutates the mutation on the petri net executor loop. This way the deferring + * to the threadpool and back to the petri net loop is avoided. + * + */ struct DirectMutation {}; class PetriNet; -} // namespace symmetri /** * @brief A DirectMutation is a synchronous Callback that always * completes. @@ -108,3 +113,5 @@ void resume(const symmetri::PetriNet &); * @return symmetri::Eventlog */ symmetri::Eventlog getLog(const symmetri::PetriNet &); + +} // namespace symmetri diff --git a/symmetri/petri.cc b/symmetri/petri.cc index 2b82530..a766cc4 100644 --- a/symmetri/petri.cc +++ b/symmetri/petri.cc @@ -1,10 +1,5 @@ #include "petri.h" -bool isSynchronous(const symmetri::DirectMutation &) { return true; } -symmetri::Token fire(const symmetri::DirectMutation &) { - return symmetri::Color::Success; -} - namespace symmetri { std::tuple, std::vector, std::vector, std::vector> @@ -242,8 +237,8 @@ Eventlog Petri::getLogInternal() const { } // get event log from parent nets: - for (const auto &cb : net.store) { - Eventlog sub_el = getLog(cb); + for (const auto &callback : net.store) { + Eventlog sub_el = getLog(callback); if (!sub_el.empty()) { eventlog.insert(eventlog.end(), sub_el.begin(), sub_el.end()); } diff --git a/symmetri/petri.h b/symmetri/petri.h index d803385..cf6f9f6 100644 --- a/symmetri/petri.h +++ b/symmetri/petri.h @@ -32,7 +32,7 @@ inline bool operator>(const AugmentedToken &lhs, const AugmentedToken &rhs) { } /** - * @brief a minimal event representation. + * @brief a minimal Event representation. * */ struct SmallEvent { @@ -256,10 +256,10 @@ struct Petri { std::vector store; void registerCallback(const std::string &t, - const symmetri::Callback &cb) noexcept { + const symmetri::Callback &callback) noexcept { if (std::find(transition.begin(), transition.end(), t) != transition.end()) { - store[toIndex(transition, t)] = cb; + store[toIndex(transition, t)] = callback; } } } net; ///< Is a data-oriented design of a Petri net diff --git a/symmetri/symmetri.cc b/symmetri/symmetri.cc index f6a5201..772d897 100644 --- a/symmetri/symmetri.cc +++ b/symmetri/symmetri.cc @@ -71,10 +71,11 @@ std::function PetriNet::getInputTransitionHandle( } } -void PetriNet::registerCallback(const std::string &transition, - const symmetri::Callback &cb) const noexcept { +void PetriNet::registerCallback( + const std::string &transition, + const symmetri::Callback &callback) const noexcept { if (!impl->thread_id_.load().has_value()) { - impl->net.registerCallback(transition, cb); + impl->net.registerCallback(transition, callback); } } @@ -98,10 +99,6 @@ bool PetriNet::reuseApplication(const std::string &new_case_id) { return false; } -} // namespace symmetri - -using namespace symmetri; - symmetri::Token fire(const PetriNet &app) { if (app.impl->thread_id_.load().has_value()) { return symmetri::Color::Failed; @@ -193,3 +190,5 @@ Eventlog getLog(const PetriNet &app) { return app.impl->getLogInternal(); } } + +} // namespace symmetri diff --git a/symmetri/tasks.cpp b/symmetri/tasks.cpp index 67f3585..1bd57b6 100644 --- a/symmetri/tasks.cpp +++ b/symmetri/tasks.cpp @@ -4,7 +4,17 @@ namespace symmetri { +/** + * @brief An alias for the implementation. In this case + * moodycamel::BlockingConcurrentQueue. + * + */ using Queue = moodycamel::BlockingConcurrentQueue; + +/** + * @brief TaskQueue is an inheritance based alias for a lock-free queue. + * + */ class TaskQueue : public Queue { using Queue::Queue; }; diff --git a/symmetri/tests/test_callback.cc b/symmetri/tests/test_callback.cc index bfd8a92..de21f24 100644 --- a/symmetri/tests/test_callback.cc +++ b/symmetri/tests/test_callback.cc @@ -3,8 +3,6 @@ #include "symmetri/callback.h" -using namespace symmetri; - class Foo { public: Foo(std::string name) : name(name), constructor(1), copy_constructor(0) { @@ -23,13 +21,15 @@ class Foo { const int copy_constructor; }; -Token fire(const Foo&) { return Color::Success; } +symmetri::Token fire(const Foo&) { return symmetri::Color::Success; } void resume(const Foo& f) { CHECK(f.constructor == 1); CHECK(f.copy_constructor == 0); } +using namespace symmetri; + TEST_CASE("Constructing is just as you expect") { Foo o("one_constructor"); CHECK(o.constructor == 1); diff --git a/symmetri/types.cpp b/symmetri/types.cpp index 0932883..cd3b21a 100644 --- a/symmetri/types.cpp +++ b/symmetri/types.cpp @@ -6,6 +6,11 @@ #include "symmetri/colors.hpp" namespace symmetri { +bool isSynchronous(const symmetri::DirectMutation&) { return true; } +symmetri::Token fire(const symmetri::DirectMutation&) { + return symmetri::Color::Success; +} + const std::string& Color::toString(symmetri::Token r) { return Color::map[r]; } const Token& Color::registerToken(const std::string& s) {