|
@@ -71,24 +71,27 @@ using DefaultCollectorType = typename DefaultCollector<Function>::collector_type
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Signal handler.
|
|
|
|
|
|
|
+ * @brief Unmanaged signal handler declaration.
|
|
|
*
|
|
*
|
|
|
* Primary template isn't defined on purpose. All the specializations give a
|
|
* Primary template isn't defined on purpose. All the specializations give a
|
|
|
* compile-time error unless the template parameter is a function type.
|
|
* compile-time error unless the template parameter is a function type.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @tparam Function A valid function type.
|
|
|
|
|
+ * @tparam Collector Type of collector to use, if any.
|
|
|
*/
|
|
*/
|
|
|
-template<typename Function, typename = DefaultCollectorType<Function>>
|
|
|
|
|
|
|
+template<typename Function, typename Collector = DefaultCollectorType<Function>>
|
|
|
class SigH;
|
|
class SigH;
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Signal handler.
|
|
|
|
|
|
|
+ * @brief Unmanaged signal handler definition.
|
|
|
*
|
|
*
|
|
|
* Unmanaged signal handler. It works directly with naked pointers to classes
|
|
* Unmanaged signal handler. It works directly with naked pointers to classes
|
|
|
* and pointers to member functions as well as pointers to free functions. Users
|
|
* and pointers to member functions as well as pointers to free functions. Users
|
|
|
* of this class are in charge of disconnecting instances before deleting them.
|
|
* of this class are in charge of disconnecting instances before deleting them.
|
|
|
*
|
|
*
|
|
|
* This class serves mainly two purposes:
|
|
* This class serves mainly two purposes:
|
|
|
- * * Creating signals to be used later to notify a bunch of listeners.
|
|
|
|
|
|
|
+ * * Creating signals used later to notify a bunch of listeners.
|
|
|
* * Collecting results from a set of functions like in a voting system.
|
|
* * Collecting results from a set of functions like in a voting system.
|
|
|
*
|
|
*
|
|
|
* The default collector does nothing. To properly collect data, define and use
|
|
* The default collector does nothing. To properly collect data, define and use
|
|
@@ -98,8 +101,8 @@ class SigH;
|
|
|
* otherwise.
|
|
* otherwise.
|
|
|
*
|
|
*
|
|
|
* @tparam Ret Return type of a function type.
|
|
* @tparam Ret Return type of a function type.
|
|
|
- * @tparam Args Types of the arguments of a function type.
|
|
|
|
|
- * @tparam Collector The type of the collector to use if any.
|
|
|
|
|
|
|
+ * @tparam Args Types of arguments of a function type.
|
|
|
|
|
+ * @tparam Collector Type of collector to use, if any.
|
|
|
*/
|
|
*/
|
|
|
template<typename Ret, typename... Args, typename Collector>
|
|
template<typename Ret, typename... Args, typename Collector>
|
|
|
class SigH<Ret(Args...), Collector> final: private Invoker<Ret(Args...), Collector> {
|
|
class SigH<Ret(Args...), Collector> final: private Invoker<Ret(Args...), Collector> {
|
|
@@ -121,6 +124,13 @@ public:
|
|
|
/*! @brief Collector type. */
|
|
/*! @brief Collector type. */
|
|
|
using collector_type = Collector;
|
|
using collector_type = Collector;
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Instance type when it comes to connecting member functions.
|
|
|
|
|
+ * @tparam Class Type of class to which the member function belongs.
|
|
|
|
|
+ */
|
|
|
|
|
+ template<typename Class>
|
|
|
|
|
+ using instance_type = Class *;
|
|
|
|
|
+
|
|
|
/*! @brief Default constructor, explicit on purpose. */
|
|
/*! @brief Default constructor, explicit on purpose. */
|
|
|
explicit SigH() noexcept = default;
|
|
explicit SigH() noexcept = default;
|
|
|
|
|
|
|
@@ -129,7 +139,7 @@ public:
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @brief Copy constructor, listeners are also connected to this signal.
|
|
* @brief Copy constructor, listeners are also connected to this signal.
|
|
|
- * @param other A signal to be used as source to initialize this instance.
|
|
|
|
|
|
|
+ * @param other A signal to use as source to initialize this instance.
|
|
|
*/
|
|
*/
|
|
|
SigH(const SigH &other)
|
|
SigH(const SigH &other)
|
|
|
: calls{other.calls}
|
|
: calls{other.calls}
|
|
@@ -137,15 +147,18 @@ public:
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @brief Default move constructor.
|
|
* @brief Default move constructor.
|
|
|
- * @param other A signal to be used as source to initialize this instance.
|
|
|
|
|
|
|
+ * @param other A signal to use as source to initialize this instance.
|
|
|
*/
|
|
*/
|
|
|
SigH(SigH &&other): SigH{} {
|
|
SigH(SigH &&other): SigH{} {
|
|
|
swap(*this, other);
|
|
swap(*this, other);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Assignment operator, listeners are also connected to this signal.
|
|
|
|
|
- * @param other A signal to be used as source to initialize this instance.
|
|
|
|
|
|
|
+ * @brief Copy assignment operator.
|
|
|
|
|
+ *
|
|
|
|
|
+ * Listeners are also connected to this signal.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param other A signal to use as source to initialize this instance.
|
|
|
* @return This signal.
|
|
* @return This signal.
|
|
|
*/
|
|
*/
|
|
|
SigH & operator=(const SigH &other) {
|
|
SigH & operator=(const SigH &other) {
|
|
@@ -154,8 +167,8 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Default move operator.
|
|
|
|
|
- * @param other A signal to be used as source to initialize this instance.
|
|
|
|
|
|
|
+ * @brief Move assignment operator.
|
|
|
|
|
+ * @param other A signal to use as source to initialize this instance.
|
|
|
* @return This signal.
|
|
* @return This signal.
|
|
|
*/
|
|
*/
|
|
|
SigH & operator=(SigH &&other) {
|
|
SigH & operator=(SigH &&other) {
|
|
@@ -164,15 +177,15 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief The number of listeners connected to the signal.
|
|
|
|
|
- * @return The number of listeners currently connected.
|
|
|
|
|
|
|
+ * @brief Number of listeners connected to the signal.
|
|
|
|
|
+ * @return Number of listeners currently connected.
|
|
|
*/
|
|
*/
|
|
|
size_type size() const noexcept {
|
|
size_type size() const noexcept {
|
|
|
return calls.size();
|
|
return calls.size();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Returns true is at least a listener is connected to the signal.
|
|
|
|
|
|
|
+ * @brief Returns false is at least a listener is connected to the signal.
|
|
|
* @return True if the signal has no listeners connected, false otherwise.
|
|
* @return True if the signal has no listeners connected, false otherwise.
|
|
|
*/
|
|
*/
|
|
|
bool empty() const noexcept {
|
|
bool empty() const noexcept {
|
|
@@ -180,16 +193,15 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Disconnects all the listeners from the signal.
|
|
|
|
|
|
|
+ * @brief Disconnects all the listeners from a signal.
|
|
|
*/
|
|
*/
|
|
|
void clear() noexcept {
|
|
void clear() noexcept {
|
|
|
calls.clear();
|
|
calls.clear();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Connects a free function to the signal.
|
|
|
|
|
|
|
+ * @brief Connects a free function to a signal.
|
|
|
*
|
|
*
|
|
|
- * @note
|
|
|
|
|
* The signal handler performs checks to avoid multiple connections for free
|
|
* The signal handler performs checks to avoid multiple connections for free
|
|
|
* functions.
|
|
* functions.
|
|
|
*
|
|
*
|
|
@@ -202,28 +214,25 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Connects the member function for the given instance to the signal.
|
|
|
|
|
|
|
+ * @brief Connects a member function for a given instance to a signal.
|
|
|
*
|
|
*
|
|
|
* The signal isn't responsible for the connected object. Users must
|
|
* The signal isn't responsible for the connected object. Users must
|
|
|
* guarantee that the lifetime of the instance overcomes the one of the
|
|
* guarantee that the lifetime of the instance overcomes the one of the
|
|
|
- * signal.
|
|
|
|
|
|
|
+ * signal. On the other side, the signal handler performs checks to avoid
|
|
|
|
|
+ * multiple connections for the same member function of a given instance.
|
|
|
*
|
|
*
|
|
|
- * @warning
|
|
|
|
|
- * The signal handler performs checks to avoid multiple connections for the
|
|
|
|
|
- * same member function of a given instance.
|
|
|
|
|
- *
|
|
|
|
|
- * @tparam Class The type of the class to which the member function belongs.
|
|
|
|
|
- * @tparam Member The member function to connect to the signal.
|
|
|
|
|
|
|
+ * @tparam Class Type of class to which the member function belongs.
|
|
|
|
|
+ * @tparam Member Member function to connect to the signal.
|
|
|
* @param instance A valid instance of type pointer to `Class`.
|
|
* @param instance A valid instance of type pointer to `Class`.
|
|
|
*/
|
|
*/
|
|
|
template <typename Class, Ret(Class::*Member)(Args...)>
|
|
template <typename Class, Ret(Class::*Member)(Args...)>
|
|
|
- void connect(Class *instance) {
|
|
|
|
|
|
|
+ void connect(instance_type<Class> instance) {
|
|
|
disconnect<Class, Member>(instance);
|
|
disconnect<Class, Member>(instance);
|
|
|
calls.emplace_back(instance, &proto<Class, Member>);
|
|
calls.emplace_back(instance, &proto<Class, Member>);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Disconnects a free function from the signal.
|
|
|
|
|
|
|
+ * @brief Disconnects a free function from a signal.
|
|
|
* @tparam Function A valid free function pointer.
|
|
* @tparam Function A valid free function pointer.
|
|
|
*/
|
|
*/
|
|
|
template<Ret(*Function)(Args...)>
|
|
template<Ret(*Function)(Args...)>
|
|
@@ -233,30 +242,30 @@ public:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Disconnects the given member function from the signal.
|
|
|
|
|
- * @tparam Class The type of the class to which the member function belongs.
|
|
|
|
|
- * @tparam Member The member function to connect to the signal.
|
|
|
|
|
|
|
+ * @brief Disconnects the given member function from a signal.
|
|
|
|
|
+ * @tparam Class Type of class to which the member function belongs.
|
|
|
|
|
+ * @tparam Member Member function to connect to the signal.
|
|
|
* @param instance A valid instance of type pointer to `Class`.
|
|
* @param instance A valid instance of type pointer to `Class`.
|
|
|
*/
|
|
*/
|
|
|
template<typename Class, Ret(Class::*Member)(Args...)>
|
|
template<typename Class, Ret(Class::*Member)(Args...)>
|
|
|
- void disconnect(Class *instance) {
|
|
|
|
|
|
|
+ void disconnect(instance_type<Class> instance) {
|
|
|
call_type target{instance, &proto<Class, Member>};
|
|
call_type target{instance, &proto<Class, Member>};
|
|
|
calls.erase(std::remove(calls.begin(), calls.end(), std::move(target)), calls.end());
|
|
calls.erase(std::remove(calls.begin(), calls.end(), std::move(target)), calls.end());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* @brief Removes all existing connections for the given instance.
|
|
* @brief Removes all existing connections for the given instance.
|
|
|
- * @tparam Class The type of the class to which the member function belongs.
|
|
|
|
|
|
|
+ * @tparam Class Type of class to which the member function belongs.
|
|
|
* @param instance A valid instance of type pointer to `Class`.
|
|
* @param instance A valid instance of type pointer to `Class`.
|
|
|
*/
|
|
*/
|
|
|
template<typename Class>
|
|
template<typename Class>
|
|
|
- void disconnect(Class *instance) {
|
|
|
|
|
|
|
+ void disconnect(instance_type<Class> instance) {
|
|
|
auto func = [instance](const call_type &call) { return call.first == instance; };
|
|
auto func = [instance](const call_type &call) { return call.first == instance; };
|
|
|
calls.erase(std::remove_if(calls.begin(), calls.end(), std::move(func)), calls.end());
|
|
calls.erase(std::remove_if(calls.begin(), calls.end(), std::move(func)), calls.end());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * @brief Triggers the signal.
|
|
|
|
|
|
|
+ * @brief Triggers a signal.
|
|
|
*
|
|
*
|
|
|
* All the listeners are notified. Order isn't guaranteed.
|
|
* All the listeners are notified. Order isn't guaranteed.
|
|
|
*
|
|
*
|
|
@@ -305,7 +314,7 @@ public:
|
|
|
* @return True if the two signals are identical, false otherwise.
|
|
* @return True if the two signals are identical, false otherwise.
|
|
|
*/
|
|
*/
|
|
|
bool operator==(const SigH &other) const noexcept {
|
|
bool operator==(const SigH &other) const noexcept {
|
|
|
- return (calls.size() == other.calls.size()) && std::equal(calls.cbegin(), calls.cend(), other.calls.cbegin());
|
|
|
|
|
|
|
+ return std::equal(calls.cbegin(), calls.cend(), other.calls.cbegin(), other.calls.cend());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
private:
|
|
@@ -320,7 +329,7 @@ private:
|
|
|
* listeners registered exactly in the same order.
|
|
* listeners registered exactly in the same order.
|
|
|
*
|
|
*
|
|
|
* @tparam Ret Return type of a function type.
|
|
* @tparam Ret Return type of a function type.
|
|
|
- * @tparam Args Types of the arguments of a function type.
|
|
|
|
|
|
|
+ * @tparam Args Types of arguments of a function type.
|
|
|
* @param lhs A valid signal object.
|
|
* @param lhs A valid signal object.
|
|
|
* @param rhs A valid signal object.
|
|
* @param rhs A valid signal object.
|
|
|
* @return True if the two signals are different, false otherwise.
|
|
* @return True if the two signals are different, false otherwise.
|
|
@@ -331,17 +340,6 @@ bool operator!=(const SigH<Ret(Args...)> &lhs, const SigH<Ret(Args...)> &rhs) no
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * @brief Event handler.
|
|
|
|
|
- *
|
|
|
|
|
- * Unmanaged event handler. Collecting data for this kind of signals doesn't
|
|
|
|
|
- * make sense at all. Its sole purpose is to provide the listeners with the
|
|
|
|
|
- * given event.
|
|
|
|
|
- */
|
|
|
|
|
-template<typename Event>
|
|
|
|
|
-using EventH = SigH<void(const Event &)>;
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|