BsRenderWindowManager.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Managers/BsRenderWindowManager.h"
  4. #include "Platform/BsPlatform.h"
  5. #include "BsCoreApplication.h"
  6. using namespace std::placeholders;
  7. namespace bs
  8. {
  9. RenderWindowManager::RenderWindowManager()
  10. :mWindowInFocus(nullptr), mNewWindowInFocus(nullptr)
  11. { }
  12. RenderWindowManager::~RenderWindowManager()
  13. {
  14. }
  15. SPtr<RenderWindow> RenderWindowManager::create(RENDER_WINDOW_DESC& desc, SPtr<RenderWindow> parentWindow)
  16. {
  17. UINT32 id = ct::RenderWindowManager::instance().mNextWindowId.fetch_add(1, std::memory_order_relaxed);
  18. SPtr<RenderWindow> renderWindow = createImpl(desc, id, parentWindow);
  19. renderWindow->_setThisPtr(renderWindow);
  20. {
  21. Lock lock(mWindowMutex);
  22. mWindows[renderWindow->mWindowId] = renderWindow.get();
  23. }
  24. if (renderWindow->getProperties().isModal)
  25. mModalWindowStack.push_back(renderWindow.get());
  26. renderWindow->initialize();
  27. return renderWindow;
  28. }
  29. void RenderWindowManager::notifyWindowDestroyed(RenderWindow* window)
  30. {
  31. {
  32. Lock lock(mWindowMutex);
  33. auto iterFind = std::find(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows), window);
  34. if(iterFind != mMovedOrResizedWindows.end())
  35. mMovedOrResizedWindows.erase(iterFind);
  36. if (mNewWindowInFocus == window)
  37. mNewWindowInFocus = nullptr;
  38. mWindows.erase(window->mWindowId);
  39. mDirtyProperties.erase(window);
  40. }
  41. {
  42. auto iterFind = std::find(begin(mModalWindowStack), end(mModalWindowStack), window);
  43. if(iterFind != mModalWindowStack.end())
  44. mModalWindowStack.erase(iterFind);
  45. }
  46. }
  47. void RenderWindowManager::notifyFocusReceived(ct::RenderWindow* coreWindow)
  48. {
  49. Lock lock(mWindowMutex);
  50. RenderWindow* window = getNonCore(coreWindow);
  51. mNewWindowInFocus = window;
  52. }
  53. void RenderWindowManager::notifyFocusLost(ct::RenderWindow* coreWindow)
  54. {
  55. Lock lock(mWindowMutex);
  56. mNewWindowInFocus = nullptr;
  57. }
  58. void RenderWindowManager::notifyMovedOrResized(ct::RenderWindow* coreWindow)
  59. {
  60. Lock lock(mWindowMutex);
  61. RenderWindow* window = getNonCore(coreWindow);
  62. if (window == nullptr)
  63. return;
  64. auto iterFind = std::find(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows), window);
  65. if (iterFind == end(mMovedOrResizedWindows))
  66. mMovedOrResizedWindows.push_back(window);
  67. }
  68. void RenderWindowManager::notifyMouseLeft(ct::RenderWindow* coreWindow)
  69. {
  70. Lock lock(mWindowMutex);
  71. RenderWindow* window = getNonCore(coreWindow);
  72. auto iterFind = std::find(begin(mMouseLeftWindows), end(mMouseLeftWindows), window);
  73. if (iterFind == end(mMouseLeftWindows))
  74. mMouseLeftWindows.push_back(window);
  75. }
  76. void RenderWindowManager::notifyCloseRequested(ct::RenderWindow* coreWindow)
  77. {
  78. Lock lock(mWindowMutex);
  79. RenderWindow* window = getNonCore(coreWindow);
  80. auto iterFind = std::find(begin(mCloseRequestedWindows), end(mCloseRequestedWindows), window);
  81. if (iterFind == end(mCloseRequestedWindows))
  82. mCloseRequestedWindows.push_back(window);
  83. }
  84. void RenderWindowManager::notifySyncDataDirty(ct::RenderWindow* coreWindow)
  85. {
  86. Lock lock(mWindowMutex);
  87. RenderWindow* window = getNonCore(coreWindow);
  88. if (window != nullptr)
  89. mDirtyProperties.insert(window);
  90. }
  91. void RenderWindowManager::_update()
  92. {
  93. RenderWindow* newWinInFocus = nullptr;
  94. Vector<RenderWindow*> movedOrResizedWindows;
  95. Vector<RenderWindow*> mouseLeftWindows;
  96. Vector<RenderWindow*> closeRequestedWindows;
  97. {
  98. Lock lock(mWindowMutex);
  99. newWinInFocus = mNewWindowInFocus;
  100. std::swap(mMovedOrResizedWindows, movedOrResizedWindows);
  101. std::swap(mMouseLeftWindows, mouseLeftWindows);
  102. for (auto& dirtyPropertyWindow : mDirtyProperties)
  103. dirtyPropertyWindow->syncProperties();
  104. mDirtyProperties.clear();
  105. std::swap(mCloseRequestedWindows, closeRequestedWindows);
  106. }
  107. if(mWindowInFocus != newWinInFocus)
  108. {
  109. if(mWindowInFocus != nullptr)
  110. onFocusLost(*mWindowInFocus);
  111. if(newWinInFocus != nullptr)
  112. onFocusGained(*newWinInFocus);
  113. mWindowInFocus = newWinInFocus;
  114. }
  115. for (auto& window : movedOrResizedWindows)
  116. window->onResized();
  117. if (!onMouseLeftWindow.empty())
  118. {
  119. for (auto& window : mouseLeftWindows)
  120. onMouseLeftWindow(*window);
  121. }
  122. SPtr<RenderWindow> primaryWindow = gCoreApplication().getPrimaryWindow();
  123. for(auto& entry : closeRequestedWindows)
  124. {
  125. // Default behaviour for primary window is to quit the app on close
  126. if(entry == primaryWindow.get() && entry->onCloseRequested.empty())
  127. {
  128. gCoreApplication().quitRequested();
  129. continue;
  130. }
  131. entry->onCloseRequested();
  132. }
  133. }
  134. Vector<RenderWindow*> RenderWindowManager::getRenderWindows() const
  135. {
  136. Lock lock(mWindowMutex);
  137. Vector<RenderWindow*> windows;
  138. for (auto& windowPair : mWindows)
  139. windows.push_back(windowPair.second);
  140. return windows;
  141. }
  142. RenderWindow* RenderWindowManager::getTopMostModal() const
  143. {
  144. if (mModalWindowStack.empty())
  145. return nullptr;
  146. return mModalWindowStack.back();
  147. }
  148. RenderWindow* RenderWindowManager::getNonCore(const ct::RenderWindow* window) const
  149. {
  150. auto iterFind = mWindows.find(window->mWindowId);
  151. if (iterFind != mWindows.end())
  152. return iterFind->second;
  153. return nullptr;
  154. }
  155. namespace ct
  156. {
  157. RenderWindowManager::RenderWindowManager()
  158. {
  159. mNextWindowId = 0;
  160. }
  161. void RenderWindowManager::_update()
  162. {
  163. Lock lock(mWindowMutex);
  164. for (auto& dirtyPropertyWindow : mDirtyProperties)
  165. dirtyPropertyWindow->syncProperties();
  166. mDirtyProperties.clear();
  167. }
  168. void RenderWindowManager::windowCreated(RenderWindow* window)
  169. {
  170. Lock lock(mWindowMutex);
  171. mCreatedWindows.push_back(window);
  172. }
  173. void RenderWindowManager::windowDestroyed(RenderWindow* window)
  174. {
  175. {
  176. Lock lock(mWindowMutex);
  177. auto iterFind = std::find(begin(mCreatedWindows), end(mCreatedWindows), window);
  178. if (iterFind == mCreatedWindows.end())
  179. BS_EXCEPT(InternalErrorException, "Trying to destroy a window that is not in the created windows list.");
  180. mCreatedWindows.erase(iterFind);
  181. mDirtyProperties.erase(window);
  182. }
  183. }
  184. Vector<RenderWindow*> RenderWindowManager::getRenderWindows() const
  185. {
  186. Lock lock(mWindowMutex);
  187. return mCreatedWindows;
  188. }
  189. void RenderWindowManager::notifySyncDataDirty(RenderWindow* window)
  190. {
  191. Lock lock(mWindowMutex);
  192. mDirtyProperties.insert(window);
  193. }
  194. }
  195. }