diff options
author | Nao Pross <naopross@thearcway.org> | 2019-02-02 22:49:46 +0100 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2019-02-02 22:49:46 +0100 |
commit | 02acb58b46192660b9a1ba337c037770801e847e (patch) | |
tree | 2a6e63da483498d63aaeab1e0b62b86daee002e8 /engine/include/core/signal.hpp | |
parent | Fix all template errors, it compiles! (but doesn't work yet) (diff) | |
download | flatland-02acb58b46192660b9a1ba337c037770801e847e.tar.gz flatland-02acb58b46192660b9a1ba337c037770801e847e.zip |
Finish signal, it compiles signal_test and works(!!)
But the whole library doesn't compile yet
Diffstat (limited to 'engine/include/core/signal.hpp')
-rw-r--r-- | engine/include/core/signal.hpp | 99 |
1 files changed, 61 insertions, 38 deletions
diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp index 7b5ac3b..a820880 100644 --- a/engine/include/core/signal.hpp +++ b/engine/include/core/signal.hpp @@ -7,12 +7,11 @@ #include "debug.hpp" #include <map> -#include <list> #include <tuple> +#include <list> #include <functional> #include <memory> #include <cstddef> -#include <type_traits> namespace flat::core @@ -41,7 +40,7 @@ namespace flat::core /* class signal<...Args> * - * is a specialized tuple that contains function arguments (...Args) + * is a tuple wrapper that contains function arguments (...Args) * that are later used to call a callback stored in a listener. */ template <typename ...Args> @@ -49,8 +48,18 @@ namespace flat::core { const std::tuple<Args...> args; - explicit constexpr signal(Args... _args) - : args(std::move(_args)...) {} + /// copy constructor + explicit constexpr signal(const Args&... _args) + : args(_args...) {} + + /// move constructor + explicit constexpr signal(Args&&... _args) + : args(std::forward<Args>(_args)...) {} + + // TODO: if needed add copy constructor and move constructor + // not needed yet + // explicit constexpr signal(const signal<Args...>& other) + // : helper::signal(), args(other.args) {} }; @@ -62,7 +71,7 @@ namespace flat::core * pointer type. To make anything with it must be first downcasted to a * core::listener<Args...> */ - class listener + class listener : public std::enable_shared_from_this<listener> { protected: explicit listener() {} @@ -83,21 +92,31 @@ namespace flat::core { public: using callback = typename std::function<void(Args...)>; - using ptr = typename std::shared_ptr<listener<Args...>>; explicit listener(callback f) : m_callback(f) {} + + // TODO: remove + ~listener() { + npdebug("deleted listener ", this); + } // attempt to call m_callback with s as argument // m_callback is called only if the signature matches bool invoke(std::shared_ptr<const helper::signal> s) const override { + // TODO: shared dynamic pointer cast const signal<Args...> *p = dynamic_cast<const signal<Args...> *>(s.get()); - if (p != nullptr) - std::apply(m_callback, p->args); + // if dynamic cast fails + if (p == nullptr) { + npdebug("invoked listener ", this, " with non-matching signal ", s); + return false; + } + + npdebug("invoked listener ", this, " with signal ", p); + std::apply(m_callback, p->args); - // return true if p was called - return (p != nullptr); + return true; } private: @@ -119,6 +138,25 @@ namespace flat::core /// task to call std::shared_ptr<task> m_broadcast; + + /// connect a closure / lambda (this is a helper), see others below + template<typename R, typename ...Args> + std::shared_ptr<listener<Args...>> _connect(std::function<R(Args...)> f) + { + auto lis_ptr = std::make_shared<listener<Args...>>(f); + + // insert pointer + m_listeners.push_front( + // decay shared_ptr to weak_ptr + // TODO: static weak + static_cast<std::weak_ptr<helper::listener>>( + // decay listener to helper::listener + std::static_pointer_cast<helper::listener>(lis_ptr) + ) + ); + + return lis_ptr; + } public: using ptr = std::shared_ptr<channel>; @@ -128,30 +166,24 @@ namespace flat::core /// add a signal to the queue/stack of signals (m_signals) template<class ...Args> - void emit(const signal<Args...> sig) + void emit(const signal<Args...>& sig) { - // insert signal and decay it to a non-template - // unique_ptr<helper::signal> - m_signals.insert(std::make_shared<helper::signal>(sig)); - } + // create a shared_ptr + auto p = std::make_shared<signal<Args...>>(sig) - /// for each signal accumulated, call each listener - void broadcast(); + npdebug("emitted signal ", p); - /// connect a standalone function - template<typename R, typename ...Args> - std::shared_ptr<listener<Args...>> _connect(std::function<R(Args...)> f) - { - auto lis_ptr = std::make_shared<listener<Args...>>(f); - // insert listener and decay it to a non-template - // weak_ptr<helper::listener> - m_listeners.push_back( - static_cast<std::weak_ptr<helper::listener>>(lis_ptr) + // insert pointer + m_signals.insert( + // decay signal to helper::signal + std::static_pointer_cast<helper::signal>(p) ); - - return lis_ptr; } + /// for each signal accumulated, call each listener + void broadcast(); + + /// connect a function template<typename R, typename ...Args> std::shared_ptr<listener<Args...>> connect(R (*f)(Args...)) { @@ -175,12 +207,3 @@ namespace flat::core }; } - -namespace std -{ - template<typename... Args> - struct tuple_size<flat::core::signal<Args...>> - { - constexpr static std::size_t value = (0 + ... + sizeof(Args)); - }; -} |