From 1d390da417e8f088e3ba52ac395e84449e815598 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Thu, 14 Sep 2023 10:51:49 +0300 Subject: [PATCH 1/5] Pass std::shared_ptr by const reference instead of value, added const specifiers for 'get' functions, added default virtual destructor for Protothread since it has a virtual pure function that is supposed to be implemented in a derived class. Moved EnvObj class in simcpp namespace and declared its constructor explicit. --- protothread.h | 10 ++++++---- simcpp.cpp | 30 +++++++++++++++--------------- simcpp.h | 28 ++++++++++++++-------------- simobj.h | 17 +++++++++++------ 4 files changed, 46 insertions(+), 39 deletions(-) diff --git a/protothread.h b/protothread.h index a1a533e..28d3bb7 100644 --- a/protothread.h +++ b/protothread.h @@ -88,7 +88,9 @@ class Protothread public: // Construct a new protothread that will start from the beginning // of its Run() function. - Protothread() : _ptLine(0) { } + Protothread() = default; + + virtual ~Protothread() = default; // Restart protothread. void Restart() { _ptLine = 0; } @@ -100,7 +102,7 @@ class Protothread // Return true if the protothread is running or waiting, false if it has // ended or exited. - bool IsRunning() { return _ptLine != LineNumberInvalid; } + bool IsRunning() const { return _ptLine != LineNumberInvalid; } // Run next part of protothread or return immediately if it's still // waiting. Return true if protothread is still running, false if it @@ -110,14 +112,14 @@ class Protothread protected: // Used to store a protothread's position (what Dunkels calls a // "local continuation"). - typedef unsigned short LineNumber; + using LineNumber = unsigned short; // An invalid line number, used to mark the protothread has ended. static const LineNumber LineNumberInvalid = (LineNumber)(-1); // Stores the protothread's position (by storing the line number of // the last PT_WAIT, which is then switched on at the next Run). - LineNumber _ptLine; + LineNumber _ptLine = 0; }; // Declare start of protothread (use at start of Run() implementation). diff --git a/simcpp.cpp b/simcpp.cpp index cd40a1d..b541a13 100644 --- a/simcpp.cpp +++ b/simcpp.cpp @@ -9,7 +9,7 @@ namespace simcpp { SimulationPtr Simulation::create() { return std::make_shared(); } -void Simulation::run_process(ProcessPtr process, simtime delay /* = 0.0 */) { +void Simulation::run_process(const ProcessPtr& process, simtime delay /* = 0.0 */) { auto event = this->event(); event->add_handler(process); event->trigger(delay); @@ -52,7 +52,7 @@ EventPtr Simulation::all_of(std::initializer_list events) { return process; } -void Simulation::schedule(EventPtr event, simtime delay /* = 0.0 */) { +void Simulation::schedule(const EventPtr& event, simtime delay /* = 0.0 */) { queued_events.emplace(now + delay, next_id, event); ++next_id; } @@ -78,7 +78,7 @@ void Simulation::advance_by(simtime duration) { now = target; } -bool Simulation::advance_to(EventPtr event) { +bool Simulation::advance_to(const EventPtr& event) { while (event->is_pending() && has_next()) { step(); } @@ -99,7 +99,7 @@ simtime Simulation::peek_next_time() { return queued_events.top().time; } /* Simulation::QueuedEvent */ -Simulation::QueuedEvent::QueuedEvent(simtime time, size_t id, EventPtr event) +Simulation::QueuedEvent::QueuedEvent(simtime time, size_t id, const EventPtr& event) : time(time), id(id), event(event) {} bool Simulation::QueuedEvent::operator<(const QueuedEvent &other) const { @@ -112,15 +112,15 @@ bool Simulation::QueuedEvent::operator<(const QueuedEvent &other) const { /* Event */ -Event::Event(SimulationPtr sim) : sim(sim) {} +Event::Event(const SimulationPtr& sim) : sim(sim) {} -bool Event::add_handler(ProcessPtr process) { +bool Event::add_handler(const ProcessPtr& process) { // Handler takes an additional EventPtr arg, but this is ignored by the // bound function. return add_handler(std::bind(&Process::resume, process)); } -bool Event::add_handler(Handler handler) { +bool Event::add_handler(const Handler& handler) { if (is_triggered()) { return false; } @@ -167,30 +167,30 @@ void Event::process() { state = State::Processed; - for (auto &handler : handlers) { + for (const auto& handler : handlers) { handler(shared_from_this()); } handlers.clear(); } -bool Event::is_pending() { return state == State::Pending; } +bool Event::is_pending() const { return state == State::Pending; } -bool Event::is_triggered() { +bool Event::is_triggered() const { return state == State::Triggered || state == State::Processed; } -bool Event::is_processed() { return state == State::Processed; } +bool Event::is_processed() const { return state == State::Processed; } -bool Event::is_aborted() { return state == State::Aborted; } +bool Event::is_aborted() const { return state == State::Aborted; } -Event::State Event::get_state() { return state; } +Event::State Event::get_state() const { return state; } void Event::Aborted() {} /* Process */ -Process::Process(SimulationPtr sim) : Event(sim), Protothread() {} +Process::Process(const SimulationPtr& sim) : Event(sim), Protothread() {} void Process::resume() { // Is the process already finished? @@ -213,7 +213,7 @@ ProcessPtr Process::shared_from_this() { /* Condition */ -Condition::Condition(SimulationPtr sim, int n) : Process(sim), n(n) {} +Condition::Condition(const SimulationPtr& sim, int n) : Process(sim), n(n) {} bool Condition::Run() { PT_BEGIN(); diff --git a/simcpp.h b/simcpp.h index 751b8de..87ceee3 100644 --- a/simcpp.h +++ b/simcpp.h @@ -92,7 +92,7 @@ class Simulation : public std::enable_shared_from_this { * @param process Process to be run. * @param delay Delay after which to run the process. */ - void run_process(ProcessPtr process, simtime delay = 0.0); + void run_process(const ProcessPtr& process, simtime delay = 0.0); /** * Construct an event. @@ -142,7 +142,7 @@ class Simulation : public std::enable_shared_from_this { * @param event Event instance. * @param delay Delay after which the event is processed. */ - void schedule(EventPtr event, simtime delay = 0.0); + void schedule(const EventPtr& event, simtime delay = 0.0); /** * Process the next scheduled event. @@ -165,7 +165,7 @@ class Simulation : public std::enable_shared_from_this { * @return Whether the event was triggered. If no scheduled events are left or * the event is aborted, this is not the case. */ - bool advance_to(EventPtr event); + bool advance_to(const EventPtr& event); /// Run the simulation until no scheduled events are left. void run(); @@ -186,7 +186,7 @@ class Simulation : public std::enable_shared_from_this { size_t id; EventPtr event; - QueuedEvent(simtime time, size_t id, EventPtr event); + QueuedEvent(simtime time, size_t id, const EventPtr& event); bool operator<(const QueuedEvent &other) const; }; @@ -221,7 +221,7 @@ class Event : public std::enable_shared_from_this { * * @param sim Simulation instance. */ - explicit Event(SimulationPtr sim); + explicit Event(const SimulationPtr& sim); /** * Add the resume method of a process as an handler of the event. @@ -233,7 +233,7 @@ class Event : public std::enable_shared_from_this { * @param process The process to resume when the event is processed. * @return Whether the event was not already triggered. */ - bool add_handler(ProcessPtr process); + bool add_handler(const ProcessPtr& process); /** * Add the callback as an handler of the event. @@ -244,7 +244,7 @@ class Event : public std::enable_shared_from_this { * receives the event instance as an argument. * @return Whether the event was not already triggered. */ - bool add_handler(Handler handler); + bool add_handler(const Handler& handler); /** * Trigger the event with a delay. @@ -274,22 +274,22 @@ class Event : public std::enable_shared_from_this { void process(); /// @return Whether the event is pending. - bool is_pending(); + bool is_pending() const; /** * @return Whether the event is triggered. Also true if the event is * processed. */ - bool is_triggered(); + bool is_triggered() const; /// @return Whether the event is aborted. - bool is_aborted(); + bool is_aborted() const; /// @return Whether the event is processed. - bool is_processed(); + bool is_processed() const; /// @return Whether the event is pending. - State get_state(); + State get_state() const; /// Called when the event is aborted. virtual void Aborted(); @@ -316,7 +316,7 @@ class Process : public Event, public Protothread { * * @param sim Simulation instance. */ - explicit Process(SimulationPtr sim); + explicit Process(const SimulationPtr& sim); /** * Resumes the process. @@ -339,7 +339,7 @@ class Condition : public Process { * @param sim Simulation instance. * @param n Number of times the process must be resumed before it finishes. */ - Condition(SimulationPtr sim, int n); + Condition(const SimulationPtr& sim, int n); /** * Wait for the given number of resumes and then finish. diff --git a/simobj.h b/simobj.h index af7c7e3..1dc0b39 100644 --- a/simobj.h +++ b/simobj.h @@ -13,10 +13,15 @@ public: \ this->NAM##_event = std::make_shared(env); \ } -class EnvObj { -protected: - shared_ptr env; -public: - EnvObj(shared_ptr s) : env(s) {} -}; +namespace simcpp { + + class EnvObj { + protected: + std::shared_ptr env; + + public: + explicit EnvObj(const std::shared_ptr& s) : env(s) {} + }; + +} From d8cc9c14af35885ee7600a9884755b3167737a52 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Thu, 14 Sep 2023 11:17:48 +0300 Subject: [PATCH 2/5] More const specifiers --- simcpp.cpp | 13 ++++++------- simcpp.h | 6 +++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/simcpp.cpp b/simcpp.cpp index b541a13..7dca500 100644 --- a/simcpp.cpp +++ b/simcpp.cpp @@ -23,7 +23,7 @@ EventPtr Simulation::timeout(simtime delay) { EventPtr Simulation::any_of(std::initializer_list events) { int n = 1; - for (auto &event : events) { + for (const auto &event : events) { if (event->is_triggered()) { n = 0; break; @@ -39,7 +39,7 @@ EventPtr Simulation::any_of(std::initializer_list events) { EventPtr Simulation::all_of(std::initializer_list events) { int n = 0; - for (auto &event : events) { + for (const auto &event : events) { if (!event->is_triggered()) { ++n; } @@ -87,15 +87,14 @@ bool Simulation::advance_to(const EventPtr& event) { } void Simulation::run() { - while (step()) { - } + while (step()); } -simtime Simulation::get_now() { return now; } +simtime Simulation::get_now() const { return now; } -bool Simulation::has_next() { return !queued_events.empty(); } +bool Simulation::has_next() const { return !queued_events.empty(); } -simtime Simulation::peek_next_time() { return queued_events.top().time; } +simtime Simulation::peek_next_time() const { return queued_events.top().time; } /* Simulation::QueuedEvent */ diff --git a/simcpp.h b/simcpp.h index 87ceee3..450b847 100644 --- a/simcpp.h +++ b/simcpp.h @@ -171,13 +171,13 @@ class Simulation : public std::enable_shared_from_this { void run(); /// @return Current simulation time. - simtime get_now(); + simtime get_now() const; /// @return Whether a scheduled event is left. - bool has_next(); + bool has_next() const; /// @return Time at which the next event is scheduled. - simtime peek_next_time(); + simtime peek_next_time() const; private: class QueuedEvent { From ac060dabfe663760781b924084a920d2bd496e22 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Sat, 16 Sep 2023 08:40:49 +0300 Subject: [PATCH 3/5] Since EnvObj is intended to be derived from, I added there a virtual destructor as well --- simobj.h | 1 + 1 file changed, 1 insertion(+) diff --git a/simobj.h b/simobj.h index 1dc0b39..4774807 100644 --- a/simobj.h +++ b/simobj.h @@ -22,6 +22,7 @@ namespace simcpp { public: explicit EnvObj(const std::shared_ptr& s) : env(s) {} + virtual ~EnvObj() = default; }; } From f917e314f423c43e9e60e84b5614d13d7a355476 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Sat, 16 Sep 2023 09:12:07 +0300 Subject: [PATCH 4/5] Some more things in order to have a class derived from EnvObj compiled --- simobj.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/simobj.h b/simobj.h index 4774807..8ce2e06 100644 --- a/simobj.h +++ b/simobj.h @@ -1,3 +1,6 @@ +#ifndef SIMOBJ_H_ +#define SIMOBJ_H_ + #include "simcpp.h" #define OBSERVABLE_PROPERTY(TYP, NAM, VAL) \ @@ -5,24 +8,27 @@ private: \ TYP NAM = VAL; \ \ public: \ - shared_ptr NAM##_event = std::make_shared(env); \ - TYP get_##NAM() { return this->NAM; } \ + simcpp::EventPtr NAM##_event{std::make_shared(env)}; \ + TYP get_##NAM() const { return this->NAM; } \ void set_##NAM(TYP v) { \ this->NAM = v; \ this->env->schedule(this->NAM##_event); \ - this->NAM##_event = std::make_shared(env); \ + this->NAM##_event = std::make_shared(env); \ } namespace simcpp { - class EnvObj { - protected: - std::shared_ptr env; +class EnvObj { +protected: + SimulationPtr env; - public: - explicit EnvObj(const std::shared_ptr& s) : env(s) {} - virtual ~EnvObj() = default; - }; +public: + explicit EnvObj(const SimulationPtr& s) : env(s) {} + virtual ~EnvObj() = default; +}; } + + +#endif From 5441e21d2298e800ccecd1c24e08c687f55dba64 Mon Sep 17 00:00:00 2001 From: Adrian Roman Date: Sat, 16 Sep 2023 09:25:18 +0300 Subject: [PATCH 5/5] Formatting --- simobj.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simobj.h b/simobj.h index 8ce2e06..e0211f8 100644 --- a/simobj.h +++ b/simobj.h @@ -8,12 +8,12 @@ private: \ TYP NAM = VAL; \ \ public: \ - simcpp::EventPtr NAM##_event{std::make_shared(env)}; \ + simcpp::EventPtr NAM##_event{std::make_shared(env)}; \ TYP get_##NAM() const { return this->NAM; } \ void set_##NAM(TYP v) { \ this->NAM = v; \ this->env->schedule(this->NAM##_event); \ - this->NAM##_event = std::make_shared(env); \ + this->NAM##_event = std::make_shared(env); \ }