diff --git a/alobe/actor.cpp b/alobe/actor.cpp new file mode 100644 index 0000000..43aa751 --- /dev/null +++ b/alobe/actor.cpp @@ -0,0 +1,47 @@ +#include "actor.h" + +/** + * Constructor + */ +Actor::Actor(): + events(vector >()) +{ +} + +/** + * Attach an event + */ +void Actor::attach(shared_ptr event) +{ + events.push_back(event); +} + +/** + * Detach an event + */ +void Actor::detach(Event & event) +{ + for ( + vector >::iterator eventIterator = events.begin(); + eventIterator != events.end(); + ) { + if ((*eventIterator).get() == &event) { + events.erase(eventIterator); + } else { + ++eventIterator; + } + } +} + +/** + * Notification called by a Stepper object + */ + void Actor::notify(unsigned int step) +{ + for ( + vector >::iterator eventIterator = events.begin(); + eventIterator != events.end(); + ) { + (*eventIterator)->action(*this, step); + } +} diff --git a/alobe/actor.h b/alobe/actor.h new file mode 100644 index 0000000..7f88be8 --- /dev/null +++ b/alobe/actor.h @@ -0,0 +1,27 @@ +#ifndef __ALOBE__ACTOR__ +#define __ALOBE__ACTOR__ + +#include + +#include "event.h" + +using namespace std; + +/** + * <> Actor + * + * Actor in the simulation + */ +class Actor +{ + public: + Actor(); + void attach(shared_ptr event); // Attach an event + void detach(Event & event); // Detach an event + void notify(unsigned int step); // Notification called by a Stepper object + + private: + vector > events; +}; + +#endif // __ALOBE__ACTOR__ diff --git a/alobe/event.cpp b/alobe/event.cpp index eef17b5..85741c6 100644 --- a/alobe/event.cpp +++ b/alobe/event.cpp @@ -3,26 +3,16 @@ /** * Constructor */ -Event::Event(unsigned int step): - triggerStep(step) +Event::Event(unsigned int step) { } /** - * Notification called by the Stepper + * Trigger event action on an actor with a given step */ -void Event::notify(unsigned int step) +void Event::action(Actor & actor, unsigned int step) { - if (step == this->getTriggerStep()) - { - this->action(); + if (step == triggerStep) { + this->filteredAction(actor); } } - -/** - * Getter for triggerStep - */ -unsigned int Event::getTriggerStep() -{ - return triggerStep; -} diff --git a/alobe/event.h b/alobe/event.h index 86d9c46..e1938c7 100644 --- a/alobe/event.h +++ b/alobe/event.h @@ -1,24 +1,28 @@ -#ifndef __alobe__event__ -#define __alobe__event__ +#ifndef __ALOBE__EVENT__ +#define __ALOBE__EVENT__ + +class Actor; + +//using namespace std; /** * <> Event * - * An event is trigger by the Stepper it is attached to, through its notify method. - * The action() method will be called if the passed step value is equal to triggerStep. + * An event is trigger by an actor, which passes itself and the current step to the event */ class Event { public: - Event(unsigned int step = 0); // Constructor - void notify(unsigned int step); // Notification called by the Stepper - unsigned int getTriggerStep(); // Getter for triggerStep + Event(unsigned int step = 0); + void action(Actor & actor, unsigned int step); // Trigger event action on an actor with a given step protected: - virtual void action() = 0; // Action called by notify() - - private: - unsigned int triggerStep; // Store the trigger step value + virtual void filteredAction(Actor & actor) = 0; // Filtered action is called only if step == triggerStep + // This method is protected so that it can be called + // from abstract inherited classes + protected: + unsigned int triggerStep; // This property is protected so that it can be called + // from abstract inherited classes }; -#endif /* defined(__alobe__event__) */ +#endif // __ALOBE__EVENT__ diff --git a/alobe/main.cpp b/alobe/main.cpp index 286e3db..9348aea 100644 --- a/alobe/main.cpp +++ b/alobe/main.cpp @@ -1,4 +1,13 @@ +#include "simulation.h" +#include "stepper.h" +#include "actor.h" + +using namespace std; + int main() { + unique_ptr simulation = make_unique(make_unique()); + + simulation->toStep(10); return 0; } diff --git a/alobe/periodicEvent.cpp b/alobe/periodicEvent.cpp index bcb4235..63f0ffd 100644 --- a/alobe/periodicEvent.cpp +++ b/alobe/periodicEvent.cpp @@ -10,20 +10,11 @@ PeriodicEvent::PeriodicEvent(unsigned int step, unsigned int period): } /** - * Notification called by the Stepper + * Change event filter rules (add periodicity) */ -void PeriodicEvent::notify(unsigned int step) +void PeriodicEvent::action(Actor & actor, unsigned int step) { - if (step >= this->getTriggerStep() and (step - this->getTriggerStep()) % this->getTriggerPeriod() == 0) - { - this->action(); + if (step >= triggerStep & (step - triggerStep) % triggerPeriod == 0) { + this->filteredAction(actor); } } - -/** - * Getter for triggerPeriod - */ -unsigned int PeriodicEvent::getTriggerPeriod() -{ - return triggerPeriod; -} diff --git a/alobe/periodicEvent.h b/alobe/periodicEvent.h index b0af714..dc5b869 100644 --- a/alobe/periodicEvent.h +++ b/alobe/periodicEvent.h @@ -1,23 +1,24 @@ -#ifndef __alobe__periodicEvent__ -#define __alobe__periodicEvent__ +#ifndef __ALOBE__PERIODIC_EVENT__ +#define __ALOBE__PERIODIC_EVENT__ #include "event.h" +//using namespace std; + /** * <> PeriodicEvent * Inherits Event * - * Starting at triggerStep, PeriodicEvent objects call their action method every triggerPeriod + * Starting at triggerStep, PeriodicEvent objects call their filteredAction method every triggerPeriod */ class PeriodicEvent: public Event { public: - PeriodicEvent(unsigned int step = 0, unsigned int period = 1); // Constructor - void notify(unsigned int step); // Notification called by the Stepper - unsigned int getTriggerPeriod(); // Getter for triggerPeriod + PeriodicEvent(unsigned int step = 0, unsigned int period = 1); + void action(Actor & actor, unsigned int step); // Change event filter rules (add periodicity) private: - unsigned int triggerPeriod; // Store the trigger step value + unsigned int triggerPeriod; }; -#endif /* defined(__alobe__periodicEvent__) */ +#endif // __ALOBE__PERIODIC_EVENT__ diff --git a/alobe/simulation.cpp b/alobe/simulation.cpp new file mode 100644 index 0000000..bd08bd2 --- /dev/null +++ b/alobe/simulation.cpp @@ -0,0 +1,45 @@ +#include "simulation.h" + +/** + * Constructor + */ +Simulation::Simulation(unique_ptr stepper): + _stepper(move(stepper)), + _actors(vector >()) +{ +} + +/** + * Add an actor + */ +void Simulation::add(shared_ptr actor) +{ + _actors.push_back(actor); +} + +/** + * Calculate simulation steps until reaching 'step' + */ +void Simulation::toStep(unsigned int step) +{ + while (_stepper->getStep() < step) { + nextStep(); + } +} + +/** + * Calculate the simulation next step + */ +void Simulation::nextStep() +{ + _stepper->increment(); + nextStepCallback(); +} + +/** + * Called at the end of the nextStep method + */ +void Simulation::nextStepCallback() +{ + std::cout << "Step: "<< _stepper->getStep() << std::endl; +} diff --git a/alobe/simulation.h b/alobe/simulation.h new file mode 100644 index 0000000..dac092e --- /dev/null +++ b/alobe/simulation.h @@ -0,0 +1,32 @@ +#ifndef __ALOBE__SIMULATION__ +#define __ALOBE__SIMULATION__ + +#include + +#include "stepper.h" +#include "actor.h" + +using namespace std; + +/** + * Simulation + * + * Controller for the simulation + */ +class Simulation +{ + public: + Simulation(unique_ptr stepper); + void add(shared_ptr actor); // Add an actor + void toStep(unsigned int step); // Calculate simulation steps until reaching 'step' + void nextStep(); // Calculate the simulation next step + + private: + void nextStepCallback(); // Called at the end of the nextStep method + + private: + unique_ptr _stepper; + vector > _actors; +}; + +#endif // __ALOBE__SIMULATION__ diff --git a/alobe/stepper.cpp b/alobe/stepper.cpp index 9899076..962834f 100644 --- a/alobe/stepper.cpp +++ b/alobe/stepper.cpp @@ -4,8 +4,8 @@ * Constructor */ Stepper::Stepper(): - step(0), - eventsByWeight(multimap()) + _step(0), + _actors(vector()) { } @@ -14,15 +14,14 @@ Stepper::Stepper(): */ void Stepper::increment() { - step += 1; + _step += 1; for ( - multimap::iterator weightAndEventIterator = eventsByWeight.begin(); - weightAndEventIterator != eventsByWeight.end(); - ++weightAndEventIterator - ) - { - weightAndEventIterator->second->notify(this->getStep()); + vector::iterator actorIterator = _actors.begin(); + actorIterator != _actors.end(); + ++actorIterator + ) { + (*actorIterator)->notify(_step); } } @@ -31,7 +30,7 @@ void Stepper::increment() */ void Stepper::reset() { - step = 0; + _step = 0; } /** @@ -39,13 +38,21 @@ void Stepper::reset() */ unsigned int Stepper::getStep() { - return step; + return _step; } /** * Attach an event */ -void Stepper::attach(Event & event, int weight) +void Stepper::attach(Actor & actor) { - eventsByWeight.insert(pair(weight, &event)); + _actors.push_back(&actor); +} + +/** + * Detach an event + */ +void Stepper::detach(Actor & actor) +{ + _actors.erase(remove(_actors.begin(), _actors.end(), &actor), _actors.end()); } diff --git a/alobe/stepper.h b/alobe/stepper.h index 3528b6d..46c9f30 100644 --- a/alobe/stepper.h +++ b/alobe/stepper.h @@ -1,31 +1,30 @@ -#ifndef __alobe__stepper__ -#define __alobe__stepper__ +#ifndef __ALOBE__STEPPER__ +#define __ALOBE__STEPPER__ -#include +#include -#include "event.h" +#include "actor.h" using namespace std; /** * Stepper * - * A stepper will trigger its observers (Event objects) after each step. - * When attaching an Event, a weight can be specified (default: 1). - * Events with a bigger weight are triggered before. + * A stepper will trigger its observers (Actor objects) after each step. */ class Stepper { public: - Stepper(); // Constructor - void increment(); // Increment the stepper value and notify the attached events - void reset(); // Reset the stepper value - unsigned int getStep(); // Get the current step - void attach(Event & event, int weight = 1); // Attach an event, and give it a weight + Stepper(); + void increment(); // Increment the stepper value and notify the attached actors + void reset(); // Reset the stepper value + unsigned int getStep(); // Get the current step + void attach(Actor & actor); // Attach an actor + void detach(Actor & actor); // Detach an actor private: - unsigned int step; // Store the stepper value - multimap eventsByWeight; // Store attached events and their associated weight + unsigned int _step; + vector _actors; }; -#endif /* defined(__alobe__stepper__) */ +#endif // __ALOBE__STEPPER__