summaryrefslogtreecommitdiffstats
path: root/engine/include/core/signal.hpp
diff options
context:
space:
mode:
authorNao Pross <naopross@thearcway.org>2019-02-03 13:36:31 +0100
committerNao Pross <naopross@thearcway.org>2019-02-03 13:36:31 +0100
commit94031d2f1718b29706a00292c2af021adde012f0 (patch)
tree767a2e26da13450ac50f5d809b28975340ba1c47 /engine/include/core/signal.hpp
parentUpdate signal_test to analyze object copying to transport signals (diff)
downloadflatland-94031d2f1718b29706a00292c2af021adde012f0.tar.gz
flatland-94031d2f1718b29706a00292c2af021adde012f0.zip
Improve signal obj forwarding with move semantics (and performance)
Diffstat (limited to 'engine/include/core/signal.hpp')
-rw-r--r--engine/include/core/signal.hpp45
1 files changed, 25 insertions, 20 deletions
diff --git a/engine/include/core/signal.hpp b/engine/include/core/signal.hpp
index f06a193..6026ce5 100644
--- a/engine/include/core/signal.hpp
+++ b/engine/include/core/signal.hpp
@@ -31,8 +31,8 @@ namespace flat::core
class signal : public prioritized
{
public:
- /// copyable
- signal(const signal& other) = default;
+ /// non copyable
+ signal(const signal& other) = delete;
/// movable
signal(signal&& other) = default;
@@ -42,7 +42,7 @@ namespace flat::core
/// not default constructible
signal() = delete;
- /// normal constructor
+ /// normal constructor, allowed only by core::signal
signal(priority_t p = priority_t::none) : prioritized(p) {}
};
}
@@ -63,18 +63,18 @@ namespace flat::core
// is not the signature of the listener (so not yet)
signal() = delete;
- /// copyable
- signal(const signal& other) = default;
+ /// non copyable, copying signal<...>::args is inefficient
+ signal(const signal& other) = delete;
/// movable
signal(signal&& other) = default;
- /// normal constructor that copies arguments
+ /// normal (inefficient) constructor that copies arguments
constexpr signal(const Args&... _args)
: helper::signal(priority_t::none), args(_args...) {}
- constexpr signal(priority_t p, const Args&... _args)
- : helper::signal(p), args(_args...) {}
+ // constexpr signal(priority_t p, const Args&... _args)
+ // : helper::signal(p), args(_args...) {}
/// normal constructor that forwards arguments
/// this optimizes rvalue initializations
@@ -83,10 +83,10 @@ namespace flat::core
args(std::forward<Args>(_args)...)
{}
- constexpr signal(priority_t p, Args&&... _args)
- : helper::signal(p),
- args(std::forward<Args>(_args)...)
- {}
+ // constexpr signal(priority_t p, Args&&... _args)
+ // : helper::signal(p),
+ // args(std::forward<Args>(_args)...)
+ // {}
};
@@ -155,7 +155,7 @@ namespace flat::core
}
npdebug("invoked listener ", this, " with signal ", p);
- std::apply(m_callback, p->args);
+ std::apply(m_callback, (p->args));
return true;
}
@@ -187,8 +187,9 @@ namespace flat::core
template<typename R, typename ...Args>
std::shared_ptr<listener<Args...>> _connect(std::function<R(Args...)>&& f)
{
+ // construct a listener by forwarding f to listener's constructor
auto lis_ptr = std::make_shared<listener<Args...>>(
- listener<Args...>(f)
+ listener<Args...>(std::forward<decltype(f)>(f))
);
// insert pointer
@@ -219,10 +220,12 @@ 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(signal<Args...>&& sig)
{
// create a shared_ptr
- auto p = std::make_shared<signal<Args...>>(sig)
+ auto p = std::make_shared<signal<Args...>>(
+ std::forward<signal<Args...>>(sig)
+ );
npdebug("emitted signal ", p);
@@ -248,8 +251,9 @@ namespace flat::core
std::shared_ptr<listener<Args...>> connect(R (*f)(Args...))
{
return _connect(static_cast<std::function<R(Args...)>>(
- [f](Args ...args) constexpr -> R {
- return f((args)...);
+ // closure that forwards ...args to f
+ [f](Args&& ...args) constexpr -> R {
+ return f(std::forward<Args>(args)...);
})
);
}
@@ -259,8 +263,9 @@ namespace flat::core
std::shared_ptr<listener<Args...>> connect(R (T::*mf)(Args ...args), T* obj)
{
return _connect(static_cast<std::function<R(Args...)>>(
- [mf, obj](Args ...args) constexpr -> R {
- return (obj->*mf)((args)...);
+ // closure that forwards ...args to mf called on obj
+ [mf, obj](Args&& ...args) constexpr -> R {
+ return (obj->*mf)(std::forward<Args>(args)...);
})
);
}