Context.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. #include "Precompiled.h"
  24. #include "Context.h"
  25. #include "DebugNew.h"
  26. static String noType;
  27. void RemoveNamedAttribute(Vector<AttributeInfo>& attributes, const String& name)
  28. {
  29. for (unsigned i = 0; i < attributes.Size(); ++i)
  30. {
  31. if (attributes[i].name_ == name)
  32. {
  33. attributes.Erase(i);
  34. return;
  35. }
  36. }
  37. }
  38. Context::Context() :
  39. eventHandler_(0)
  40. {
  41. }
  42. Context::~Context()
  43. {
  44. // Release the subsystems before the event receiver maps are destroyed
  45. for (Map<ShortStringHash, SharedPtr<Object> >::Iterator i = subsystems_.Begin(); i != subsystems_.End(); ++i)
  46. i->second_.Reset();
  47. subsystems_.Clear();
  48. factories_.Clear();
  49. }
  50. SharedPtr<Object> Context::CreateObject(ShortStringHash objectType)
  51. {
  52. Map<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories_.Find(objectType);
  53. if (i != factories_.End())
  54. return i->second_->CreateObject();
  55. else
  56. return SharedPtr<Object>();
  57. }
  58. void Context::RegisterFactory(ObjectFactory* factory)
  59. {
  60. if (!factory)
  61. return;
  62. factories_[factory->GetType()] = factory;
  63. }
  64. void Context::RegisterSubsystem(Object* object)
  65. {
  66. if (!object)
  67. return;
  68. subsystems_[object->GetType()] = object;
  69. }
  70. void Context::RegisterAttribute(ShortStringHash objectType, const AttributeInfo& attr)
  71. {
  72. // None or Pointer types can not be supported
  73. if (attr.type_ == VAR_NONE || attr.type_ == VAR_PTR)
  74. return;
  75. attributes_[objectType].Push(attr);
  76. if (attr.mode_ & AM_NET)
  77. networkAttributes_[objectType].Push(attr);
  78. }
  79. void Context::RemoveAttribute(ShortStringHash objectType, const String& name)
  80. {
  81. Map<ShortStringHash, Vector<AttributeInfo> >::Iterator i = attributes_.Find(objectType);
  82. if (i != attributes_.End())
  83. RemoveNamedAttribute(i->second_, name);
  84. i = networkAttributes_.Find(objectType);
  85. if (i != networkAttributes_.End())
  86. RemoveNamedAttribute(i->second_, name);
  87. }
  88. void Context::CopyBaseAttributes(ShortStringHash baseType, ShortStringHash derivedType)
  89. {
  90. const Vector<AttributeInfo>* baseAttributes = GetAttributes(baseType);
  91. if (baseAttributes)
  92. attributes_[derivedType] = *baseAttributes;
  93. const Vector<AttributeInfo>* baseNetworkAttributes = GetNetworkAttributes(baseType);
  94. if (baseNetworkAttributes)
  95. networkAttributes_[derivedType] = *baseNetworkAttributes;
  96. }
  97. void Context::AddEventReceiver(Object* receiver, StringHash eventType)
  98. {
  99. PODVector<Object*>& receivers = eventReceivers_[eventType];
  100. for (PODVector<Object*>::ConstIterator j = receivers.Begin(); j != receivers.End(); ++j)
  101. {
  102. // Check if already registered
  103. if (*j == receiver)
  104. return;
  105. }
  106. receivers.Push(receiver);
  107. }
  108. void Context::AddEventReceiver(Object* receiver, Object* sender, StringHash eventType)
  109. {
  110. PODVector<Object*>& receivers = specificEventReceivers_[MakePair(sender, eventType)];
  111. for (PODVector<Object*>::ConstIterator j = receivers.Begin(); j != receivers.End(); ++j)
  112. {
  113. if (*j == receiver)
  114. return;
  115. }
  116. receivers.Push(receiver);
  117. }
  118. void Context::RemoveEventSender(Object* sender)
  119. {
  120. for (Map<Pair<Object*, StringHash>, PODVector<Object*> >::Iterator i = specificEventReceivers_.Begin();
  121. i != specificEventReceivers_.End();)
  122. {
  123. Map<Pair<Object*, StringHash>, PODVector<Object*> >::Iterator current = i++;
  124. if (current->first_.first_ == sender)
  125. {
  126. PODVector<Object*>& receivers = current->second_;
  127. for (PODVector<Object*>::Iterator j = receivers.Begin(); j != receivers.End(); ++j)
  128. {
  129. if (*j)
  130. (*j)->RemoveEventSender(sender);
  131. }
  132. specificEventReceivers_.Erase(current);
  133. }
  134. }
  135. }
  136. void Context::RemoveEventReceiver(Object* receiver, StringHash eventType)
  137. {
  138. PODVector<Object*>* group = GetReceivers(eventType);
  139. if (!group)
  140. return;
  141. for (PODVector<Object*>::Iterator i = group->Begin(); i != group->End(); ++i)
  142. {
  143. if (*i == receiver)
  144. {
  145. // If no event handling going on, can erase the receiver. Otherwise reset the pointer and clean up later
  146. if (eventSenders_.Empty())
  147. group->Erase(i);
  148. else
  149. {
  150. *i = 0;
  151. dirtyReceivers_.Insert(eventType);
  152. }
  153. return;
  154. }
  155. }
  156. }
  157. void Context::RemoveEventReceiver(Object* receiver, Object* sender, StringHash eventType)
  158. {
  159. PODVector<Object*>* group = GetReceivers(sender, eventType);
  160. if (!group)
  161. return;
  162. for (PODVector<Object*>::Iterator i = group->Begin(); i != group->End(); ++i)
  163. {
  164. if (*i == receiver)
  165. {
  166. if (eventSenders_.Empty())
  167. group->Erase(i);
  168. else
  169. {
  170. *i = 0;
  171. dirtySpecificReceivers_.Insert(MakePair(sender, eventType));
  172. }
  173. return;
  174. }
  175. }
  176. }
  177. Object* Context::GetSubsystem(ShortStringHash type) const
  178. {
  179. Map<ShortStringHash, SharedPtr<Object> >::ConstIterator i = subsystems_.Find(type);
  180. if (i != subsystems_.End())
  181. return i->second_;
  182. else
  183. return 0;
  184. }
  185. Object* Context::GetEventSender() const
  186. {
  187. if (!eventSenders_.Empty())
  188. return eventSenders_.Back();
  189. else
  190. return 0;
  191. }
  192. const String& Context::GetTypeName(ShortStringHash type) const
  193. {
  194. // Search factories to find the hash-to-name mapping
  195. Map<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories_.Find(type);
  196. return i != factories_.End() ? i->second_->GetTypeName() : noType;
  197. }