资源的使用例子见: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_ */

286

被折叠的 条评论
为什么被折叠?



