LogicComponent.cpp 6.0 KB

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