Context.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/HashSet.h"
  24. #include "../Core/Attribute.h"
  25. #include "../Core/Object.h"
  26. namespace Atomic
  27. {
  28. // ATOMIC BEGIN
  29. class GlobalEventListener
  30. {
  31. public:
  32. virtual void BeginSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData) = 0;
  33. virtual void EndSendEvent(Context* context, Object* sender, StringHash eventType, VariantMap& eventData) = 0;
  34. };
  35. // ATOMIC END
  36. /// Tracking structure for event receivers.
  37. class ATOMIC_API EventReceiverGroup : public RefCounted
  38. {
  39. ATOMIC_REFCOUNTED(EventReceiverGroup);
  40. public:
  41. /// Construct.
  42. EventReceiverGroup() :
  43. inSend_(0),
  44. dirty_(false)
  45. {
  46. }
  47. /// Begin event send. When receivers are removed during send, group has to be cleaned up afterward.
  48. void BeginSendEvent();
  49. /// End event send. Clean up if necessary.
  50. void EndSendEvent();
  51. /// Add receiver. Same receiver must not be double-added!
  52. void Add(Object* object);
  53. /// Remove receiver. Leave holes during send, which requires later cleanup.
  54. void Remove(Object* object);
  55. /// Receivers. May contain holes during sending.
  56. PODVector<Object*> receivers_;
  57. private:
  58. /// "In send" recursion counter.
  59. unsigned inSend_;
  60. /// Cleanup required flag.
  61. bool dirty_;
  62. };
  63. /// Urho3D execution context. Provides access to subsystems, object factories and attributes, and event receivers.
  64. class ATOMIC_API Context : public RefCounted
  65. {
  66. friend class Object;
  67. ATOMIC_REFCOUNTED(Context)
  68. public:
  69. /// Construct.
  70. Context();
  71. /// Destruct.
  72. ~Context();
  73. /// Create an object by type. Return pointer to it or null if no factory found.
  74. template <class T> inline SharedPtr<T> CreateObject()
  75. {
  76. return StaticCast<T>(CreateObject(T::GetTypeStatic()));
  77. }
  78. // ATOMIC BEGIN
  79. /// Create an object by type hash. Return pointer to it or null if no factory found.
  80. SharedPtr<Object> CreateObject(StringHash objectType, const XMLElement &source = XMLElement::EMPTY);
  81. // ATOMIC END
  82. /// Register a factory for an object type.
  83. void RegisterFactory(ObjectFactory* factory);
  84. /// Register a factory for an object type and specify the object category.
  85. void RegisterFactory(ObjectFactory* factory, const char* category);
  86. /// Register a subsystem.
  87. void RegisterSubsystem(Object* subsystem);
  88. /// Remove a subsystem.
  89. void RemoveSubsystem(StringHash objectType);
  90. /// Register object attribute.
  91. void RegisterAttribute(StringHash objectType, const AttributeInfo& attr);
  92. /// Remove object attribute.
  93. void RemoveAttribute(StringHash objectType, const char* name);
  94. /// Update object attribute's default value.
  95. void UpdateAttributeDefaultValue(StringHash objectType, const char* name, const Variant& defaultValue);
  96. /// Return a preallocated map for event data. Used for optimization to avoid constant re-allocation of event data maps.
  97. VariantMap& GetEventDataMap();
  98. /// Initialises the specified SDL systems, if not already. Returns true if successful. This call must be matched with ReleaseSDL() when SDL functions are no longer required, even if this call fails.
  99. bool RequireSDL(unsigned int sdlFlags);
  100. /// Indicate that you are done with using SDL. Must be called after using RequireSDL().
  101. void ReleaseSDL();
  102. #ifdef ATOMIC_IK
  103. /// Initialises the IK library, if not already. This call must be matched with ReleaseIK() when the IK library is no longer required.
  104. void RequireIK();
  105. /// Indicate that you are done with using the IK library.
  106. void ReleaseIK();
  107. #endif
  108. /// Copy base class attributes to derived class.
  109. void CopyBaseAttributes(StringHash baseType, StringHash derivedType);
  110. /// Template version of registering an object factory.
  111. template <class T> void RegisterFactory();
  112. /// Template version of registering an object factory with category.
  113. template <class T> void RegisterFactory(const char* category);
  114. /// Template version of removing a subsystem.
  115. template <class T> void RemoveSubsystem();
  116. /// Template version of registering an object attribute.
  117. template <class T> void RegisterAttribute(const AttributeInfo& attr);
  118. /// Template version of removing an object attribute.
  119. template <class T> void RemoveAttribute(const char* name);
  120. /// Template version of copying base class attributes to derived class.
  121. template <class T, class U> void CopyBaseAttributes();
  122. /// Template version of updating an object attribute's default value.
  123. template <class T> void UpdateAttributeDefaultValue(const char* name, const Variant& defaultValue);
  124. /// Return subsystem by type.
  125. Object* GetSubsystem(StringHash type) const;
  126. /// Return global variable based on key
  127. const Variant& GetGlobalVar(StringHash key) const ;
  128. /// Return all global variables.
  129. const VariantMap& GetGlobalVars() const { return globalVars_; }
  130. /// Set global variable with the respective key and value
  131. void SetGlobalVar(StringHash key, const Variant& value);
  132. /// Return all subsystems.
  133. const HashMap<StringHash, SharedPtr<Object> >& GetSubsystems() const { return subsystems_; }
  134. /// Return all object factories.
  135. const HashMap<StringHash, SharedPtr<ObjectFactory> >& GetObjectFactories() const { return factories_; }
  136. /// Return all object categories.
  137. const HashMap<String, Vector<StringHash> >& GetObjectCategories() const { return objectCategories_; }
  138. /// Return active event sender. Null outside event handling.
  139. Object* GetEventSender() const;
  140. /// Return active event handler. Set by Object. Null outside event handling.
  141. EventHandler* GetEventHandler() const { return eventHandler_; }
  142. /// Return object type name from hash, or empty if unknown.
  143. const String& GetTypeName(StringHash objectType) const;
  144. /// Return a specific attribute description for an object, or null if not found.
  145. AttributeInfo* GetAttribute(StringHash objectType, const char* name);
  146. /// Template version of returning a subsystem.
  147. template <class T> T* GetSubsystem() const;
  148. /// Template version of returning a specific attribute description.
  149. template <class T> AttributeInfo* GetAttribute(const char* name);
  150. /// Return attribute descriptions for an object type, or null if none defined.
  151. const Vector<AttributeInfo>* GetAttributes(StringHash type) const
  152. {
  153. HashMap<StringHash, Vector<AttributeInfo> >::ConstIterator i = attributes_.Find(type);
  154. return i != attributes_.End() ? &i->second_ : 0;
  155. }
  156. /// Return network replication attribute descriptions for an object type, or null if none defined.
  157. const Vector<AttributeInfo>* GetNetworkAttributes(StringHash type) const
  158. {
  159. HashMap<StringHash, Vector<AttributeInfo> >::ConstIterator i = networkAttributes_.Find(type);
  160. return i != networkAttributes_.End() ? &i->second_ : 0;
  161. }
  162. /// Return all registered attributes.
  163. const HashMap<StringHash, Vector<AttributeInfo> >& GetAllAttributes() const { return attributes_; }
  164. /// Return event receivers for a sender and event type, or null if they do not exist.
  165. EventReceiverGroup* GetEventReceivers(Object* sender, StringHash eventType)
  166. {
  167. HashMap<Object*, HashMap<StringHash, SharedPtr<EventReceiverGroup> > >::Iterator i = specificEventReceivers_.Find(sender);
  168. if (i != specificEventReceivers_.End())
  169. {
  170. HashMap<StringHash, SharedPtr<EventReceiverGroup> >::Iterator j = i->second_.Find(eventType);
  171. return j != i->second_.End() ? j->second_ : (EventReceiverGroup*)0;
  172. }
  173. else
  174. return 0;
  175. }
  176. /// Return event receivers for an event type, or null if they do not exist.
  177. EventReceiverGroup* GetEventReceivers(StringHash eventType)
  178. {
  179. HashMap<StringHash, SharedPtr<EventReceiverGroup> >::Iterator i = eventReceivers_.Find(eventType);
  180. return i != eventReceivers_.End() ? i->second_ : (EventReceiverGroup*)0;
  181. }
  182. // ATOMIC BEGIN
  183. /// Get whether an Editor Context
  184. bool GetEditorContext() { return editorContext_; }
  185. /// Get whether an Editor Context
  186. void SetEditorContext(bool editor) { editorContext_ = editor; }
  187. // hook for listening into events
  188. void AddGlobalEventListener(GlobalEventListener* listener) { globalEventListeners_.Push(listener); }
  189. void RemoveGlobalEventListener(GlobalEventListener* listener) { globalEventListeners_.Erase(globalEventListeners_.Find(listener)); }
  190. // ATOMIC END
  191. private:
  192. /// Add event receiver.
  193. void AddEventReceiver(Object* receiver, StringHash eventType);
  194. /// Add event receiver for specific event.
  195. void AddEventReceiver(Object* receiver, Object* sender, StringHash eventType);
  196. /// Remove an event sender from all receivers. Called on its destruction.
  197. void RemoveEventSender(Object* sender);
  198. /// Remove event receiver from specific events.
  199. void RemoveEventReceiver(Object* receiver, Object* sender, StringHash eventType);
  200. /// Remove event receiver from non-specific events.
  201. void RemoveEventReceiver(Object* receiver, StringHash eventType);
  202. /// Begin event send.
  203. void BeginSendEvent(Object* sender, StringHash eventType);
  204. /// End event send. Clean up event receivers removed in the meanwhile.
  205. void EndSendEvent();
  206. /// Set current event handler. Called by Object.
  207. void SetEventHandler(EventHandler* handler) { eventHandler_ = handler; }
  208. /// Object factories.
  209. HashMap<StringHash, SharedPtr<ObjectFactory> > factories_;
  210. /// Subsystems.
  211. HashMap<StringHash, SharedPtr<Object> > subsystems_;
  212. /// Attribute descriptions per object type.
  213. HashMap<StringHash, Vector<AttributeInfo> > attributes_;
  214. /// Network replication attribute descriptions per object type.
  215. HashMap<StringHash, Vector<AttributeInfo> > networkAttributes_;
  216. /// Event receivers for non-specific events.
  217. HashMap<StringHash, SharedPtr<EventReceiverGroup> > eventReceivers_;
  218. /// Event receivers for specific senders' events.
  219. HashMap<Object*, HashMap<StringHash, SharedPtr<EventReceiverGroup> > > specificEventReceivers_;
  220. /// Event sender stack.
  221. PODVector<Object*> eventSenders_;
  222. /// Event data stack.
  223. PODVector<VariantMap*> eventDataMaps_;
  224. /// Active event handler. Not stored in a stack for performance reasons; is needed only in esoteric cases.
  225. EventHandler* eventHandler_;
  226. /// Object categories.
  227. HashMap<String, Vector<StringHash> > objectCategories_;
  228. /// Variant map for global variables that can persist throughout application execution.
  229. VariantMap globalVars_;
  230. // ATOMIC BEGIN
  231. /// Begin event send.
  232. void GlobalBeginSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) {
  233. for (unsigned i = 0; i < globalEventListeners_.Size(); i++)
  234. globalEventListeners_[i]->BeginSendEvent(this, sender, eventType, eventData);
  235. eventSenders_.Push(sender);
  236. }
  237. /// End event send. Clean up event receivers removed in the meanwhile.
  238. void GlobalEndSendEvent(Object* sender, StringHash eventType, VariantMap& eventData) {
  239. for (unsigned i = 0; i < globalEventListeners_.Size(); i++)
  240. globalEventListeners_[i]->EndSendEvent(this, sender, eventType, eventData);
  241. eventSenders_.Pop();
  242. }
  243. PODVector<GlobalEventListener*> globalEventListeners_;
  244. bool editorContext_;
  245. // ATOMIC END
  246. };
  247. template <class T> void Context::RegisterFactory() { RegisterFactory(new ObjectFactoryImpl<T>(this)); }
  248. template <class T> void Context::RegisterFactory(const char* category)
  249. {
  250. RegisterFactory(new ObjectFactoryImpl<T>(this), category);
  251. }
  252. template <class T> void Context::RemoveSubsystem() { RemoveSubsystem(T::GetTypeStatic()); }
  253. template <class T> void Context::RegisterAttribute(const AttributeInfo& attr) { RegisterAttribute(T::GetTypeStatic(), attr); }
  254. template <class T> void Context::RemoveAttribute(const char* name) { RemoveAttribute(T::GetTypeStatic(), name); }
  255. template <class T, class U> void Context::CopyBaseAttributes() { CopyBaseAttributes(T::GetTypeStatic(), U::GetTypeStatic()); }
  256. template <class T> T* Context::GetSubsystem() const { return static_cast<T*>(GetSubsystem(T::GetTypeStatic())); }
  257. template <class T> AttributeInfo* Context::GetAttribute(const char* name) { return GetAttribute(T::GetTypeStatic(), name); }
  258. template <class T> void Context::UpdateAttributeDefaultValue(const char* name, const Variant& defaultValue)
  259. {
  260. UpdateAttributeDefaultValue(T::GetTypeStatic(), name, defaultValue);
  261. }
  262. }