|
@@ -20,14 +20,23 @@ namespace entt {
|
|
|
namespace internal {
|
|
namespace internal {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+template<typename>
|
|
|
|
|
+struct sigh_traits;
|
|
|
|
|
+
|
|
|
|
|
+template<typename Ret, typename... Args>
|
|
|
|
|
+struct sigh_traits<Ret(Args...)> {
|
|
|
|
|
+ using proto_fn_type = Ret(void *, Args...);
|
|
|
|
|
+ using call_type = std::pair<void *, proto_fn_type *>;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
template<typename, typename>
|
|
template<typename, typename>
|
|
|
struct Invoker;
|
|
struct Invoker;
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename Ret, typename... Args, typename Collector>
|
|
template<typename Ret, typename... Args, typename Collector>
|
|
|
struct Invoker<Ret(Args...), Collector> {
|
|
struct Invoker<Ret(Args...), Collector> {
|
|
|
- using proto_fn_type = Ret(void *, Args...);
|
|
|
|
|
- using call_type = std::pair<void *, proto_fn_type *>;
|
|
|
|
|
|
|
+ using proto_fn_type = typename sigh_traits<Ret(Args...)>::proto_fn_type;
|
|
|
|
|
|
|
|
virtual ~Invoker() = default;
|
|
virtual ~Invoker() = default;
|
|
|
|
|
|
|
@@ -39,8 +48,7 @@ struct Invoker<Ret(Args...), Collector> {
|
|
|
|
|
|
|
|
template<typename... Args, typename Collector>
|
|
template<typename... Args, typename Collector>
|
|
|
struct Invoker<void(Args...), Collector> {
|
|
struct Invoker<void(Args...), Collector> {
|
|
|
- using proto_fn_type = void(void *, Args...);
|
|
|
|
|
- using call_type = std::pair<void *, proto_fn_type *>;
|
|
|
|
|
|
|
+ using proto_fn_type = typename sigh_traits<void(Args...)>::proto_fn_type;
|
|
|
|
|
|
|
|
virtual ~Invoker() = default;
|
|
virtual ~Invoker() = default;
|
|
|
|
|
|
|
@@ -132,14 +140,18 @@ class Sink<Ret(Args...)> final {
|
|
|
template<typename, typename>
|
|
template<typename, typename>
|
|
|
friend class SigH;
|
|
friend class SigH;
|
|
|
|
|
|
|
|
- using proto_fn_type = Ret(void *, Args...);
|
|
|
|
|
- using call_type = std::pair<void *, proto_fn_type *>;
|
|
|
|
|
|
|
+ using call_type = typename internal::sigh_traits<Ret(Args...)>::call_type;
|
|
|
|
|
|
|
|
template<Ret(*Function)(Args...)>
|
|
template<Ret(*Function)(Args...)>
|
|
|
static Ret proto(void *, Args... args) {
|
|
static Ret proto(void *, Args... args) {
|
|
|
return (Function)(args...);
|
|
return (Function)(args...);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ template<typename Class, Ret(Class:: *Member)(Args... args) const>
|
|
|
|
|
+ static Ret proto(void *instance, Args... args) {
|
|
|
|
|
+ return (static_cast<const Class *>(instance)->*Member)(args...);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
template<typename Class, Ret(Class:: *Member)(Args... args)>
|
|
template<typename Class, Ret(Class:: *Member)(Args... args)>
|
|
|
static Ret proto(void *instance, Args... args) {
|
|
static Ret proto(void *instance, Args... args) {
|
|
|
return (static_cast<Class *>(instance)->*Member)(args...);
|
|
return (static_cast<Class *>(instance)->*Member)(args...);
|
|
@@ -164,6 +176,25 @@ public:
|
|
|
calls.emplace_back(nullptr, &proto<Function>);
|
|
calls.emplace_back(nullptr, &proto<Function>);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @brief Connects a member function for a given instance to a signal.
|
|
|
|
|
+ *
|
|
|
|
|
+ * The signal isn't responsible for the connected object. Users must
|
|
|
|
|
+ * guarantee that the lifetime of the instance overcomes the one of the
|
|
|
|
|
+ * signal. On the other side, the signal handler performs checks to
|
|
|
|
|
+ * avoid multiple connections for the same member function of a given
|
|
|
|
|
+ * instance.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @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`.
|
|
|
|
|
+ */
|
|
|
|
|
+ template <typename Class, Ret(Class:: *Member)(Args...) const = &Class::receive>
|
|
|
|
|
+ void connect(Class *instance) {
|
|
|
|
|
+ disconnect<Class, Member>(instance);
|
|
|
|
|
+ calls.emplace_back(instance, &proto<Class, Member>);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* @brief Connects a member function for a given instance to a signal.
|
|
* @brief Connects a member function for a given instance to a signal.
|
|
|
*
|
|
*
|
|
@@ -193,6 +224,18 @@ public:
|
|
|
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 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`.
|
|
|
|
|
+ */
|
|
|
|
|
+ template<typename Class, Ret(Class:: *Member)(Args...) const>
|
|
|
|
|
+ void disconnect(Class *instance) {
|
|
|
|
|
+ call_type target{instance, &proto<Class, Member>};
|
|
|
|
|
+ calls.erase(std::remove(calls.begin(), calls.end(), std::move(target)), calls.end());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* @brief Disconnects the given member function from a signal.
|
|
* @brief Disconnects the given member function from a signal.
|
|
|
* @tparam Class Type of class to which the member function belongs.
|
|
* @tparam Class Type of class to which the member function belongs.
|
|
@@ -253,7 +296,7 @@ private:
|
|
|
*/
|
|
*/
|
|
|
template<typename Ret, typename... Args, typename Collector>
|
|
template<typename Ret, typename... Args, typename Collector>
|
|
|
class SigH<Ret(Args...), Collector> final: private internal::Invoker<Ret(Args...), Collector> {
|
|
class SigH<Ret(Args...), Collector> final: private internal::Invoker<Ret(Args...), Collector> {
|
|
|
- using call_type = typename internal::Invoker<Ret(Args...), Collector>::call_type;
|
|
|
|
|
|
|
+ using call_type = typename internal::sigh_traits<Ret(Args...)>::call_type;
|
|
|
|
|
|
|
|
public:
|
|
public:
|
|
|
/*! @brief Unsigned integer type. */
|
|
/*! @brief Unsigned integer type. */
|