BsPlayInEditorManager.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsPlayInEditorManager.h"
  4. #include "BsScriptGameObjectManager.h"
  5. #include "Utility/BsTime.h"
  6. #include "Scene/BsSceneManager.h"
  7. #include "Scene/BsSceneObject.h"
  8. #include "BsApplication.h"
  9. #include "Physics/BsPhysics.h"
  10. #include "Audio/BsAudio.h"
  11. #include "Animation/BsAnimationManager.h"
  12. namespace bs
  13. {
  14. PlayInEditorManager::PlayInEditorManager()
  15. :mState(PlayInEditorState::Stopped), mNextState(PlayInEditorState::Stopped),
  16. mFrameStepActive(false), mScheduledStateChange(false), mPausableTime(0.0f)
  17. {
  18. if (!gApplication().isEditor())
  19. mState = PlayInEditorState::Playing;
  20. else
  21. {
  22. setSystemsPauseState(true);
  23. gSceneManager().setComponentState(ComponentState::Stopped);
  24. }
  25. }
  26. void PlayInEditorManager::setState(PlayInEditorState state)
  27. {
  28. if (!gApplication().isEditor())
  29. return;
  30. // Delay state change to next frame as this method could be called in middle of object update, in which case
  31. // part of the objects before this call would receive different state than other objects.
  32. mScheduledStateChange = true;
  33. mNextState = state;
  34. }
  35. void PlayInEditorManager::setStateImmediate(PlayInEditorState state)
  36. {
  37. if (mState == state)
  38. return;
  39. PlayInEditorState oldState = mState;
  40. mState = state;
  41. switch (state)
  42. {
  43. case PlayInEditorState::Stopped:
  44. {
  45. mFrameStepActive = false;
  46. mPausableTime = 0.0f;
  47. setSystemsPauseState(true);
  48. gSceneManager().setComponentState(ComponentState::Stopped);
  49. mSavedScene->_instantiate();
  50. gSceneManager().setRootNode(mSavedScene);
  51. mSavedScene = nullptr;
  52. }
  53. break;
  54. case PlayInEditorState::Playing:
  55. {
  56. if (oldState == PlayInEditorState::Stopped)
  57. saveSceneInMemory();
  58. gSceneManager().setComponentState(ComponentState::Running);
  59. setSystemsPauseState(false);
  60. gAnimation().setPaused(false);
  61. }
  62. break;
  63. case PlayInEditorState::Paused:
  64. {
  65. mFrameStepActive = false;
  66. setSystemsPauseState(true);
  67. gAnimation().setPaused(true);
  68. if (oldState == PlayInEditorState::Stopped)
  69. saveSceneInMemory();
  70. gSceneManager().setComponentState(ComponentState::Paused);
  71. }
  72. break;
  73. default:
  74. break;
  75. }
  76. }
  77. void PlayInEditorManager::frameStep()
  78. {
  79. if (!gApplication().isEditor())
  80. return;
  81. switch (mState)
  82. {
  83. case PlayInEditorState::Stopped:
  84. case PlayInEditorState::Paused:
  85. setState(PlayInEditorState::Playing);
  86. break;
  87. default:
  88. break;
  89. }
  90. mFrameStepActive = true;
  91. }
  92. void PlayInEditorManager::update()
  93. {
  94. if (mState == PlayInEditorState::Playing)
  95. mPausableTime += gTime().getFrameDelta();
  96. if (mScheduledStateChange)
  97. {
  98. setStateImmediate(mNextState);
  99. mScheduledStateChange = false;
  100. }
  101. if (mFrameStepActive)
  102. {
  103. setState(PlayInEditorState::Paused);
  104. mFrameStepActive = false;
  105. }
  106. }
  107. void PlayInEditorManager::saveSceneInMemory()
  108. {
  109. mSavedScene = SceneManager::instance().getRootNode()->clone(false);
  110. // Remove objects with "dont save" flag
  111. Stack<HSceneObject> todo;
  112. todo.push(mSavedScene);
  113. while (!todo.empty())
  114. {
  115. HSceneObject current = todo.top();
  116. todo.pop();
  117. if (current->hasFlag(SOF_DontSave))
  118. current->destroy();
  119. else
  120. {
  121. UINT32 numChildren = current->getNumChildren();
  122. for (UINT32 i = 0; i < numChildren; i++)
  123. todo.push(current->getChild(i));
  124. }
  125. }
  126. }
  127. void PlayInEditorManager::setSystemsPauseState(bool paused)
  128. {
  129. gPhysics().setPaused(paused);
  130. gAudio().setPaused(paused);
  131. }
  132. }