[DEV] can remove signal befor handle
This commit is contained in:
parent
9003745811
commit
1fcf22bf03
@ -14,15 +14,13 @@
|
|||||||
|
|
||||||
namespace esignal {
|
namespace esignal {
|
||||||
#undef __class__
|
#undef __class__
|
||||||
#define __class__ "Signal<T>"
|
#define __class__ "ISignal<T>"
|
||||||
template<typename T> class Signal : public esignal::Base {
|
template<class... Args>
|
||||||
private:
|
class ISignal : public Signal<Args...> {
|
||||||
std::vector<std::pair<std::weak_ptr<void>,
|
protected:
|
||||||
std::function<void(const T&)>>> m_callerList; // current list of binded element
|
esignal::Interface& m_signalInterfaceLink;
|
||||||
std::vector<std::pair<std::weak_ptr<void>,
|
std::string m_name;
|
||||||
std::function<void(const T&)>>> m_callerListInCallback; // temporaty list (when add one in call process)
|
std::string m_description;
|
||||||
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)
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Create a signal with a specific type.
|
* @brief Create a signal with a specific type.
|
||||||
@ -31,10 +29,10 @@ namespace esignal {
|
|||||||
* @param[in] _description Description 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.
|
* @param[in] _periodic Customisation of the log display tag at true to down debug lebel at verbose.
|
||||||
*/
|
*/
|
||||||
Signal(esignal::Interface& _signalInterfaceLink,
|
ISignal(esignal::Interface& _signalInterfaceLink,
|
||||||
const std::string& _name,
|
const std::string& _name,
|
||||||
const std::string& _description = "",
|
const std::string& _description = "",
|
||||||
bool _periodic = false);
|
bool _periodic = false);
|
||||||
/**
|
/**
|
||||||
* @brief Destructor.
|
* @brief Destructor.
|
||||||
*/
|
*/
|
||||||
|
430
esignal/Signal.h
430
esignal/Signal.h
@ -14,27 +14,172 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace esignal {
|
namespace esignal {
|
||||||
extern size_t s_uid;
|
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__
|
#undef __class__
|
||||||
#define __class__ "Signal<T>"
|
#define __class__ "Signal<T>"
|
||||||
class SignalInderection;
|
class SignalInderection;
|
||||||
class SignalBase {
|
class SignalBase {
|
||||||
|
protected:
|
||||||
|
lockSharedPtrRef<SignalBase> m_shared;
|
||||||
public:
|
public:
|
||||||
SignalBase() {
|
SignalBase() :
|
||||||
|
m_shared(this) {
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual ~SignalBase() {
|
// 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;
|
virtual void disconnect(std::size_t _uid) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Connection {
|
class Connection {
|
||||||
public:
|
public:
|
||||||
Connection(SignalBase* _sig, std::size_t _id):
|
Connection(lockSharedPtrRef<SignalBase> _ref, std::size_t _id):
|
||||||
m_signal(_sig), m_uid(_id) {
|
m_signalRefUnique(_ref), m_uid(_id) {
|
||||||
|
|
||||||
}
|
}
|
||||||
Connection(const Connection&) = delete; // not copyable
|
Connection(const Connection&) = delete; // not copyable
|
||||||
@ -43,23 +188,15 @@ namespace esignal {
|
|||||||
Connection& operator=(Connection&&) = default; // movable op
|
Connection& operator=(Connection&&) = default; // movable op
|
||||||
|
|
||||||
~Connection() {
|
~Connection() {
|
||||||
if (m_signal == nullptr) {
|
m_signalRefUnique.disconnect(m_uid);
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_signal->disconnect(m_uid);
|
|
||||||
m_signal = nullptr;
|
|
||||||
m_uid = 0;
|
m_uid = 0;
|
||||||
}
|
}
|
||||||
void disconnect() {
|
void disconnect() {
|
||||||
if (m_signal == nullptr) {
|
m_signalRefUnique.disconnect(m_uid);
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_signal->disconnect(m_uid);
|
|
||||||
m_signal = nullptr;
|
|
||||||
m_uid = 0;
|
m_uid = 0;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SignalBase* m_signal;
|
lockSharedPtrRef<SignalBase> m_signalRefUnique;
|
||||||
std::size_t m_uid;
|
std::size_t m_uid;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -67,8 +204,6 @@ namespace esignal {
|
|||||||
class Signal : public SignalBase {
|
class Signal : public SignalBase {
|
||||||
public:
|
public:
|
||||||
using Observer = std::function<void(const Args&...)>;
|
using Observer = std::function<void(const Args&...)>;
|
||||||
public:
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
class Executor {
|
class Executor {
|
||||||
@ -132,7 +267,7 @@ namespace esignal {
|
|||||||
std::unique_ptr<Executor> executer(new Executor(std::forward<ObserverType>(observer)));
|
std::unique_ptr<Executor> executer(new Executor(std::forward<ObserverType>(observer)));
|
||||||
std::size_t uid = executer->m_uid;
|
std::size_t uid = executer->m_uid;
|
||||||
m_executors.push_back(std::move(executer));
|
m_executors.push_back(std::move(executer));
|
||||||
return Connection(this, uid);
|
return Connection(SignalBase::m_shared, uid);
|
||||||
}
|
}
|
||||||
template<class pointer, class Func, class... Arg>
|
template<class pointer, class Func, class... Arg>
|
||||||
Connection connect(pointer* _class, Func _f, Arg... _arg) {
|
Connection connect(pointer* _class, Func _f, Arg... _arg) {
|
||||||
@ -141,7 +276,7 @@ namespace esignal {
|
|||||||
}));
|
}));
|
||||||
std::size_t uid = executer->m_uid;
|
std::size_t uid = executer->m_uid;
|
||||||
m_executors.push_back(std::move(executer));
|
m_executors.push_back(std::move(executer));
|
||||||
return Connection(this, uid);
|
return Connection(SignalBase::m_shared, uid);
|
||||||
}
|
}
|
||||||
template<class pointer, class Func, class... Arg>
|
template<class pointer, class Func, class... Arg>
|
||||||
void connect(const std::shared_ptr<pointer>& _class, Func _f, Arg... _arg) {
|
void connect(const std::shared_ptr<pointer>& _class, Func _f, Arg... _arg) {
|
||||||
@ -183,6 +318,15 @@ namespace esignal {
|
|||||||
m_callInProgress(0) {
|
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 {
|
size_t size() const {
|
||||||
return m_executors.size();
|
return m_executors.size();
|
||||||
}
|
}
|
||||||
@ -198,256 +342,8 @@ namespace esignal {
|
|||||||
std::vector<std::unique_ptr<Executor>> m_executors;
|
std::vector<std::unique_ptr<Executor>> m_executors;
|
||||||
int32_t m_callInProgress;
|
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__
|
#undef __class__
|
||||||
#define __class__ nullptr
|
#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>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#undef __class__
|
#undef __class__
|
||||||
#define __class__ "etktest"
|
#define __class__ "etk-test"
|
||||||
|
|
||||||
int main(int _argc, const char *_argv[]) {
|
int main(int _argc, const char *_argv[]) {
|
||||||
::testing::InitGoogleTest(&_argc, const_cast<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];
|
std::string data = _argv[iii];
|
||||||
if ( data == "-h"
|
if ( data == "-h"
|
||||||
|| data == "--help") {
|
|| data == "--help") {
|
||||||
TEST_PRINT("esvg-test - help : ");
|
TEST_PRINT("esignal-test - help : ");
|
||||||
TEST_PRINT(" " << _argv[0] << " [options]");
|
TEST_PRINT(" " << _argv[0] << " [options]");
|
||||||
TEST_PRINT(" No optiions ...");
|
TEST_PRINT(" No optiions ...");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//etk::initDefaultFolder("esvg-test");
|
|
||||||
return RUN_ALL_TESTS();
|
return RUN_ALL_TESTS();
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,7 @@ TEST(test_signal_arg, checkType) {
|
|||||||
baseClass.emit();
|
baseClass.emit();
|
||||||
EXPECT_EQ(connectedClass->m_valueInt32, 22);
|
EXPECT_EQ(connectedClass->m_valueInt32, 22);
|
||||||
*/
|
*/
|
||||||
|
#if 0
|
||||||
esignal::Signal<int, float, char> signal;
|
esignal::Signal<int, float, char> signal;
|
||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
auto display_values_1 = []( int a, float b, char c){
|
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.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( complete_class(&connectedClass, &TestConnect::display_values_3) );
|
||||||
//signal.connect( TestConnect::display_values_3(&connectedClass) );
|
//signal.connect( TestConnect::display_values_3(&connectedClass) );
|
||||||
|
|
||||||
@ -144,5 +153,25 @@ TEST(test_signal_arg, checkType) {
|
|||||||
// ----------------------------------------------------
|
// ----------------------------------------------------
|
||||||
|
|
||||||
signal.emit( 5, 2.99, 'k');
|
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…
x
Reference in New Issue
Block a user