BsPlayInEditorManager.cpp 3.4 KB

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