Game of Ur 0.3.3
This is a computer adaptation of Game of Ur, written in C++ mainly using SDL and OpenGL.
Loading...
Searching...
No Matches
signals.hpp
Go to the documentation of this file.
1
11
17
18#ifndef FOOLSENGINE_SIGNALS_H
19#define FOOLSENGINE_SIGNALS_H
20
21#include <memory>
22#include <cassert>
23#include <functional>
24#include <string>
25#include <map>
26#include <set>
27
28namespace ToyMaker {
29 class SignalTracker;
30 class ISignalObserver;
31 class ISignal;
32 template <typename ...TArgs>
33 class SignalObserver_;
34 template <typename ...TArgs>
35 class Signal_;
36 template <typename ...TArgs>
37 class SignalObserver;
38 template <typename ...TArgs>
39 class Signal;
40
42
48 class ISignal {
49 public:
55 virtual void registerObserver(std::weak_ptr<ISignalObserver> observer)=0;
56 };
57
64 template <typename ...TArgs>
65 class Signal_: public ISignal {
66 public:
72 void emit (TArgs... args);
73
79 void registerObserver(std::weak_ptr<ISignalObserver> observer) override;
80
81 private:
88 Signal_() = default;
89
94 std::set<
95 std::weak_ptr<SignalObserver_<TArgs...>>,
96 std::owner_less<std::weak_ptr<SignalObserver_<TArgs...>>>
98
99 friend class SignalTracker;
100 friend class Signal<TArgs...>;
101 };
102
111 template <typename ...TArgs>
113 public:
119 void operator() (TArgs... args);
120 private:
126 SignalObserver_(std::function<void(TArgs...)> callback);
127
132 std::function<void(TArgs...)> mStoredFunction {};
133 friend class SignalTracker;
134 friend class SignalObserver<TArgs...>;
135 };
136
162 public:
168
174 SignalTracker(const SignalTracker& other);
175
183
190
199
207 void connect(const std::string& theirSignal, const std::string& ourObserver, SignalTracker& other);
208
209 private:
210
221 template <typename ...TArgs>
222 std::shared_ptr<Signal_<TArgs...>> declareSignal(
223 const std::string& signalName
224 );
225
234 template <typename ...TArgs>
235 std::shared_ptr<SignalObserver_<TArgs...>> declareSignalObserver(
236 const std::string& observerName,
237 std::function<void(TArgs...)> callbackFunction
238 );
239
244 void garbageCollection();
245
250 std::unordered_map<std::string, std::weak_ptr<ISignalObserver>> mObservers {};
251
256 std::unordered_map<std::string, std::weak_ptr<ISignal>> mSignals {};
257 friend class ISignal;
258 friend class IObserver;
259
260 template <typename ...TArgs>
261 friend class SignalObserver;
262
263 template <typename ...TArgs>
264 friend class Signal;
265 };
266
322 template <typename ...TArgs>
323 class Signal {
324 public:
331 Signal(SignalTracker& owningTracker, const std::string& name);
332
333 Signal(const Signal& other) = delete;
334 Signal(Signal&& other) = delete;
335 Signal& operator=(const Signal& other) = delete;
336 Signal& operator=(Signal&& other) = delete;
337
343 void emit(TArgs...args);
344
356 void resetSignal(SignalTracker& owningTracker, const std::string& name);
357
358 private:
365
370 std::shared_ptr<Signal_<TArgs...>> mSignal_;
371
372 friend class SignalObserver<TArgs...>;
373 };
374
375
411 template <typename ...TArgs>
413 public:
421 SignalObserver(SignalTracker& owningTracker, const std::string& name, std::function<void(TArgs...)> callback);
422
423 SignalObserver(const SignalObserver& other)=delete;
424 SignalObserver(SignalObserver&& other)=delete;
425 SignalObserver& operator=(const SignalObserver& other) = delete;
426 SignalObserver& operator=(SignalObserver&& other) = delete;
427
440 void resetObserver(SignalTracker& owningTracker, const std::string& name, std::function<void(TArgs...)> callback);
441
448
449 private:
450
455 std::shared_ptr<SignalObserver_<TArgs...>> mSignalObserver_;
456
457 friend class Signal<TArgs...>;
458 };
459
460 template <typename ...TArgs>
461 inline void Signal_<TArgs...>::registerObserver(std::weak_ptr<ISignalObserver> observer) {
462 assert(!observer.expired() && "Cannot register a null pointer as an observer");
463 mObservers.insert(std::static_pointer_cast<SignalObserver_<TArgs...>>(observer.lock()));
464 }
465 template <typename ...TArgs>
466 void Signal_<TArgs...>::emit (TArgs ... args) {
467 //observers that will be removed from the list after this signal has been emitted
468 std::vector<std::weak_ptr<SignalObserver_<TArgs...>>> expiredObservers {};
469
470 for(auto observer: mObservers) {
471 // lock means that this observer is still active
472 if(std::shared_ptr<SignalObserver_<TArgs...>> activeObserver = observer.lock()) {
473 (*activeObserver)(args...);
474
475 // go to the purge list
476 } else {
477 expiredObservers.push_back(observer);
478 }
479 }
480
481 // remove dead observers
482 for(auto expiredObserver: expiredObservers) {
483 mObservers.erase(expiredObserver);
484 }
485 }
486
487 template <typename ...TArgs>
488 inline SignalObserver_<TArgs...>::SignalObserver_(std::function<void(TArgs...)> callback):
489 mStoredFunction{ callback }
490 {}
491 template <typename ...TArgs>
492 inline void SignalObserver_<TArgs...>::operator() (TArgs ... args) {
493 mStoredFunction(args...);
494 }
495
496 template <typename ...TArgs>
497 inline std::shared_ptr<Signal_<TArgs...>> SignalTracker::declareSignal(const std::string& name) {
498 std::shared_ptr<ISignal> newSignal { new Signal_<TArgs...>{} };
499 mSignals.insert({name, newSignal});
501 return std::static_pointer_cast<Signal_<TArgs...>>(newSignal);
502 }
503 template <typename ...TArgs>
504 inline std::shared_ptr<SignalObserver_<TArgs...>> SignalTracker::declareSignalObserver(const std::string& name, std::function<void(TArgs...)> callback) {
505 std::shared_ptr<ISignalObserver> newObserver { new SignalObserver_<TArgs...>{callback} };
506 mObservers.insert({name, newObserver});
508 return std::static_pointer_cast<SignalObserver_<TArgs...>>(newObserver);
509 }
510 template <typename ...TArgs>
511 Signal<TArgs...>::Signal(SignalTracker& owningTracker, const std::string& name) {
512 resetSignal(owningTracker, name);
513 }
514 template <typename ...TArgs>
515 void Signal<TArgs...>::emit(TArgs...args) {
516 mSignal_->emit(args...);
517 }
518 template <typename ...TArgs>
519 void Signal<TArgs...>::resetSignal(SignalTracker& owningTracker, const std::string& name) {
520 mSignal_ = owningTracker.declareSignal<TArgs...>(name);
521 }
522 template <typename ...TArgs>
524 mSignal_->registerObserver(observer.mSignalObserver_);
525 }
526
527 template <typename ...TArgs>
528 SignalObserver<TArgs...>::SignalObserver(SignalTracker& owningTracker, const std::string& name, std::function<void(TArgs...)> callback) {
529 resetObserver(owningTracker, name, callback);
530 };
531 template <typename ...TArgs>
532 void SignalObserver<TArgs...>::resetObserver(SignalTracker& owningTracker, const std::string& name, std::function<void(TArgs...)> callback) {
533 assert(callback && "Empty callback is not allowed");
534 mSignalObserver_ = owningTracker.declareSignalObserver<TArgs...>(name, callback);
535 }
536 template <typename ...TArgs>
540}
541
542#endif
Definition signals.hpp:41
The base class for any signal that an object advertises.
Definition signals.hpp:48
virtual void registerObserver(std::weak_ptr< ISignalObserver > observer)=0
A method used by observers to declare their interest in this signal.
A class containing most of the implementation for this engine's SignalObserver concept.
Definition signals.hpp:112
std::function< void(TArgs...)> mStoredFunction
A reference to the function stored by this observer.
Definition signals.hpp:132
SignalObserver_(std::function< void(TArgs...)> callback)
Constructs a new Signal Observer_ object.
Definition signals.hpp:488
void operator()(TArgs... args)
The function called by a Signal this oberver is subscribed to.
Definition signals.hpp:492
A SignalObserver object, which can subscribe to Signals matching its data signature and receive signa...
Definition signals.hpp:412
std::shared_ptr< SignalObserver_< TArgs... > > mSignalObserver_
The underlying implementation of the observer template.
Definition signals.hpp:455
SignalObserver(SignalTracker &owningTracker, const std::string &name, std::function< void(TArgs...)> callback)
Creates a new SignalObserver object.
Definition signals.hpp:528
void resetObserver(SignalTracker &owningTracker, const std::string &name, std::function< void(TArgs...)> callback)
Reinitializes this observer with a new SignalTracker.
Definition signals.hpp:532
void connectTo(Signal< TArgs... > &signal)
Subscribes this SignalObserver to a Signal whose signature matches its own.
Definition signals.hpp:537
A signal tracker, the main interface between an object and the signal system.
Definition signals.hpp:161
void connect(const std::string &theirSignal, const std::string &ourObserver, SignalTracker &other)
Method that connects one of this objects SignalObservers to another tracker's Signal.
Definition signals.cpp:28
std::unordered_map< std::string, std::weak_ptr< ISignalObserver > > mObservers
A list of weak references to this object's SignalObservers, along with their names.
Definition signals.hpp:250
std::shared_ptr< SignalObserver_< TArgs... > > declareSignalObserver(const std::string &observerName, std::function< void(TArgs...)> callbackFunction)
Declares a SignalObserver owned by this tracker, returns a reference to it.
Definition signals.hpp:504
std::unordered_map< std::string, std::weak_ptr< ISignal > > mSignals
A list of weak references to this object's Signals, along with their names.
Definition signals.hpp:256
std::shared_ptr< Signal_< TArgs... > > declareSignal(const std::string &signalName)
Declares a Signal owned by this tracker, and returns a reference to it.
Definition signals.hpp:497
void garbageCollection()
A method which removes any signals and observers sitting on this object which were destroyed at some ...
Definition signals.cpp:44
SignalTracker & operator=(const SignalTracker &other)
Copy assignment operator.
Definition signals.cpp:13
SignalTracker()
Constructs a new SignalTracker object.
A class containing most of the implementation of this engine's Signal concept.
Definition signals.hpp:65
void registerObserver(std::weak_ptr< ISignalObserver > observer) override
Causes an eligible observer to be subscribed to this signal.
Definition signals.hpp:461
void emit(TArgs... args)
Method via which the owner of the signal can send data to the signal's obervers.
Definition signals.hpp:466
Signal_()=default
Constructs a new Signal_ object.
std::set< std::weak_ptr< SignalObserver_< TArgs... > >, std::owner_less< std::weak_ptr< SignalObserver_< TArgs... > > > > mObservers
Weak references to all the observers that have registered themselves with this Signal.
Definition signals.hpp:97
A Signal object, designed to emit signals matching some data signature to be received by all the Sign...
Definition signals.hpp:323
void resetSignal(SignalTracker &owningTracker, const std::string &name)
Reinitializes the tracker with a new owning SignalTracker.
Definition signals.hpp:519
std::shared_ptr< Signal_< TArgs... > > mSignal_
The actual object connected with this Signal's signal tracker, hidden from users of Signal.
Definition signals.hpp:370
void registerObserver(SignalObserver< TArgs... > &observer)
Registers a compatible SignalObserver as a subscriber of this Signal.
Definition signals.hpp:523
void emit(TArgs...args)
A method on the signal which causes the signal to be sent to all of its subscribers (aka SignalObserv...
Definition signals.hpp:515
Signal(SignalTracker &owningTracker, const std::string &name)
Constructs a Signal object and associates it with its SignalTracker.
Definition signals.hpp:511
Namespace containing all class definitions and functions related to the ToyMaker engine.
Definition camera_system.hpp:20