EventBus资源

资源的使用例子见:https://blog.csdn.net/Mason___/article/details/157769142?spm=1001.2014.3001.5501

EventBus资源如下:

Event.hpp

/*
 * Copyright (c) 2014, Dan Quist
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef _SRC_EVENT_EVENT_HPP_
#define _SRC_EVENT_EVENT_HPP_

#include "Object.hpp"

#include <typeindex>
#include <typeinfo>
#include <vector>
#include <stdexcept>

namespace EvBus {
	/**
	 * \brief The base event class, all events inherit from this class
	 */
	class Event : public Object
	{
	public:
		/**
		 * \brief Default constructor
		 *
		 * @param typeIndex The type ID of the inherited class
		 * @param sender The sender of the event
		 */
		Event(Object& sender) :
			sender(sender),
			canceled(false) {
		}

        /**
		 * \brief Empty virtual destructor
		 */
		virtual ~Event() { }


		/**
		 * \brief Gets the source object for this event
		 *
		 * @return The event sender
		 */
		Object& getSender() {
			return sender;
		}


		/**
		 * \brief Gets whether the event has been canceled
		 *
		 * @return true if the event is canceled
		 */
		bool getCanceled() {
			return canceled;
		}

        /**
		 * \brief Sets the canceled status for the event
		 *
		 * @param canceled Whether the even is canceled or not
		 */
		void setCanceled(bool canceled) {
			this->canceled = canceled;
		}

	private:
		Object& sender;
		bool canceled;

	};
} // end of namespace EvBus
#endif /* _SRC_EVENT_EVENT_HPP_ */

EventBus.cpp

/*
 * Copyright (c) 2014, Dan Quist
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "EventBus.hpp"

// Declare the static instance since this can't be done in the header file
namespace EvBus {
    EventBus* EventBus::instance = nullptr;
} // end of namespace EvBus

EventBus.hpp

/*
 * Copyright (c) 2014, Dan Quist
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef _SRC_EVENT_EVENT_BUS_HPP_
#define _SRC_EVENT_EVENT_BUS_HPP_

#include "Object.hpp"
#include "EventHandler.hpp"
#include "Event.hpp"
#include "HandlerRegistration.hpp"

#include <list>
#include <typeinfo>
#include <unordered_map>

namespace EvBus {
	/**
	 * \brief An Event system that allows decoupling of code through synchronous events
	 *
	 */
	class EventBus : public Object {
	public:
		/**
		 * \brief Default empty constructor
		 */
		EventBus() { }


		/**
		 * \brief Empty virtual destructor
		 */
		virtual ~EventBus() { }

        /**
		 * \brief Returns the EventBus singleton instance
		 *
		 * Creates a new instance of the EventBus if hasn't already been created
		 *
		 * @return The singleton instance
		 */
		static EventBus* const GetInstance() {
			if (instance == nullptr) {
				instance = new EventBus();
			}

			return instance;
		}

        /**
		 * \brief Registers a new event handler to the EventBus with a source specifier
		 *
		 * The template parameter is the specific type of event that is being added. Since a class can
		 * potentially inherit multiple event handlers, the template specifier will remove any ambiguity
		 * as to which handler pointer is being referenced.
		 *
		 * @param handler The event handler class
		 * @param sender The source sender object
		 * @return An EventRegistration pointer which can be used to unregister the event handler
		 */
		template <class T>
		static HandlerRegistration* const AddHandler(EventHandler<T>& handler, Object& sender) {
			EventBus* instance = GetInstance();

			// Fetch the list of event pairs unique to this event type
			Registrations* registrations = instance->handlers[typeid(T)];

			// Create a new collection instance for this type if it hasn't been created yet
			if (registrations == nullptr) {
				registrations = new Registrations();
				instance->handlers[typeid(T)] = registrations;
			}

			// Create a new EventPair instance for this registration.
			// This will group the handler, sender, and registration object into the same class
			EventRegistration* registration = new EventRegistration(static_cast<void*>(&handler), registrations, &sender);

            // Add the registration object to the collection
			registrations->push_back(registration);

			return registration;
		}

        /**
		 * \brief Registers a new event handler to the EventBus with no source specified
		 *
		 * @param handler The event handler class
		 * @return An EventRegistration pointer which can be used to unregister the event handler
		 */
		template <class T>
		static HandlerRegistration* const AddHandler(EventHandler<T>& handler) {
			EventBus* instance = GetInstance();

			// Fetch the list of event pairs unique to this event type
			Registrations* registrations = instance->handlers[typeid(T)];

			// Create a new collection instance for this type if it hasn't been created yet
			if (registrations == nullptr) {
				registrations = new Registrations();
				instance->handlers[typeid(T)] = registrations;
			}

            // Create a new EventPair instance for this registration.
			// This will group the handler, sender, and registration object into the same class
			EventRegistration* registration = new EventRegistration(static_cast<void*>(&handler), registrations, nullptr);

			// Add the registration object to the collection
			registrations->push_back(registration);

			return registration;
		}

        /**
		 * \brief Fires an event
		 *
		 * @param e The event to fire
		 */
		static void FireEvent(Event& e) {
			EventBus* instance = GetInstance();

			Registrations* registrations = instance->handlers[typeid(e)];

			// If the registrations list is null, then no handlers have been registered for this event
			if (registrations == nullptr) {
				return;
			}

			// Iterate through all the registered handlers and dispatch to each one if the sender
			// matches the source or if the sender is not specified
			for (auto& reg : *registrations) {
				if ((reg->getSender() == nullptr) || (reg->getSender() == &e.getSender())) {

					// This is where some magic happens. The void * handler is statically cast to an event handler
					// of generic type Event and dispatched. The dispatch function will then do a dynamic
					// cast to the correct event type so the matching onEvent method can be called
					static_cast<EventHandler<Event>*>(reg->getHandler())->dispatch(e);
				}
			}
		}

    private:
		// Singleton class instance
		static EventBus* instance;


		/**
		 * \brief Registration class private to EventBus for registered event handlers
		 */
		class EventRegistration : public HandlerRegistration
		{
		public:
			typedef std::list<EventRegistration*> Registrations;


			/**
			 * \brief Represents a registration object for a registered event handler
			 *
			 * This object is stored in a collection with other handlers for the event type.
			 *
			 * @param handler The event handler
			 * @param registrations The handler collection for this event type
			 * @param sender The registered sender object
			 */
			EventRegistration(void* const handler, Registrations* const registrations, Object* const sender) :
				handler(handler),
				registrations(registrations),
				sender(sender),
				registered(true)
			{ }

            /**
			 * \brief Empty virtual destructor
			 */
			virtual ~EventRegistration() { }


			/**
			 * \brief Gets the event handler for this registration
			 *
			 * @return The event handler
			 */
			void* const getHandler() {
				return handler;
			}


			/**
			 * \brief Gets the sender object for this registration
			 *
			 * @return The registered sender object
			 */
			Object* const getSender() {
				return sender;
			}

            /**
			 * \brief Removes an event handler from the registration collection
			 *
			 * The event handler will no longer receive events for this event type
			 */
			virtual void removeHandler() {
				if (registered) {
					registrations->remove(this);
					registered = false;
				}
			}

		private:
			void* const handler;
			Registrations* const registrations;
			Object* const sender;

			bool registered;
		};

		typedef std::list<EventRegistration*> Registrations;
		typedef std::unordered_map<std::type_index, std::list<EventRegistration*>*> TypeMap;

		TypeMap handlers;

	};
} // end of namespace EvBus
#endif /* _SRC_EVENT_EVENT_BUS_HPP_ */
		

EventHandler.hpp

/*
 * Copyright (c) 2014, Dan Quist
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef _SRC_EVENT_EVENT_HANDLER_HPP_
#define _SRC_EVENT_EVENT_HANDLER_HPP_

#include "Object.hpp"

#include <typeinfo>
#include <type_traits>
namespace EvBus {
	// Forward declare the Event class
	class Event;

    /**
	 * \brief Base class of all classes that listen for events
	 *
	 * For a class to be an event listener, it needs to inherit from EventHandler
	 * with the specific event type as the template parameter. A class can inherit from
	 * multiple EventHandler base classes each using a different template parameter.
	 */
	template <class T>
	class EventHandler {
	public:

		/**
		 * \brief Default constructor that enforces the template type
		 */
		EventHandler() {
			// An error here indicates you're trying to implement EventHandler with a type that is not derived from Event
			static_assert(std::is_base_of<Event, T>::value, "EventHandler<T>: T must be a class derived from Event");
		}

        /**
		 * \brief Empty virtual destructor
		 */
		virtual ~EventHandler() { }


		/**
		 * \brief Pure virtual method for implementing the body of the listener
		 *
		 * @param The event instance
		 */
		virtual void onEvent(T&) = 0;


		/**
		 * \brief Dispatches a generic event to the appropriate listener method
		 *
		 * This method is called by the EventBus and dispatches to the correct method by
		 * dynamic casting the event parameter to the template type for this handler.
		 *
		 * @param e The event to dispatch
		 */
		void dispatch(Event& e) {
			onEvent(dynamic_cast<T&>(e));
		}
	};
} // end of namespace EvBus
#endif /* _SRC_EVENT_EVENT_HANDLER_HPP_ */

HandlerRegistration.hpp

/*
 * Copyright (c) 2014, Dan Quist
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef _SRC_EVENT_HANDLER_REGISTRATION_HPP_
#define _SRC_EVENT_HANDLER_REGISTRATION_HPP_

#include "Object.hpp"

namespace EvBus {
	/**
	 * \brief Interface that that allows event handlers to be removed from the EventBus
	 */
	class HandlerRegistration : public Object {
	public:
		virtual ~HandlerRegistration() { }

		virtual void removeHandler() = 0;
	};
} // end of namespace EvBus
#endif /* _SRC_EVENT_HANDLER_REGISTRATION_HPP_ */ 

Object.hpp

/*
 * Copyright (c) 2014, Dan Quist
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#ifndef _SRC_EVENT_OBJECT_HPP_
#define _SRC_EVENT_OBJECT_HPP_

namespace EvBus {
	/**
	 * \brief Root class of the type hierarchy
	 *
	 * All events and event handlers derive from this class
	 */
	class Object {
	public:
		/**
		 * \brief Default empty constructor
		 */
		Object() { }


		/**
		 * Empty virtual destructor
		 */
		virtual ~Object() {	}


		/**
		 * Default empty copy constructor
		 * @param other The instance to copy from
		 */
		Object(const Object& other) { }
	};
} // end of namespace EvBus
#endif /* _SRC_EVENT_OBJECT_HPP_ */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值