#include #include namespace nana { namespace detail { //class events_operation using lock_guard = std::lock_guard; void events_operation::register_evt(event_handle evt) { lock_guard lock(mutex_); handles_.insert(evt); } void events_operation::cancel(event_handle evt) { lock_guard lock(mutex_); handles_.erase(evt); } void events_operation::erase(event_handle evt) { lock_guard lock(mutex_); auto i = handles_.find(evt); if (i != handles_.end()) { reinterpret_cast(evt)->get_event()->remove(evt); } } //end namespace events_operation //class docker_base docker_base::docker_base(event_interface* evt, bool unignorable_flag) : event_ptr(evt), unignorable(unignorable_flag) {} detail::event_interface * docker_base::get_event() const { return event_ptr; } //end class docker_base //class event_base event_base::~event_base() { clear(); } std::size_t event_base::length() const { internal_scope_guard lock; return (nullptr == dockers_ ? 0 : dockers_->size()); } void event_base::clear() noexcept { internal_scope_guard lock; if (dockers_) { auto & evt_operation = bedrock::instance().evt_operation(); for (auto p : *dockers_) { evt_operation.cancel(reinterpret_cast(p)); delete p; } dockers_->clear(); delete dockers_; dockers_ = nullptr; } } void event_base::remove(event_handle evt) { internal_scope_guard lock; if (dockers_) { for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i) { if (reinterpret_cast(evt) == *i) { //Checks whether this event is working now. if (emitting_count_) { static_cast(*i)->flag_deleted = true; deleted_flags_ = true; } else { bedrock::instance().evt_operation().cancel(evt); dockers_->erase(i); delete reinterpret_cast(evt); } break; } } } } event_handle event_base::_m_emplace(detail::docker_interface* docker_ptr, bool in_front) { internal_scope_guard lock; if (nullptr == dockers_) dockers_ = new std::vector; auto evt = reinterpret_cast(docker_ptr); if (in_front) dockers_->emplace(dockers_->begin(), docker_ptr); else dockers_->emplace_back(docker_ptr); detail::events_operation_register(evt); return evt; } //class emit_counter event_base::emit_counter::emit_counter(event_base* evt) : evt_{ evt } { ++evt->emitting_count_; } event_base::emit_counter::~emit_counter() { if ((0 == --evt_->emitting_count_) && evt_->deleted_flags_) { evt_->deleted_flags_ = false; for (auto i = evt_->dockers_->begin(); i != evt_->dockers_->end();) { if (static_cast(*i)->flag_deleted) { bedrock::instance().evt_operation().cancel(reinterpret_cast(*i)); delete (*i); i = evt_->dockers_->erase(i); } else ++i; } } } //end class emit_counter //end class event_base }//end namespace detail }//end namespace nana