[DEV] can remove signal befor handle
This commit is contained in:
parent
9003745811
commit
1fcf22bf03
@ -14,15 +14,13 @@
|
||||
|
||||
namespace esignal {
|
||||
#undef __class__
|
||||
#define __class__ "Signal<T>"
|
||||
template<typename T> class Signal : public esignal::Base {
|
||||
private:
|
||||
std::vector<std::pair<std::weak_ptr<void>,
|
||||
std::function<void(const T&)>>> m_callerList; // current list of binded element
|
||||
std::vector<std::pair<std::weak_ptr<void>,
|
||||
std::function<void(const T&)>>> m_callerListInCallback; // temporaty list (when add one in call process)
|
||||
std::vector<std::function<void(const T&)>> m_callerListDirect; // current list of binded element
|
||||
std::vector<std::function<void(const T&)>> m_callerListDirectInCallback; // temporaty list (when add one in call process)
|
||||
#define __class__ "ISignal<T>"
|
||||
template<class... Args>
|
||||
class ISignal : public Signal<Args...> {
|
||||
protected:
|
||||
esignal::Interface& m_signalInterfaceLink;
|
||||
std::string m_name;
|
||||
std::string m_description;
|
||||
public:
|
||||
/**
|
||||
* @brief Create a signal with a specific type.
|
||||
@ -31,10 +29,10 @@ namespace esignal {
|
||||
* @param[in] _description Description of the signal.
|
||||
* @param[in] _periodic Customisation of the log display tag at true to down debug lebel at verbose.
|
||||
*/
|
||||
Signal(esignal::Interface& _signalInterfaceLink,
|
||||
const std::string& _name,
|
||||
const std::string& _description = "",
|
||||
bool _periodic = false);
|
||||
ISignal(esignal::Interface& _signalInterfaceLink,
|
||||
const std::string& _name,
|
||||
const std::string& _description = "",
|
||||
bool _periodic = false);
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
|
430
esignal/Signal.h
430
esignal/Signal.h
@ -14,27 +14,172 @@
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <mutex>
|
||||
|
||||
namespace esignal {
|
||||
extern size_t s_uid;
|
||||
|
||||
template<class TYPE>
|
||||
class RefCount {
|
||||
public:
|
||||
std::mutex m_lock;
|
||||
int64_t m_count;
|
||||
TYPE* m_data;
|
||||
public:
|
||||
RefCount(TYPE* _data) :
|
||||
m_count(0),
|
||||
m_data(_data) {
|
||||
// nothing to do.
|
||||
}
|
||||
// copy constructor:
|
||||
RefCount(const RefCount&) = delete;
|
||||
// copy operator:
|
||||
RefCount& operator=(RefCount) = delete;
|
||||
RefCount& operator=(const RefCount& _obj) = delete;
|
||||
// Move constructor
|
||||
RefCount(RefCount&& _obj) = delete;
|
||||
// Move operator
|
||||
RefCount& operator=(RefCount&& _obj) = delete;
|
||||
public:
|
||||
~RefCount() {
|
||||
m_data = nullptr;
|
||||
}
|
||||
public:
|
||||
void lock() {
|
||||
m_lock.lock();
|
||||
}
|
||||
void unlock() {
|
||||
m_lock.unlock();
|
||||
}
|
||||
void inc() {
|
||||
lock();
|
||||
m_count++;
|
||||
unlock();
|
||||
}
|
||||
int64_t dec() {
|
||||
int64_t val;
|
||||
lock();
|
||||
m_count--;
|
||||
val = m_count;
|
||||
unlock();
|
||||
return val;
|
||||
}
|
||||
int64_t getCount() const {
|
||||
return m_count;
|
||||
}
|
||||
void remove() {
|
||||
lock();
|
||||
m_data = nullptr;
|
||||
unlock();
|
||||
}
|
||||
TYPE* get() {
|
||||
return m_data;
|
||||
}
|
||||
};
|
||||
template<class TYPE>
|
||||
class lockSharedPtrRef {
|
||||
public:
|
||||
RefCount<TYPE>* m_counter;
|
||||
public:
|
||||
lockSharedPtrRef(TYPE* _pointer) :
|
||||
m_counter(nullptr) {
|
||||
if (_pointer != nullptr) {
|
||||
m_counter = new RefCount<TYPE>(_pointer);
|
||||
m_counter->inc();
|
||||
}
|
||||
}
|
||||
// copy constructor:
|
||||
lockSharedPtrRef(const lockSharedPtrRef& _obj) :
|
||||
m_counter(_obj.m_counter) {
|
||||
if (m_counter == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_counter->inc();
|
||||
}
|
||||
// copy operator:
|
||||
lockSharedPtrRef& operator=(lockSharedPtrRef) = delete;
|
||||
lockSharedPtrRef& operator=(const lockSharedPtrRef& _obj) {
|
||||
if (&_obj == this) {
|
||||
return *this;
|
||||
}
|
||||
if (m_counter != nullptr) {
|
||||
m_counter->dec();
|
||||
m_counter = nullptr;
|
||||
}
|
||||
m_counter = _obj.m_counter;
|
||||
if (m_counter == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_counter->inc();
|
||||
return *this;
|
||||
}
|
||||
// Move constructor
|
||||
lockSharedPtrRef(lockSharedPtrRef&& _obj) :
|
||||
m_counter(std::move(_obj.m_counter)) {
|
||||
|
||||
}
|
||||
// Move operator
|
||||
lockSharedPtrRef& operator=(lockSharedPtrRef&& _obj) {
|
||||
m_counter = std::move(_obj.m_counter);
|
||||
}
|
||||
~lockSharedPtrRef() {
|
||||
int64_t count = m_counter->dec();
|
||||
if (count > 0) {
|
||||
return;
|
||||
}
|
||||
delete m_counter;
|
||||
m_counter = nullptr;
|
||||
}
|
||||
void removeData() {
|
||||
if (m_counter != nullptr) {
|
||||
m_counter->remove();
|
||||
}
|
||||
}
|
||||
void disconnect(std::size_t _uid) {
|
||||
if (m_counter == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_counter->lock();
|
||||
TYPE* val = m_counter->get();
|
||||
if (val != nullptr) {
|
||||
val->disconnect(_uid);
|
||||
}
|
||||
m_counter->unlock();
|
||||
}
|
||||
};
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "Signal<T>"
|
||||
class SignalInderection;
|
||||
class SignalBase {
|
||||
protected:
|
||||
lockSharedPtrRef<SignalBase> m_shared;
|
||||
public:
|
||||
SignalBase() {
|
||||
SignalBase() :
|
||||
m_shared(this) {
|
||||
|
||||
}
|
||||
// copy constructor:
|
||||
SignalBase(const SignalBase&) = delete;
|
||||
// copy operator:
|
||||
//SignalBase& operator=(SignalBase) = delete;
|
||||
//SignalBase& operator=(const SignalBase& _obj) = delete;
|
||||
// Move constructor
|
||||
SignalBase(SignalBase&& _obj) = delete;
|
||||
// Move operator
|
||||
//SignalBase& operator=(SignalBase&& _obj) = delete;
|
||||
|
||||
virtual ~SignalBase() {
|
||||
|
||||
m_shared.removeData();
|
||||
}
|
||||
virtual void disconnect(std::size_t _uid) = 0;
|
||||
};
|
||||
|
||||
|
||||
class Connection {
|
||||
public:
|
||||
Connection(SignalBase* _sig, std::size_t _id):
|
||||
m_signal(_sig), m_uid(_id) {
|
||||
Connection(lockSharedPtrRef<SignalBase> _ref, std::size_t _id):
|
||||
m_signalRefUnique(_ref), m_uid(_id) {
|
||||
|
||||
}
|
||||
Connection(const Connection&) = delete; // not copyable
|
||||
@ -43,23 +188,15 @@ namespace esignal {
|
||||
Connection& operator=(Connection&&) = default; // movable op
|
||||
|
||||
~Connection() {
|
||||
if (m_signal == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_signal->disconnect(m_uid);
|
||||
m_signal = nullptr;
|
||||
m_signalRefUnique.disconnect(m_uid);
|
||||
m_uid = 0;
|
||||
}
|
||||
void disconnect() {
|
||||
if (m_signal == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_signal->disconnect(m_uid);
|
||||
m_signal = nullptr;
|
||||
m_signalRefUnique.disconnect(m_uid);
|
||||
m_uid = 0;
|
||||
}
|
||||
private:
|
||||
SignalBase* m_signal;
|
||||
lockSharedPtrRef<SignalBase> m_signalRefUnique;
|
||||
std::size_t m_uid;
|
||||
};
|
||||
|
||||
@ -67,8 +204,6 @@ namespace esignal {
|
||||
class Signal : public SignalBase {
|
||||
public:
|
||||
using Observer = std::function<void(const Args&...)>;
|
||||
public:
|
||||
|
||||
private:
|
||||
|
||||
class Executor {
|
||||
@ -132,7 +267,7 @@ namespace esignal {
|
||||
std::unique_ptr<Executor> executer(new Executor(std::forward<ObserverType>(observer)));
|
||||
std::size_t uid = executer->m_uid;
|
||||
m_executors.push_back(std::move(executer));
|
||||
return Connection(this, uid);
|
||||
return Connection(SignalBase::m_shared, uid);
|
||||
}
|
||||
template<class pointer, class Func, class... Arg>
|
||||
Connection connect(pointer* _class, Func _f, Arg... _arg) {
|
||||
@ -141,7 +276,7 @@ namespace esignal {
|
||||
}));
|
||||
std::size_t uid = executer->m_uid;
|
||||
m_executors.push_back(std::move(executer));
|
||||
return Connection(this, uid);
|
||||
return Connection(SignalBase::m_shared, uid);
|
||||
}
|
||||
template<class pointer, class Func, class... Arg>
|
||||
void connect(const std::shared_ptr<pointer>& _class, Func _f, Arg... _arg) {
|
||||
@ -183,6 +318,15 @@ namespace esignal {
|
||||
m_callInProgress(0) {
|
||||
|
||||
}
|
||||
// copy constructor:
|
||||
Signal(const Signal&) = delete;
|
||||
// copy operator:
|
||||
Signal& operator=(Signal) = delete;
|
||||
Signal& operator=(const Signal& _obj) = delete;
|
||||
// Move constructor
|
||||
Signal(Signal&& _obj) = delete;
|
||||
// Move operator
|
||||
Signal& operator=(Signal&& _obj) = delete;
|
||||
size_t size() const {
|
||||
return m_executors.size();
|
||||
}
|
||||
@ -198,256 +342,8 @@ namespace esignal {
|
||||
std::vector<std::unique_ptr<Executor>> m_executors;
|
||||
int32_t m_callInProgress;
|
||||
};
|
||||
/*
|
||||
class SignalInderection : public std::enable_shared_ptr<SignalInderection> {
|
||||
public:
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
#if 0
|
||||
template<typename... T> class Signal {
|
||||
public:
|
||||
using Observer std::function<void(const T&...)>;
|
||||
private:
|
||||
std::vector<std::pair<std::weak_ptr<void>, Observer>> m_callerList; // current list of binded element
|
||||
std::vector<std::pair<std::weak_ptr<void>, Observer>> m_callerListInCallback; // temporaty list (when add one in call process)
|
||||
std::vector<Observer> m_callerListDirect; // current list of binded element
|
||||
std::vector<Observer> m_callerListDirectInCallback; // temporaty list (when add one in call process)
|
||||
int32_t m_callInProgress;
|
||||
bool m_someOneRemoveInCall;
|
||||
public:
|
||||
/**
|
||||
* @brief Create a signal with a specific type.
|
||||
* @param[in] _signalInterfaceLink reference on the signal lister.
|
||||
* @param[in] _name Static name of the signal.
|
||||
* @param[in] _description Description of the signal.
|
||||
* @param[in] _periodic Customisation of the log display tag at true to down debug lebel at verbose.
|
||||
*/
|
||||
Signal() :
|
||||
m_callInProgress(0),
|
||||
m_someOneRemoveInCall(false) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor.
|
||||
*/
|
||||
~Signal() = default;
|
||||
/**
|
||||
* @brief Bind a callback function to the current signal (generic methis (simplest))
|
||||
* @param[in] _obj Shared pointer on the caller object
|
||||
* @param[in] _func Link on the fuction that might be called (inside a class)
|
||||
* @example signalXXXX.bind(shared_from_this(), &ClassName::onCallbackXXX);
|
||||
*/
|
||||
template<class TYPE_CLASS, class TYPE, typename... TArgs>
|
||||
void bind(std::shared_ptr<TYPE_CLASS> _obj, void (TYPE::*_func)(const T&..., TArgs...), TArgs... _args2) {
|
||||
std::shared_ptr<TYPE> obj2 = std::dynamic_pointer_cast<TYPE>(_obj);
|
||||
if (obj2 == nullptr) {
|
||||
ESIGNAL_ERROR("Can not bind signal ...");
|
||||
return;
|
||||
}
|
||||
if (m_callInProgress == 0) {
|
||||
if (COUNT_ELEM == 1) {
|
||||
m_callerList.push_back(std::make_pair(std::weak_ptr<void>(_obj), [](TArgs...){obj2.get()->, std::placeholders::_1, std::forward<TArgs>(_args2)...)));
|
||||
}
|
||||
} else {
|
||||
// m_callerListInCallback.push_back(std::make_pair(std::weak_ptr<void>(_obj), std::bind(_func, obj2.get(), std::placeholders::_1, std::forward<TArgs>(_args2)...)));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Advanced binding a callback function to the current signal.
|
||||
* @param[in] _obj Shared pointer on the caller object
|
||||
* @param[in] _func functor to call (do it yourself)
|
||||
* @example signalXXXX.connect(shared_from_this(), std::bind(&ClassName::onCallbackXXX, this, std::placeholders::_1));
|
||||
*/
|
||||
void connect(std::shared_ptr<void> _obj, std::function<void(const T&...)> _function ) {
|
||||
if (m_callInProgress == 0) {
|
||||
m_callerList.push_back(std::make_pair(std::weak_ptr<void>(_obj), _function));
|
||||
} else {
|
||||
m_callerListInCallback.push_back(std::make_pair(std::weak_ptr<void>(_obj), _function));
|
||||
}
|
||||
}
|
||||
//! @previous
|
||||
void connect(std::function<void(const T&...)> _function );{
|
||||
if (m_callInProgress == 0) {
|
||||
m_callerListDirect.push_back(_function);
|
||||
} else {
|
||||
m_callerListDirectInCallback.push_back(_function);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Check if an object is registered in the Signal
|
||||
* @param[in] _obj shared pointer on the object
|
||||
* @return true The object is connected at this signal.
|
||||
* @return false The object is NOT connected on this signal.
|
||||
*/
|
||||
bool isRegistered(std::shared_ptr<void> _obj) {
|
||||
if (_obj == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (auto &it : m_callerList) {
|
||||
std::shared_ptr<void> obj = it.first.lock();
|
||||
if (obj == _obj) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (auto &it : m_callerListInCallback) {
|
||||
std::shared_ptr<void> obj = it.first.lock();
|
||||
if (obj == _obj) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* @brief remove link on the signal.
|
||||
* @param[in] _obj shared pointer on the removing object
|
||||
*/
|
||||
void release(std::shared_ptr<void> _obj);{
|
||||
if (m_callInProgress == 0) {
|
||||
// Remove from the list :
|
||||
auto it(m_callerList.begin());
|
||||
while(it != m_callerList.end()) {
|
||||
if (it->first.lock() == _obj) {
|
||||
it = m_callerList.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// just remove weak poointer
|
||||
auto it(m_callerList.begin());
|
||||
while(it != m_callerList.end()) {
|
||||
if (it->first.lock() == _obj) {
|
||||
it->first.reset();
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
m_someOneRemoveInCall = true;
|
||||
}
|
||||
// remove from add list in callback progress
|
||||
auto it = m_callerListInCallback.begin();
|
||||
while(it != m_callerListInCallback.end()) {
|
||||
if (it->first.lock() == _obj) {
|
||||
it = m_callerListInCallback.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Generate a signal on all interface listening.
|
||||
* @param[in] _data data to emit
|
||||
*/
|
||||
void emit(const T&... _data);{
|
||||
#ifdef DEBUG
|
||||
m_signalCallLevel++;
|
||||
int32_t tmpID = m_uidSignal++;
|
||||
#endif
|
||||
m_callInProgress++;
|
||||
if (m_periodic == true) {
|
||||
ESIGNAL_VERBOSE(esignal::logIndent(m_signalCallLevel-1) << "emit signal{" << tmpID << "} : signal='" << m_name << "' data='" << /*etk::to_string(_data) <<*/ "' to: " << m_callerList.size() << " element(s)");
|
||||
} else {
|
||||
ESIGNAL_DEBUG(esignal::logIndent(m_signalCallLevel-1) << "emit signal{" << tmpID << "} : signal='" << m_name << "' data='" << /*etk::to_string(_data) <<*/ "' to: " << m_callerList.size() << " element(s)");
|
||||
}
|
||||
{
|
||||
auto it(m_callerList.begin());
|
||||
while (it != m_callerList.end()) {
|
||||
std::shared_ptr<void> destObject = it->first.lock();
|
||||
if (destObject == nullptr) {
|
||||
it = m_callerList.erase(it);
|
||||
ESIGNAL_DEBUG(esignal::logIndent(m_signalCallLevel-1) << " nullptr dest");
|
||||
continue;
|
||||
}
|
||||
if (m_periodic == true) {
|
||||
ESIGNAL_VERBOSE(esignal::logIndent(m_signalCallLevel-1) << " signal{" << tmpID << "} :");// [" << destObject->getId() << "]" << destObject->getObjectType());
|
||||
} else {
|
||||
ESIGNAL_DEBUG(esignal::logIndent(m_signalCallLevel-1) << " signal{" << tmpID << "} :");// [" << destObject->getId() << "]" << destObject->getObjectType());
|
||||
}
|
||||
it->second(_data...);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto it(m_callerListDirect.begin());
|
||||
while (it != m_callerListDirect.end()) {
|
||||
if (m_periodic == true) {
|
||||
ESIGNAL_VERBOSE(esignal::logIndent(m_signalCallLevel-1) << "X signal{" << tmpID << "} :");// [" << destObject->getId() << "]" << destObject->getObjectType());
|
||||
} else {
|
||||
ESIGNAL_DEBUG(esignal::logIndent(m_signalCallLevel-1) << "X signal{" << tmpID << "} :");// [" << destObject->getId() << "]" << destObject->getObjectType());
|
||||
}
|
||||
(*it)(_data...);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
m_callInProgress--;
|
||||
#ifdef DEBUG
|
||||
m_signalCallLevel--;
|
||||
#endif
|
||||
// Remove element in call phase:
|
||||
if (m_someOneRemoveInCall == true) {
|
||||
m_someOneRemoveInCall = false;
|
||||
// Remove from the list :
|
||||
auto it(m_callerList.begin());
|
||||
while(it != m_callerList.end()) {
|
||||
if (it->first.expired() == true) {
|
||||
it = m_callerList.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
// add element in call phase:
|
||||
if (m_callerListInCallback.size() > 0) {
|
||||
for (auto &it : m_callerListInCallback) {
|
||||
m_callerList.push_back(it);
|
||||
}
|
||||
m_callerListInCallback.clear();
|
||||
}
|
||||
if (m_callerListDirectInCallback.size() > 0) {
|
||||
for (auto &it : m_callerListDirectInCallback) {
|
||||
m_callerListDirect.push_back(it);
|
||||
}
|
||||
m_callerListDirectInCallback.clear();
|
||||
}
|
||||
}
|
||||
size_t getNumberConnected();{
|
||||
return m_callerList.size() + m_callerListDirect.size();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#undef __class__
|
||||
#define __class__ nullptr
|
||||
}
|
||||
|
||||
|
||||
//#define SDFGSDFGSDFGSDFGSDFGSDFG
|
||||
#ifdef SDFGSDFGSDFGSDFGSDFGSDFG
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
template<int I> struct placeholder{};
|
||||
|
||||
namespace std{
|
||||
template<int I>
|
||||
struct is_placeholder< ::placeholder<I>> : std::integral_constant<int, I>{
|
||||
|
||||
};
|
||||
} // std::
|
||||
|
||||
namespace detail{
|
||||
template<std::size_t... Is, class F, class... Args>
|
||||
auto easy_bind(indices<Is...>, F const& f, Args&&... args) -> decltype(std::bind(f, std::forward<Args>(args)..., placeholder<Is + 1>{}...)) {
|
||||
return std::bind(f, std::forward<Args>(args)..., placeholder<Is + 1>{}...);
|
||||
}
|
||||
} // detail::
|
||||
|
||||
template<class R, class... FArgs, class... Args>
|
||||
auto easy_bind(std::function<R(FArgs...)> const& f, Args&&... args) -> decltype(detail::easy_bind(build_indices<sizeof...(FArgs) - sizeof...(Args)>{}, f, std::forward<Args>(args)...)) {
|
||||
return detail::easy_bind(build_indices<sizeof...(FArgs) - sizeof...(Args)>{}, f, std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "etktest"
|
||||
#define __class__ "etk-test"
|
||||
|
||||
int main(int _argc, const char *_argv[]) {
|
||||
::testing::InitGoogleTest(&_argc, const_cast<char **>(_argv));
|
||||
@ -22,12 +22,11 @@ int main(int _argc, const char *_argv[]) {
|
||||
std::string data = _argv[iii];
|
||||
if ( data == "-h"
|
||||
|| data == "--help") {
|
||||
TEST_PRINT("esvg-test - help : ");
|
||||
TEST_PRINT("esignal-test - help : ");
|
||||
TEST_PRINT(" " << _argv[0] << " [options]");
|
||||
TEST_PRINT(" No optiions ...");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
//etk::initDefaultFolder("esvg-test");
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ TEST(test_signal_arg, checkType) {
|
||||
baseClass.emit();
|
||||
EXPECT_EQ(connectedClass->m_valueInt32, 22);
|
||||
*/
|
||||
#if 0
|
||||
esignal::Signal<int, float, char> signal;
|
||||
// ----------------------------------------------------
|
||||
auto display_values_1 = []( int a, float b, char c){
|
||||
@ -129,6 +130,14 @@ TEST(test_signal_arg, checkType) {
|
||||
signal.connect(connectedClassShared, &TestConnectShared::display_values_7, "coucou");
|
||||
|
||||
|
||||
signal.emit( 5, 2.99, 'k');
|
||||
|
||||
h1.disconnect();
|
||||
h2.disconnect();
|
||||
h3.disconnect();
|
||||
h4.disconnect();
|
||||
h5.disconnect();
|
||||
|
||||
//signal.connect( complete_class(&connectedClass, &TestConnect::display_values_3) );
|
||||
//signal.connect( TestConnect::display_values_3(&connectedClass) );
|
||||
|
||||
@ -144,5 +153,25 @@ TEST(test_signal_arg, checkType) {
|
||||
// ----------------------------------------------------
|
||||
|
||||
signal.emit( 5, 2.99, 'k');
|
||||
#endif
|
||||
std::cout << "========> Nes Signal " << std::endl;
|
||||
std::shared_ptr<esignal::Signal<std::string>> signalShared = std::make_shared<esignal::Signal<std::string>>();
|
||||
|
||||
std::cout << "========> Connect callback " << std::endl;
|
||||
auto display_val = [&]( const std::string& a){
|
||||
std::cout << " 1010 " << a<< std::endl;
|
||||
std::cout << " ----------------------------------" << std::endl;
|
||||
};
|
||||
esignal::Connection h7 = signalShared->connect(display_val);
|
||||
|
||||
std::cout << "========> Emit" << std::endl;
|
||||
signalShared->emit("coucou");
|
||||
|
||||
std::cout << "========> Remove Signal " << std::endl;
|
||||
signalShared.reset();
|
||||
|
||||
std::cout << "========> disconnect " << std::endl;
|
||||
h7.disconnect();
|
||||
|
||||
std::cout << "========================================= " << std::endl;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user