LogicComponent.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. //
  2. // Copyright (c) 2008-2020 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. #include "../Precompiled.h"
  23. #include "../IO/Log.h"
  24. #if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
  25. #include "../Physics/PhysicsEvents.h"
  26. #endif
  27. #include "../Scene/LogicComponent.h"
  28. #include "../Scene/Scene.h"
  29. #include "../Scene/SceneEvents.h"
  30. namespace Urho3D
  31. {
  32. LogicComponent::LogicComponent(Context* context) :
  33. Component(context),
  34. updateEventMask_(USE_UPDATE | USE_POSTUPDATE | USE_FIXEDUPDATE | USE_FIXEDPOSTUPDATE),
  35. currentEventMask_(0),
  36. delayedStartCalled_(false)
  37. {
  38. }
  39. LogicComponent::~LogicComponent() = default;
  40. void LogicComponent::OnSetEnabled()
  41. {
  42. UpdateEventSubscription();
  43. }
  44. void LogicComponent::Update(float timeStep)
  45. {
  46. }
  47. void LogicComponent::PostUpdate(float timeStep)
  48. {
  49. }
  50. void LogicComponent::FixedUpdate(float timeStep)
  51. {
  52. }
  53. void LogicComponent::FixedPostUpdate(float timeStep)
  54. {
  55. }
  56. void LogicComponent::SetUpdateEventMask(UpdateEventFlags mask)
  57. {
  58. if (updateEventMask_ != mask)
  59. {
  60. updateEventMask_ = mask;
  61. UpdateEventSubscription();
  62. }
  63. }
  64. void LogicComponent::OnNodeSet(Node* node)
  65. {
  66. if (node)
  67. {
  68. // Execute the user-defined start function
  69. Start();
  70. }
  71. else
  72. {
  73. // We are being detached from a node: execute user-defined stop function and prepare for destruction
  74. Stop();
  75. }
  76. }
  77. void LogicComponent::OnSceneSet(Scene* scene)
  78. {
  79. if (scene)
  80. UpdateEventSubscription();
  81. else
  82. {
  83. UnsubscribeFromEvent(E_SCENEUPDATE);
  84. UnsubscribeFromEvent(E_SCENEPOSTUPDATE);
  85. #if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
  86. UnsubscribeFromEvent(E_PHYSICSPRESTEP);
  87. UnsubscribeFromEvent(E_PHYSICSPOSTSTEP);
  88. #endif
  89. currentEventMask_ = USE_NO_EVENT;
  90. }
  91. }
  92. void LogicComponent::UpdateEventSubscription()
  93. {
  94. Scene* scene = GetScene();
  95. if (!scene)
  96. return;
  97. bool enabled = IsEnabledEffective();
  98. bool needUpdate = enabled && ((updateEventMask_ & USE_UPDATE) || !delayedStartCalled_);
  99. if (needUpdate && !(currentEventMask_ & USE_UPDATE))
  100. {
  101. SubscribeToEvent(scene, E_SCENEUPDATE, URHO3D_HANDLER(LogicComponent, HandleSceneUpdate));
  102. currentEventMask_ |= USE_UPDATE;
  103. }
  104. else if (!needUpdate && (currentEventMask_ & USE_UPDATE))
  105. {
  106. UnsubscribeFromEvent(scene, E_SCENEUPDATE);
  107. currentEventMask_ &= ~USE_UPDATE;
  108. }
  109. bool needPostUpdate = enabled && (updateEventMask_ & USE_POSTUPDATE);
  110. if (needPostUpdate && !(currentEventMask_ & USE_POSTUPDATE))
  111. {
  112. SubscribeToEvent(scene, E_SCENEPOSTUPDATE, URHO3D_HANDLER(LogicComponent, HandleScenePostUpdate));
  113. currentEventMask_ |= USE_POSTUPDATE;
  114. }
  115. else if (!needPostUpdate && (currentEventMask_ & USE_POSTUPDATE))
  116. {
  117. UnsubscribeFromEvent(scene, E_SCENEPOSTUPDATE);
  118. currentEventMask_ &= ~USE_POSTUPDATE;
  119. }
  120. #if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
  121. Component* world = GetFixedUpdateSource();
  122. if (!world)
  123. return;
  124. bool needFixedUpdate = enabled && (updateEventMask_ & USE_FIXEDUPDATE);
  125. if (needFixedUpdate && !(currentEventMask_ & USE_FIXEDUPDATE))
  126. {
  127. SubscribeToEvent(world, E_PHYSICSPRESTEP, URHO3D_HANDLER(LogicComponent, HandlePhysicsPreStep));
  128. currentEventMask_ |= USE_FIXEDUPDATE;
  129. }
  130. else if (!needFixedUpdate && (currentEventMask_ & USE_FIXEDUPDATE))
  131. {
  132. UnsubscribeFromEvent(world, E_PHYSICSPRESTEP);
  133. currentEventMask_ &= ~USE_FIXEDUPDATE;
  134. }
  135. bool needFixedPostUpdate = enabled && (updateEventMask_ & USE_FIXEDPOSTUPDATE);
  136. if (needFixedPostUpdate && !(currentEventMask_ & USE_FIXEDPOSTUPDATE))
  137. {
  138. SubscribeToEvent(world, E_PHYSICSPOSTSTEP, URHO3D_HANDLER(LogicComponent, HandlePhysicsPostStep));
  139. currentEventMask_ |= USE_FIXEDPOSTUPDATE;
  140. }
  141. else if (!needFixedPostUpdate && (currentEventMask_ & USE_FIXEDPOSTUPDATE))
  142. {
  143. UnsubscribeFromEvent(world, E_PHYSICSPOSTSTEP);
  144. currentEventMask_ &= ~USE_FIXEDPOSTUPDATE;
  145. }
  146. #endif
  147. }
  148. void LogicComponent::HandleSceneUpdate(StringHash eventType, VariantMap& eventData)
  149. {
  150. using namespace SceneUpdate;
  151. // Execute user-defined delayed start function before first update
  152. if (!delayedStartCalled_)
  153. {
  154. DelayedStart();
  155. delayedStartCalled_ = true;
  156. // If did not need actual update events, unsubscribe now
  157. if (!(updateEventMask_ & USE_UPDATE))
  158. {
  159. UnsubscribeFromEvent(GetScene(), E_SCENEUPDATE);
  160. currentEventMask_ &= ~USE_UPDATE;
  161. return;
  162. }
  163. }
  164. // Then execute user-defined update function
  165. Update(eventData[P_TIMESTEP].GetFloat());
  166. }
  167. void LogicComponent::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData)
  168. {
  169. using namespace ScenePostUpdate;
  170. // Execute user-defined post-update function
  171. PostUpdate(eventData[P_TIMESTEP].GetFloat());
  172. }
  173. #if defined(URHO3D_PHYSICS) || defined(URHO3D_URHO2D)
  174. void LogicComponent::HandlePhysicsPreStep(StringHash eventType, VariantMap& eventData)
  175. {
  176. using namespace PhysicsPreStep;
  177. // Execute user-defined delayed start function before first fixed update if not called yet
  178. if (!delayedStartCalled_)
  179. {
  180. DelayedStart();
  181. delayedStartCalled_ = true;
  182. }
  183. // Execute user-defined fixed update function
  184. FixedUpdate(eventData[P_TIMESTEP].GetFloat());
  185. }
  186. void LogicComponent::HandlePhysicsPostStep(StringHash eventType, VariantMap& eventData)
  187. {
  188. using namespace PhysicsPostStep;
  189. // Execute user-defined fixed post-update function
  190. FixedPostUpdate(eventData[P_TIMESTEP].GetFloat());
  191. }
  192. #endif
  193. }