optimize template class to reduce generated binary size
This commit is contained in:
		
							parent
							
								
									2dd9283782
								
							
						
					
					
						commit
						0ed51a7a21
					
				@ -24,6 +24,9 @@ namespace nana
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	namespace detail
 | 
						namespace detail
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							void events_operation_register(event_handle);
 | 
				
			||||||
 | 
							void events_operation_cancel(event_handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		class event_interface
 | 
							class event_interface
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
@ -38,8 +41,50 @@ namespace nana
 | 
				
			|||||||
			virtual event_interface*	get_event() const = 0;
 | 
								virtual event_interface*	get_event() const = 0;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void events_operation_register(event_handle);
 | 
					
 | 
				
			||||||
		void events_operation_cancel(event_handle);
 | 
							struct docker_base
 | 
				
			||||||
 | 
								: public docker_interface
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								event_interface * event_ptr;
 | 
				
			||||||
 | 
								bool flag_deleted{ false };
 | 
				
			||||||
 | 
								const bool unignorable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								docker_base(event_interface*, bool unignorable_flag);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								detail::event_interface * get_event() const override;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							class event_base
 | 
				
			||||||
 | 
								: public detail::event_interface
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							public:
 | 
				
			||||||
 | 
								~event_base();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								std::size_t length() const;
 | 
				
			||||||
 | 
								void clear() noexcept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								void remove(event_handle evt) override;
 | 
				
			||||||
 | 
							protected:
 | 
				
			||||||
 | 
								//class emit_counter is a RAII helper for emitting count
 | 
				
			||||||
 | 
								//It is used for avoiding a try{}catch block which is required for some finial works when
 | 
				
			||||||
 | 
								//event handlers throw exceptions.
 | 
				
			||||||
 | 
								class emit_counter
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
								public:
 | 
				
			||||||
 | 
									emit_counter(event_base*);
 | 
				
			||||||
 | 
									~emit_counter();
 | 
				
			||||||
 | 
								private:
 | 
				
			||||||
 | 
									event_base * const evt_;
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								//event_handle _m_emplace(::std::unique_ptr<detail::docker_interface>& docker_ptr, bool in_front);
 | 
				
			||||||
 | 
								event_handle _m_emplace(detail::docker_interface*, bool in_front);
 | 
				
			||||||
 | 
							protected:
 | 
				
			||||||
 | 
								unsigned emitting_count_{ 0 };
 | 
				
			||||||
 | 
								bool deleted_flags_{ false };
 | 
				
			||||||
 | 
								//std::unique_ptr<std::vector<std::unique_ptr<detail::docker_interface>>> dockers_;
 | 
				
			||||||
 | 
								std::vector<detail::docker_interface*> * dockers_{ nullptr };
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
	}//end namespace detail
 | 
						}//end namespace detail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// base clase for all event argument types
 | 
					    /// base clase for all event argument types
 | 
				
			||||||
@ -59,83 +104,32 @@ namespace nana
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /// the type of the members of general_events 
 | 
					    /// the type of the members of general_events 
 | 
				
			||||||
	template<typename Arg>
 | 
						template<typename Arg>
 | 
				
			||||||
	class basic_event : public detail::event_interface
 | 
						class basic_event : public detail::event_base
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		using arg_reference = const typename std::remove_reference<Arg>::type &;
 | 
							using arg_reference = const typename std::remove_reference<Arg>::type &;
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		struct docker
 | 
							struct docker
 | 
				
			||||||
			: public detail::docker_interface
 | 
								: public detail::docker_base
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			basic_event * const event_ptr;
 | 
					 | 
				
			||||||
			std::function<void(arg_reference)> invoke;
 | 
								std::function<void(arg_reference)> invoke;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool flag_deleted{ false };
 | 
								docker(basic_event * evt, std::function<void(arg_reference)> && ivk, bool unignorable_flag)
 | 
				
			||||||
			bool unignorable{false};
 | 
									: docker_base(evt, unignorable_flag), invoke(std::move(ivk))
 | 
				
			||||||
 | 
					 | 
				
			||||||
			docker(basic_event * s, std::function<void(arg_reference)> && ivk, bool unignorable_flag)
 | 
					 | 
				
			||||||
				: event_ptr(s), invoke(std::move(ivk)), unignorable(unignorable_flag)
 | 
					 | 
				
			||||||
			{}
 | 
								{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			docker(basic_event * s, const std::function<void(arg_reference)> & ivk, bool unignorable_flag)
 | 
								docker(basic_event * evt, const std::function<void(arg_reference)> & ivk, bool unignorable_flag)
 | 
				
			||||||
				: event_ptr(s), invoke(ivk), unignorable(unignorable_flag)
 | 
									: docker_base(evt, unignorable_flag), invoke(ivk)
 | 
				
			||||||
			{}
 | 
								{}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			~docker()
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				detail::events_operation_cancel(reinterpret_cast<event_handle>(this));
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			detail::event_interface * get_event() const override
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				return event_ptr;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		//class emit_counter is a RAII helper for emitting count
 | 
					 | 
				
			||||||
		//It is used for avoiding a try{}catch block which is required for some finial works when
 | 
					 | 
				
			||||||
		//event handlers throw exceptions.
 | 
					 | 
				
			||||||
		class emit_counter
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
		public:
 | 
					 | 
				
			||||||
			emit_counter(basic_event* evt)
 | 
					 | 
				
			||||||
				: evt_{evt}
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				++evt->emitting_count_;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			~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<docker*>(i->get())->flag_deleted)
 | 
					 | 
				
			||||||
							i = evt_->dockers_->erase(i);
 | 
					 | 
				
			||||||
						else
 | 
					 | 
				
			||||||
							++i;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		private:
 | 
					 | 
				
			||||||
			basic_event * const evt_;
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
        /// It will get called firstly, because it is set at the beginning of the chain.
 | 
							/// Creates an event handler at the beginning of event chain
 | 
				
			||||||
		template<typename Function>
 | 
							template<typename Function>
 | 
				
			||||||
		event_handle connect_front(Function && fn)
 | 
							event_handle connect_front(Function && fn)
 | 
				
			||||||
		{
 | 
							{	
 | 
				
			||||||
			internal_scope_guard lock;
 | 
					 | 
				
			||||||
			if (nullptr == dockers_)
 | 
					 | 
				
			||||||
				dockers_.reset(new std::vector<std::unique_ptr<detail::docker_interface>>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			using prototype = typename std::remove_reference<Function>::type;
 | 
								using prototype = typename std::remove_reference<Function>::type;
 | 
				
			||||||
			std::unique_ptr<detail::docker_interface> dck(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false));
 | 
					
 | 
				
			||||||
			auto evt = reinterpret_cast<event_handle>(dck.get());
 | 
								return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), true);
 | 
				
			||||||
			dockers_->emplace(dockers_->begin(), std::move(dck));
 | 
					 | 
				
			||||||
			detail::events_operation_register(evt);
 | 
					 | 
				
			||||||
			return evt;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		event_handle connect(void (*fn)(arg_reference))
 | 
							event_handle connect(void (*fn)(arg_reference))
 | 
				
			||||||
@ -149,16 +143,9 @@ namespace nana
 | 
				
			|||||||
		template<typename Function>
 | 
							template<typename Function>
 | 
				
			||||||
		event_handle connect(Function && fn)
 | 
							event_handle connect(Function && fn)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			internal_scope_guard lock;
 | 
					 | 
				
			||||||
			if (nullptr == dockers_)
 | 
					 | 
				
			||||||
				dockers_.reset(new std::vector<std::unique_ptr<detail::docker_interface>>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			using prototype = typename std::remove_reference<Function>::type;
 | 
								using prototype = typename std::remove_reference<Function>::type;
 | 
				
			||||||
			std::unique_ptr<detail::docker_interface> dck(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false));
 | 
					
 | 
				
			||||||
			auto evt = reinterpret_cast<event_handle>(dck.get());
 | 
								return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), false), false);
 | 
				
			||||||
			dockers_->emplace_back(std::move(dck));
 | 
					 | 
				
			||||||
			detail::events_operation_register(evt);
 | 
					 | 
				
			||||||
			return evt;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// It will not get called if stop_propagation() was called.
 | 
							/// It will not get called if stop_propagation() was called.
 | 
				
			||||||
@ -171,26 +158,10 @@ namespace nana
 | 
				
			|||||||
		/// It will get called because it is unignorable.
 | 
							/// It will get called because it is unignorable.
 | 
				
			||||||
        template<typename Function>
 | 
					        template<typename Function>
 | 
				
			||||||
		event_handle connect_unignorable(Function && fn, bool in_front = false)
 | 
							event_handle connect_unignorable(Function && fn, bool in_front = false)
 | 
				
			||||||
		{
 | 
							{			
 | 
				
			||||||
			internal_scope_guard lock;
 | 
					 | 
				
			||||||
			if (nullptr == dockers_)
 | 
					 | 
				
			||||||
				dockers_.reset(new std::vector<std::unique_ptr<detail::docker_interface>>);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			using prototype = typename std::remove_reference<Function>::type;
 | 
								using prototype = typename std::remove_reference<Function>::type;
 | 
				
			||||||
			std::unique_ptr<detail::docker_interface> dck(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), true));
 | 
					 | 
				
			||||||
			auto evt = reinterpret_cast<event_handle>(dck.get());
 | 
					 | 
				
			||||||
			if (in_front)
 | 
					 | 
				
			||||||
				dockers_->emplace(dockers_->begin(), std::move(dck));
 | 
					 | 
				
			||||||
			else
 | 
					 | 
				
			||||||
				dockers_->emplace_back(std::move(dck));
 | 
					 | 
				
			||||||
			detail::events_operation_register(evt);
 | 
					 | 
				
			||||||
			return evt;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::size_t length() const
 | 
								return _m_emplace(new docker(this, factory<prototype, std::is_bind_expression<prototype>::value>::build(std::forward<Function>(fn)), true), in_front);
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			internal_scope_guard lock;
 | 
					 | 
				
			||||||
			return (nullptr == dockers_ ? 0 : dockers_->size());
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void emit(arg_reference& arg)
 | 
							void emit(arg_reference& arg)
 | 
				
			||||||
@ -202,13 +173,13 @@ namespace nana
 | 
				
			|||||||
			emit_counter ec(this);
 | 
								emit_counter ec(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto& dockers = *dockers_;
 | 
								auto& dockers = *dockers_;
 | 
				
			||||||
			const auto dockers_len = dockers.size();
 | 
								const auto dockers_len = dockers_->size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			//The dockers may resize when a new event handler is created by a calling handler.
 | 
								//The dockers may resize when a new event handler is created by a calling handler.
 | 
				
			||||||
			//Traverses with position can avaid crash error which caused by a iterator which becomes invalid.
 | 
								//Traverses with position can avaid crash error which caused by a iterator which becomes invalid.
 | 
				
			||||||
			for (std::size_t pos = 0; pos < dockers_len; ++pos)
 | 
								for (std::size_t pos = 0; pos < dockers_len; ++pos)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				auto docker_ptr = static_cast<docker*>(dockers[pos].get());
 | 
									auto docker_ptr = static_cast<docker*>(dockers[pos]);
 | 
				
			||||||
				if (docker_ptr->flag_deleted)
 | 
									if (docker_ptr->flag_deleted)
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -217,7 +188,7 @@ namespace nana
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					for (++pos; pos < dockers_len; ++pos)
 | 
										for (++pos; pos < dockers_len; ++pos)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						auto docker_ptr = static_cast<docker*>(dockers[pos].get());
 | 
											auto docker_ptr = static_cast<docker*>(dockers[pos]);
 | 
				
			||||||
						if (!docker_ptr->unignorable || docker_ptr->flag_deleted)
 | 
											if (!docker_ptr->unignorable || docker_ptr->flag_deleted)
 | 
				
			||||||
							continue;
 | 
												continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -227,36 +198,6 @@ namespace nana
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		void clear()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			internal_scope_guard lock;
 | 
					 | 
				
			||||||
			if (dockers_)
 | 
					 | 
				
			||||||
				dockers_.reset();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void remove(event_handle evt) override
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			internal_scope_guard lock;
 | 
					 | 
				
			||||||
			if (dockers_)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				for (auto i = dockers_->begin(), end = dockers_->end(); i != end; ++i)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (reinterpret_cast<detail::docker_interface*>(evt) == i->get())
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						//Checks whether this event is working now.
 | 
					 | 
				
			||||||
						if (emitting_count_ > 1)
 | 
					 | 
				
			||||||
						{
 | 
					 | 
				
			||||||
							static_cast<docker*>(i->get())->flag_deleted = true;
 | 
					 | 
				
			||||||
							deleted_flags_ = true;
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						else
 | 
					 | 
				
			||||||
							dockers_->erase(i);
 | 
					 | 
				
			||||||
						break;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		template<typename Fn, bool IsBind>
 | 
							template<typename Fn, bool IsBind>
 | 
				
			||||||
		struct factory
 | 
							struct factory
 | 
				
			||||||
@ -413,10 +354,6 @@ namespace nana
 | 
				
			|||||||
				};
 | 
									};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	private:
 | 
					 | 
				
			||||||
		unsigned emitting_count_{ 0 };
 | 
					 | 
				
			||||||
		bool deleted_flags_{ false };
 | 
					 | 
				
			||||||
		std::unique_ptr<std::vector<std::unique_ptr<detail::docker_interface>>> dockers_;
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct arg_mouse
 | 
						struct arg_mouse
 | 
				
			||||||
@ -427,12 +364,12 @@ namespace nana
 | 
				
			|||||||
		::nana::point pos;   ///< cursor position in the event window
 | 
							::nana::point pos;   ///< cursor position in the event window
 | 
				
			||||||
		::nana::mouse button;	///< indicates a button which triggers the event
 | 
							::nana::mouse button;	///< indicates a button which triggers the event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool left_button;	///< mouse left button is pressed?
 | 
							bool left_button;	///< true if mouse left button is pressed
 | 
				
			||||||
		bool mid_button;	///< mouse middle button is pressed?
 | 
							bool mid_button;	///< true if mouse middle button is pressed
 | 
				
			||||||
		bool right_button;	///< mouse right button is pressed?
 | 
							bool right_button;	///< true if mouse right button is pressed
 | 
				
			||||||
		bool alt;			///< keyboard alt is pressed?
 | 
							bool alt;			///< true if keyboard alt is pressed
 | 
				
			||||||
		bool shift;			///< keyboard Shift is pressed?
 | 
							bool shift;			///< true if keyboard Shift is pressed
 | 
				
			||||||
		bool ctrl;			///< keyboard Ctrl is pressed?
 | 
							bool ctrl;			///< true if keyboard Ctrl is pressed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// Checks if left button is operated,
 | 
							/// Checks if left button is operated,
 | 
				
			||||||
		bool is_left_button() const
 | 
							bool is_left_button() const
 | 
				
			||||||
@ -481,7 +418,7 @@ namespace nana
 | 
				
			|||||||
		event_code evt_code;	    ///< it is event_code::key_press in current event
 | 
							event_code evt_code;	    ///< it is event_code::key_press in current event
 | 
				
			||||||
		::nana::window window_handle;	///< A handle to the event window
 | 
							::nana::window window_handle;	///< A handle to the event window
 | 
				
			||||||
		mutable wchar_t key;	///< the key corresponding to the key pressed
 | 
							mutable wchar_t key;	///< the key corresponding to the key pressed
 | 
				
			||||||
		mutable bool ignore;	    ///< this member is not used
 | 
							mutable bool ignore;	    ///< this member is only available for key_char event, set 'true' to ignore the input.
 | 
				
			||||||
		bool ctrl;	                ///< keyboard Ctrl is pressed?
 | 
							bool ctrl;	                ///< keyboard Ctrl is pressed?
 | 
				
			||||||
		bool shift;	                ///< keyboard Shift is pressed
 | 
							bool shift;	                ///< keyboard Shift is pressed
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
				
			|||||||
@ -42,5 +42,112 @@ namespace nana
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		//end namespace events_operation
 | 
							//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_)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										for (auto p : *dockers_)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											detail::events_operation_cancel(reinterpret_cast<event_handle>(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<detail::docker_interface*>(evt) == *i)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												//Checks whether this event is working now.
 | 
				
			||||||
 | 
												if (emitting_count_ > 1)
 | 
				
			||||||
 | 
												{
 | 
				
			||||||
 | 
													static_cast<docker_base*>(*i)->flag_deleted = true;
 | 
				
			||||||
 | 
													deleted_flags_ = true;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
												else
 | 
				
			||||||
 | 
													dockers_->erase(i);
 | 
				
			||||||
 | 
												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<detail::docker_interface*>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									auto evt = reinterpret_cast<event_handle>(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<docker_base*>(*i)->flag_deleted)
 | 
				
			||||||
 | 
													i = evt_->dockers_->erase(i);
 | 
				
			||||||
 | 
												else
 | 
				
			||||||
 | 
													++i;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								//end class emit_counter
 | 
				
			||||||
 | 
							//end class event_base
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}//end namespace detail
 | 
						}//end namespace detail
 | 
				
			||||||
}//end namespace nana
 | 
					}//end namespace nana
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user