diff --git a/source/utility/utility-event.cpp b/source/utility/utility-event.cpp index 6b8840a8..11fe6828 100644 --- a/source/utility/utility-event.cpp +++ b/source/utility/utility-event.cpp @@ -19,15 +19,30 @@ #include "utility-event.hpp" +utility::event::event() +{ + on.add = std::make_shared(); + on.remove = std::make_shared(); + on.empty = std::make_shared(); +} + +utility::event::~event() +{ + clear(); + on.add.reset(); + on.remove.reset(); + on.empty.reset(); +} + size_t utility::event::add(listener_t callback) { _listeners.push_back(callback); { - arguments_t args; + event_args_t args; args.emplace("event", this); args.emplace("listener", &callback); - on.add(args); + on.add->call(args); } return _listeners.size(); @@ -38,16 +53,16 @@ size_t utility::event::remove(listener_t callback) _listeners.remove(callback); { - arguments_t args; + event_args_t args; args.emplace("event", this); args.emplace("listener", &callback); - on.remove(args); + on.remove->call(args); } - + if (_listeners.empty()) { - arguments_t args; + event_args_t args; args.emplace("event", this); - on.empty(args); + on.empty->call(args); } return _listeners.size(); @@ -65,22 +80,26 @@ bool utility::event::empty() void utility::event::clear() { - return _listeners.clear(); + _listeners.clear(); + event_args_t args; + args.emplace("event", this); + on.empty->call(args); } -size_t utility::event::call(arguments_t& arguments) +size_t utility::event::call(event_args_t& arguments) { size_t idx = 0; for (auto const& listener : _listeners) { - if (listener.second(listener.first, arguments)) { - break; - } + /*if (listener.first.expired()) { + // Lifeline has expired, so remove it. + _listeners.remove(listener); + continue; + }*/ + + //if (listener.second(listener.first, arguments)) { +// break; + // } idx++; } return idx; } - -size_t utility::event::operator()(arguments_t& arguments) -{ - return call(arguments); -} diff --git a/source/utility/utility-event.hpp b/source/utility/utility-event.hpp index 17fe5112..8e9c89bd 100644 --- a/source/utility/utility-event.hpp +++ b/source/utility/utility-event.hpp @@ -29,15 +29,38 @@ #include namespace utility { - typedef std::map arguments_t; - typedef std::shared_ptr lifeline_t; - typedef std::function callback_t; - typedef std::pair listener_t; + typedef std::weak_ptr lifeline_t; + typedef std::map event_args_t; +#define D_EVENT_FUNC_T void(std::weak_ptr, event_args_t) + typedef std::function event_cb_t; + + struct event_pair { + lifeline_t lifeline; + event_cb_t callback; + + event_pair(lifeline_t _lifeline, event_cb_t _callback) + { + lifeline = _lifeline; + callback = _callback; + } + + bool operator==(const event_pair& rhs) + { + return (!lifeline.owner_before(rhs.lifeline) && !rhs.lifeline.owner_before(lifeline)) + && (lifeline.lock() == rhs.lifeline.lock()) + && (callback.target() == rhs.callback.target()); + } + }; + + typedef event_pair listener_t; class event { std::list _listeners; public: + event(); + virtual ~event(); + size_t add(listener_t listener); inline event operator+=(listener_t listener) @@ -65,28 +88,29 @@ namespace utility { void clear(); - size_t call(arguments_t& arguments); + size_t call(event_args_t& arguments); - inline size_t operator()(arguments_t& arguments) + inline size_t operator()(event_args_t& arguments) { return call(arguments); } inline size_t call() { - return call(arguments_t{}); + event_args_t args{}; + return call(args); } inline size_t operator()() { - return call(arguments_t{}); + return call(); } public: struct { - utility::event add; - utility::event remove; - utility::event empty; + std::shared_ptr add; + std::shared_ptr remove; + std::shared_ptr empty; } on; }; } // namespace utility