BsPlayInEditorManager.cpp 3.3 KB

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