| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- //
- // Urho3D Engine
- // Copyright (c) 2008-2011 Lasse Öörni
- //
- // 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.
- //
- #pragma once
- #include "SharedPtr.h"
- #include "Variant.h"
- class Context;
- class EventHandler;
- /// Base class for objects with type identification, subsystem access and event sending/receiving capability
- class Object : public RefCounted
- {
- public:
- /// Construct
- Object(Context* context);
- /// Destruct. Clean up self from event sender & receiver structures
- virtual ~Object();
-
- /// Return type
- virtual ShortStringHash GetType() const = 0;
- /// Return type name
- virtual const String& GetTypeName() const = 0;
- /// Handle event
- virtual void OnEvent(Object* sender, bool broadcast, StringHash eventType, VariantMap& eventData);
-
- /// Subscribe to an event that can be sent by any sender
- void SubscribeToEvent(StringHash eventType, EventHandler* handler);
- /// Subscribe to a specific sender's event
- void SubscribeToEvent(Object* sender, StringHash eventType, EventHandler* handler);
- /// Unsubscribe from an event
- void UnsubscribeFromEvent(StringHash eventType);
- /// Unsubscribe from a specific sender's event
- void UnsubscribeFromEvent(Object* sender, StringHash eventType);
- /// Unsubscribe from a specific sender's events
- void UnsubscribeFromEvents(Object* sender);
- /// Unsubscribe from all events
- void UnsubscribeFromAllEvents();
- /// Unsubscribe from all events with userdata defined in the handler
- void UnsubscribeFromAllEventsWithUserData();
- /// Send event to all subscribers
- void SendEvent(StringHash eventType);
- /// Send event with parameters to all subscribers
- void SendEvent(StringHash eventType, VariantMap& eventData);
- /// Send event to a specific receiver
- void SendEvent(Object* receiver, StringHash eventType);
- /// Send event with parameters to a specific receiver
- void SendEvent(Object* receiver, StringHash eventType, VariantMap& eventData);
- /// Template version of creating an object
- template <class T> SharedPtr<T> CreateObject();
-
- /// Return execution context
- Context* GetContext() const { return context_; }
- /// Return subsystem by type
- Object* GetSubsystem(ShortStringHash type) const;
- /// Return whether has subscribed to an event without specific sender
- bool HasSubscribedToEvent(StringHash eventType) const;
- /// Return whether has subscribed to a specific sender's event
- bool HasSubscribedToEvent(Object* sender, StringHash eventType) const;
- /// Return active event sender
- Object* GetSender() const;
- /// Template version of returning a subsystem
- template <class T> T* GetSubsystem() const;
-
- /// Remove event handlers related to a specific sender
- void RemoveEventSender(Object* sender);
-
- protected:
- /// Execution context
- Context* context_;
-
- private:
- /// Event handlers. Sender is null for non-specific handlers
- Map<Pair<Object*, StringHash>, SharedPtr<EventHandler> > eventHandlers_;
- };
- template <class T> SharedPtr<T> Object::CreateObject()
- {
- return StaticCast<T>(CreateObject(T::GetTypeStatic()));
- }
- template <class T> T* Object::GetSubsystem() const
- {
- return static_cast<T*>(GetSubsystem(T::GetTypeStatic()));
- }
- /// Object factory
- class ObjectFactory : public RefCounted
- {
- public:
- /// Construct
- ObjectFactory(Context* context) :
- context_(context)
- {
- }
-
- /// Create an object. Implemented in templated subclasses
- virtual SharedPtr<Object> CreateObject() = 0;
-
- /// Return execution context
- Context* GetContext() const { return context_; }
- /// Return type
- ShortStringHash GetType() const { return type_; }
- /// Return typename
- const String& GetTypeName() const { return typeName_; }
-
- protected:
- /// Execution context
- Context* context_;
- /// Object type
- ShortStringHash type_;
- /// Object typename
- String typeName_;
- };
- /// Template implementation of the object factory
- template <class T> class ObjectFactoryImpl : public ObjectFactory
- {
- public:
- /// Construct
- ObjectFactoryImpl(Context* context) :
- ObjectFactory(context)
- {
- type_ = T::GetTypeStatic();
- typeName_ = T::GetTypeNameStatic();
- }
-
- /// Create an object of the specific type
- virtual SharedPtr<Object>(CreateObject())
- {
- return SharedPtr<Object>(new T(context_));
- }
- };
- /// Internal helper class for invoking event handler functions
- class EventHandler : public RefCounted
- {
- public:
- /// Construct with specified receiver
- EventHandler(Object* receiver) :
- receiver_(receiver),
- userData_(0)
- {
- }
-
- /// Construct with specified receiver and userdata
- EventHandler(Object* receiver, void* userData) :
- receiver_(receiver),
- userData_(userData)
- {
- }
-
- /// Destruct
- virtual ~EventHandler() {}
-
- /// Invoke event handler function
- virtual void Invoke(StringHash eventType, VariantMap& eventData) = 0;
-
- /// Return event receiver
- Object* GetReceiver() const { return receiver_; }
- /// Return userdata
- void* GetUserData() const { return userData_; }
-
- protected:
- /// Event receiver
- Object* receiver_;
- /// Userdata
- void* userData_;
- };
- /// Template implementation of the event handler invoke helper (stores a function pointer of specific class)
- template <class T> class EventHandlerImpl : public EventHandler
- {
- public:
- typedef void (T::*HandlerFunctionPtr)(StringHash, VariantMap&);
-
- /// Construct with receiver and function pointers
- EventHandlerImpl(T* receiver, HandlerFunctionPtr function) :
- EventHandler(receiver),
- function_(function)
- {
- }
-
- /// Construct with receiver and function pointers and userdata
- EventHandlerImpl(T* receiver, HandlerFunctionPtr function, void* userData) :
- EventHandler(receiver, userData),
- function_(function)
- {
- }
-
- /// Invoke event handler function
- virtual void Invoke(StringHash eventType, VariantMap& eventData)
- {
- T* receiver = static_cast<T*>(receiver_);
- (receiver->*function_)(eventType, eventData);
- }
-
- private:
- /// Class-specific pointer to handler function
- HandlerFunctionPtr function_;
- };
- #define OBJECT(typeName) \
- private: \
- static const ShortStringHash typeStatic; \
- static const String typeNameStatic; \
- public: \
- virtual ShortStringHash GetType() const { return GetTypeStatic(); } \
- virtual const String& GetTypeName() const { return GetTypeNameStatic(); } \
- static ShortStringHash GetTypeStatic() \
- { \
- return typeStatic; \
- } \
- static const String& GetTypeNameStatic() \
- { \
- return typeNameStatic; \
- } \
- #define OBJECTTYPESTATIC(typeName) \
- const ShortStringHash typeName::typeStatic(#typeName); \
- const String typeName::typeNameStatic(#typeName); \
- #define EVENT(eventID, eventName) static const StringHash eventID(#eventName); namespace eventName
- #define PARAM(paraid_, paraname_) static const ShortStringHash paraid_(#paraname_)
- #define HANDLER(className, function) (new EventHandlerImpl<className>(this, &className::function))
- #define HANDLER_USERDATA(className, function, userData) (new EventHandlerImpl<className>(this, &className::function, userData))
|