BsPlayInEditorManager.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include "BsPlayInEditorManager.h"
  2. #include "BsScriptGameObjectManager.h"
  3. #include "BsTime.h"
  4. #include "BsSceneManager.h"
  5. #include "BsSceneObject.h"
  6. #include "BsApplication.h"
  7. namespace BansheeEngine
  8. {
  9. PlayInEditorManager::PlayInEditorManager()
  10. :mState(PlayInEditorState::Stopped), mNextState(PlayInEditorState::Stopped),
  11. mFrameStepActive(false), mScheduledStateChange(false), mPausableTime(0.0f)
  12. {
  13. if (!gApplication().isEditor())
  14. mState = PlayInEditorState::Playing;
  15. }
  16. void PlayInEditorManager::setState(PlayInEditorState state)
  17. {
  18. if (!gApplication().isEditor())
  19. return;
  20. // Delay state change to next frame as this method could be called in middle of object update, in which case
  21. // part of the objects before this call would receive different state than other objects.
  22. mScheduledStateChange = true;
  23. mNextState = state;
  24. }
  25. void PlayInEditorManager::setStateImmediate(PlayInEditorState state)
  26. {
  27. if (mState == state)
  28. return;
  29. PlayInEditorState oldState = mState;
  30. mState = state;
  31. switch (state)
  32. {
  33. case PlayInEditorState::Stopped:
  34. {
  35. mFrameStepActive = false;
  36. mPausableTime = 0.0f;
  37. mSavedScene->_instantiate();
  38. gSceneManager()._setRootNode(mSavedScene);
  39. mSavedScene = nullptr;
  40. }
  41. break;
  42. case PlayInEditorState::Playing:
  43. {
  44. if (oldState == PlayInEditorState::Paused)
  45. {
  46. ScriptGameObjectManager::instance().sendComponentInitializeEvents();
  47. }
  48. else // Was stopped
  49. {
  50. saveSceneInMemory();
  51. ScriptGameObjectManager::instance().sendComponentInitializeEvents();
  52. }
  53. }
  54. break;
  55. case PlayInEditorState::Paused:
  56. {
  57. mFrameStepActive = false;
  58. if (oldState == PlayInEditorState::Stopped)
  59. {
  60. saveSceneInMemory();
  61. ScriptGameObjectManager::instance().sendComponentInitializeEvents();
  62. }
  63. }
  64. break;
  65. default:
  66. break;
  67. }
  68. }
  69. void PlayInEditorManager::frameStep()
  70. {
  71. if (!gApplication().isEditor())
  72. return;
  73. switch (mState)
  74. {
  75. case PlayInEditorState::Stopped:
  76. case PlayInEditorState::Paused:
  77. setState(PlayInEditorState::Playing);
  78. break;
  79. }
  80. mFrameStepActive = true;
  81. }
  82. void PlayInEditorManager::update()
  83. {
  84. if (mState == PlayInEditorState::Playing)
  85. mPausableTime += gTime().getFrameDelta();
  86. if (mScheduledStateChange)
  87. {
  88. setStateImmediate(mNextState);
  89. mScheduledStateChange = false;
  90. }
  91. if (mFrameStepActive)
  92. {
  93. setState(PlayInEditorState::Paused);
  94. mFrameStepActive = false;
  95. }
  96. }
  97. void PlayInEditorManager::saveSceneInMemory()
  98. {
  99. mSavedScene = SceneManager::instance().getRootNode()->clone(false);
  100. // Remove objects with "dont save" flag
  101. Stack<HSceneObject> todo;
  102. todo.push(mSavedScene);
  103. while (!todo.empty())
  104. {
  105. HSceneObject current = todo.top();
  106. todo.pop();
  107. if (current->hasFlag(SOF_DontSave))
  108. current->destroy();
  109. else
  110. {
  111. UINT32 numChildren = current->getNumChildren();
  112. for (UINT32 i = 0; i < numChildren; i++)
  113. todo.push(current->getChild(i));
  114. }
  115. }
  116. }
  117. }