Object.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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 char* GetTypeName() const = 0;
  40. /// Handle event
  41. virtual void OnEvent(Object* sender, bool broadcast, StringHash eventType, VariantMap& eventData);
  42. /// Create object by type
  43. SharedPtr<Object> CreateObject(ShortStringHash type);
  44. /// Subscribe to an event that can be sent by any sender
  45. void SubscribeToEvent(StringHash eventType, EventHandler* handler);
  46. /// Subscribe to a specific sender's event
  47. void SubscribeToEvent(Object* sender, StringHash eventType, EventHandler* handler);
  48. /// Unsubscribe from an event
  49. void UnsubscribeFromEvent(StringHash eventType);
  50. /// Unsubscribe from a specific sender's event
  51. void UnsubscribeFromEvent(Object* sender, StringHash eventType);
  52. /// Unsubscribe from a specific sender's events
  53. void UnsubscribeFromEvents(Object* sender);
  54. /// Unsubscribe from all events
  55. void UnsubscribeFromAllEvents();
  56. /// Unsubscribe from all events with userdata defined in the handler (possibly scripted)
  57. void UnsubscribeFromAllEventsWithUserData();
  58. /// Send event to all subscribers
  59. void SendEvent(StringHash eventType);
  60. /// Send event with parameters to all subscribers
  61. void SendEvent(StringHash eventType, VariantMap& eventData);
  62. /// Send event to a specific receiver
  63. void SendEvent(Object* receiver, StringHash eventType);
  64. /// Send event with parameters to a specific receiver
  65. void SendEvent(Object* receiver, StringHash eventType, VariantMap& eventData);
  66. /// Template version of creating an object
  67. template <class T> SharedPtr<T> CreateObject();
  68. /// Return typename as std::string
  69. std::string GetTypeNameStr() const { return std::string(GetTypeName()); }
  70. /// Return execution context
  71. Context* GetContext() const { return context_; }
  72. /// Return subsystem by type
  73. Object* GetSubsystem(ShortStringHash type) const;
  74. /// Return whether has subscribed to an event without specific sender
  75. bool HasSubscribed(StringHash eventType) const;
  76. /// Return whether has subscribed to a specific sender's event
  77. bool HasSubscribed(Object* sender, StringHash eventType) const;
  78. /// Return active event sender
  79. Object* GetSender() const;
  80. /// Template version of returning a subsystem
  81. template <class T> T* GetSubsystem() const;
  82. /// Remove event handlers related to a specific sender
  83. void RemoveEventSender(Object* sender);
  84. protected:
  85. /// Execution context
  86. Context* context_;
  87. private:
  88. /// Event handlers. Sender is null for non-specific handlers
  89. std::map<std::pair<Object*, StringHash>, EventHandler*> eventHandlers_;
  90. };
  91. template <class T> SharedPtr<T> Object::CreateObject()
  92. {
  93. return StaticCast<T>(CreateObject(T::GetTypeStatic()));
  94. }
  95. template <class T> T* Object::GetSubsystem() const
  96. {
  97. return static_cast<T*>(GetSubsystem(T::GetTypeStatic()));
  98. }
  99. /// Object factory
  100. class ObjectFactory : public RefCounted
  101. {
  102. public:
  103. /// Construct
  104. ObjectFactory(Context* context) :
  105. context_(context)
  106. {
  107. }
  108. /// Create an object. Implemented in templated subclasses
  109. virtual SharedPtr<Object> CreateObject() = 0;
  110. /// Return execution context
  111. Context* GetContext() const { return context_; }
  112. /// Return type
  113. ShortStringHash GetType() const { return type_; }
  114. /// Return typename
  115. const char* GetTypeName() const { return typeName_; }
  116. /// Return typename as std::string
  117. std::string GetTypeNameStr() const { return std::string(typeName_); }
  118. protected:
  119. /// Execution context
  120. Context* context_;
  121. /// Object type
  122. ShortStringHash type_;
  123. /// Object typename
  124. const char* typeName_;
  125. };
  126. /// Template implementation of the object factory
  127. template <class T> class ObjectFactoryImpl : public ObjectFactory
  128. {
  129. public:
  130. /// Construct
  131. ObjectFactoryImpl(Context* context) :
  132. ObjectFactory(context)
  133. {
  134. type_ = T::GetTypeStatic();
  135. typeName_ = T::GetTypeNameStatic();
  136. }
  137. /// Create an object of the specific type
  138. virtual SharedPtr<Object>(CreateObject())
  139. {
  140. return SharedPtr<Object>(new T(context_));
  141. }
  142. };
  143. /// Internal helper class for invoking event handler functions
  144. class EventHandler
  145. {
  146. public:
  147. /// Construct with specified receiver
  148. EventHandler(Object* receiver) :
  149. receiver_(receiver),
  150. userData_(0)
  151. {
  152. }
  153. /// Construct with specified receiver and userdata
  154. EventHandler(Object* receiver, void* userData) :
  155. receiver_(receiver),
  156. userData_(userData)
  157. {
  158. }
  159. /// Destruct
  160. virtual ~EventHandler() {}
  161. /// Invoke event handler function
  162. virtual void Invoke(StringHash eventType, VariantMap& eventData) = 0;
  163. /// Return event receiver
  164. Object* GetReceiver() const { return receiver_; }
  165. /// Return userdata
  166. void* GetUserData() const { return userData_; }
  167. protected:
  168. /// Event receiver
  169. Object* receiver_;
  170. /// Userdata
  171. void* userData_;
  172. };
  173. /// Template implementation of the event handler (stores a function pointer of specific class)
  174. template <class T> class EventHandlerImpl : public EventHandler
  175. {
  176. public:
  177. typedef void (T::*HandlerFunctionPtr)(StringHash, VariantMap&);
  178. /// Construct with receiver and function pointers
  179. EventHandlerImpl(T* receiver, HandlerFunctionPtr function) :
  180. EventHandler(receiver),
  181. function_(function)
  182. {
  183. }
  184. /// Construct with receiver and function pointers and userdata
  185. EventHandlerImpl(T* receiver, HandlerFunctionPtr function, void* userData) :
  186. EventHandler(receiver, userData),
  187. function_(function)
  188. {
  189. }
  190. /// Invoke event handler function
  191. virtual void Invoke(StringHash eventType, VariantMap& eventData)
  192. {
  193. T* receiver = static_cast<T*>(receiver_);
  194. (receiver->*function_)(eventType, eventData);
  195. }
  196. private:
  197. /// Class-specific pointer to handler function
  198. HandlerFunctionPtr function_;
  199. };
  200. #define OBJECT(typeName) \
  201. private: \
  202. static const ShortStringHash typeStatic; \
  203. static const char* typeNameStatic; \
  204. public: \
  205. virtual ShortStringHash GetType() const { return GetTypeStatic(); } \
  206. virtual const char* GetTypeName() const { return GetTypeNameStatic(); } \
  207. static ShortStringHash GetTypeStatic() \
  208. { \
  209. return typeStatic; \
  210. } \
  211. static const char* GetTypeNameStatic() \
  212. { \
  213. return typeNameStatic; \
  214. } \
  215. #define OBJECTTYPESTATIC(typeName) \
  216. const ShortStringHash typeName::typeStatic(#typeName); \
  217. const char* typeName::typeNameStatic = #typeName; \
  218. #define EVENT(eventID, eventName) static const StringHash eventID(#eventName); namespace eventName
  219. #define PARAM(paraid_, paraname_) static const ShortStringHash paraid_(#paraname_)
  220. #define HANDLER(className, function) (new EventHandlerImpl<className>(this, &className::function))
  221. #define HANDLER_USERDATA(className, function, userData) (new EventHandlerImpl<className>(this, &className::function, userData))