Object.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #pragma once
  24. #include "SharedPtr.h"
  25. #include "Variant.h"
  26. class Context;
  27. class EventHandler;
  28. /// Base class for objects with type identification, subsystem access and event sending/receiving capability
  29. class Object : public RefCounted
  30. {
  31. public:
  32. /// Construct
  33. Object(Context* context);
  34. /// Destruct. Clean up self from event sender & receiver structures
  35. virtual ~Object();
  36. /// Return type
  37. virtual ShortStringHash GetType() const = 0;
  38. /// Return type name
  39. virtual const String& GetTypeName() const = 0;
  40. /// Handle event
  41. virtual void OnEvent(Object* sender, bool broadcast, StringHash eventType, VariantMap& eventData);
  42. /// Subscribe to an event that can be sent by any sender
  43. void SubscribeToEvent(StringHash eventType, EventHandler* handler);
  44. /// Subscribe to a specific sender's event
  45. void SubscribeToEvent(Object* sender, StringHash eventType, EventHandler* handler);
  46. /// Unsubscribe from an event
  47. void UnsubscribeFromEvent(StringHash eventType);
  48. /// Unsubscribe from a specific sender's event
  49. void UnsubscribeFromEvent(Object* sender, StringHash eventType);
  50. /// Unsubscribe from a specific sender's events
  51. void UnsubscribeFromEvents(Object* sender);
  52. /// Unsubscribe from all events
  53. void UnsubscribeFromAllEvents();
  54. /// Unsubscribe from all events with userdata defined in the handler
  55. void UnsubscribeFromAllEventsWithUserData();
  56. /// Send event to all subscribers
  57. void SendEvent(StringHash eventType);
  58. /// Send event with parameters to all subscribers
  59. void SendEvent(StringHash eventType, VariantMap& eventData);
  60. /// Send event to a specific receiver
  61. void SendEvent(Object* receiver, StringHash eventType);
  62. /// Send event with parameters to a specific receiver
  63. void SendEvent(Object* receiver, StringHash eventType, VariantMap& eventData);
  64. /// Template version of creating an object
  65. template <class T> SharedPtr<T> CreateObject();
  66. /// Return execution context
  67. Context* GetContext() const { return context_; }
  68. /// Return subsystem by type
  69. Object* GetSubsystem(ShortStringHash type) const;
  70. /// Return whether has subscribed to an event without specific sender
  71. bool HasSubscribedToEvent(StringHash eventType) const;
  72. /// Return whether has subscribed to a specific sender's event
  73. bool HasSubscribedToEvent(Object* sender, StringHash eventType) const;
  74. /// Return active event sender
  75. Object* GetSender() const;
  76. /// Template version of returning a subsystem
  77. template <class T> T* GetSubsystem() const;
  78. /// Remove event handlers related to a specific sender
  79. void RemoveEventSender(Object* sender);
  80. protected:
  81. /// Execution context
  82. Context* context_;
  83. private:
  84. /// Event handlers. Sender is null for non-specific handlers
  85. Map<Pair<Object*, StringHash>, SharedPtr<EventHandler> > eventHandlers_;
  86. };
  87. template <class T> SharedPtr<T> Object::CreateObject()
  88. {
  89. return StaticCast<T>(CreateObject(T::GetTypeStatic()));
  90. }
  91. template <class T> T* Object::GetSubsystem() const
  92. {
  93. return static_cast<T*>(GetSubsystem(T::GetTypeStatic()));
  94. }
  95. /// Object factory
  96. class ObjectFactory : public RefCounted
  97. {
  98. public:
  99. /// Construct
  100. ObjectFactory(Context* context) :
  101. context_(context)
  102. {
  103. }
  104. /// Create an object. Implemented in templated subclasses
  105. virtual SharedPtr<Object> CreateObject() = 0;
  106. /// Return execution context
  107. Context* GetContext() const { return context_; }
  108. /// Return type
  109. ShortStringHash GetType() const { return type_; }
  110. /// Return typename
  111. const String& GetTypeName() const { return typeName_; }
  112. protected:
  113. /// Execution context
  114. Context* context_;
  115. /// Object type
  116. ShortStringHash type_;
  117. /// Object typename
  118. String typeName_;
  119. };
  120. /// Template implementation of the object factory
  121. template <class T> class ObjectFactoryImpl : public ObjectFactory
  122. {
  123. public:
  124. /// Construct
  125. ObjectFactoryImpl(Context* context) :
  126. ObjectFactory(context)
  127. {
  128. type_ = T::GetTypeStatic();
  129. typeName_ = T::GetTypeNameStatic();
  130. }
  131. /// Create an object of the specific type
  132. virtual SharedPtr<Object>(CreateObject())
  133. {
  134. return SharedPtr<Object>(new T(context_));
  135. }
  136. };
  137. /// Internal helper class for invoking event handler functions
  138. class EventHandler : public RefCounted
  139. {
  140. public:
  141. /// Construct with specified receiver
  142. EventHandler(Object* receiver) :
  143. receiver_(receiver),
  144. userData_(0)
  145. {
  146. }
  147. /// Construct with specified receiver and userdata
  148. EventHandler(Object* receiver, void* userData) :
  149. receiver_(receiver),
  150. userData_(userData)
  151. {
  152. }
  153. /// Destruct
  154. virtual ~EventHandler() {}
  155. /// Invoke event handler function
  156. virtual void Invoke(StringHash eventType, VariantMap& eventData) = 0;
  157. /// Return event receiver
  158. Object* GetReceiver() const { return receiver_; }
  159. /// Return userdata
  160. void* GetUserData() const { return userData_; }
  161. protected:
  162. /// Event receiver
  163. Object* receiver_;
  164. /// Userdata
  165. void* userData_;
  166. };
  167. /// Template implementation of the event handler invoke helper (stores a function pointer of specific class)
  168. template <class T> class EventHandlerImpl : public EventHandler
  169. {
  170. public:
  171. typedef void (T::*HandlerFunctionPtr)(StringHash, VariantMap&);
  172. /// Construct with receiver and function pointers
  173. EventHandlerImpl(T* receiver, HandlerFunctionPtr function) :
  174. EventHandler(receiver),
  175. function_(function)
  176. {
  177. }
  178. /// Construct with receiver and function pointers and userdata
  179. EventHandlerImpl(T* receiver, HandlerFunctionPtr function, void* userData) :
  180. EventHandler(receiver, userData),
  181. function_(function)
  182. {
  183. }
  184. /// Invoke event handler function
  185. virtual void Invoke(StringHash eventType, VariantMap& eventData)
  186. {
  187. T* receiver = static_cast<T*>(receiver_);
  188. (receiver->*function_)(eventType, eventData);
  189. }
  190. private:
  191. /// Class-specific pointer to handler function
  192. HandlerFunctionPtr function_;
  193. };
  194. #define OBJECT(typeName) \
  195. private: \
  196. static const ShortStringHash typeStatic; \
  197. static const String typeNameStatic; \
  198. public: \
  199. virtual ShortStringHash GetType() const { return GetTypeStatic(); } \
  200. virtual const String& GetTypeName() const { return GetTypeNameStatic(); } \
  201. static ShortStringHash GetTypeStatic() \
  202. { \
  203. return typeStatic; \
  204. } \
  205. static const String& GetTypeNameStatic() \
  206. { \
  207. return typeNameStatic; \
  208. } \
  209. #define OBJECTTYPESTATIC(typeName) \
  210. const ShortStringHash typeName::typeStatic(#typeName); \
  211. const String typeName::typeNameStatic(#typeName); \
  212. #define EVENT(eventID, eventName) static const StringHash eventID(#eventName); namespace eventName
  213. #define PARAM(paraid_, paraname_) static const ShortStringHash paraid_(#paraname_)
  214. #define HANDLER(className, function) (new EventHandlerImpl<className>(this, &className::function))
  215. #define HANDLER_USERDATA(className, function, userData) (new EventHandlerImpl<className>(this, &className::function, userData))