| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "Managers/BsRenderWindowManager.h"
- #include "Platform/BsPlatform.h"
- #include "BsCoreApplication.h"
- using namespace std::placeholders;
- namespace bs
- {
- RenderWindowManager::RenderWindowManager()
- :mWindowInFocus(nullptr), mNewWindowInFocus(nullptr)
- { }
- RenderWindowManager::~RenderWindowManager()
- {
- }
- SPtr<RenderWindow> RenderWindowManager::create(RENDER_WINDOW_DESC& desc, SPtr<RenderWindow> parentWindow)
- {
- UINT32 id = ct::RenderWindowManager::instance().mNextWindowId.fetch_add(1, std::memory_order_relaxed);
- SPtr<RenderWindow> renderWindow = createImpl(desc, id, parentWindow);
- renderWindow->_setThisPtr(renderWindow);
-
- {
- Lock lock(mWindowMutex);
- mWindows[renderWindow->mWindowId] = renderWindow.get();
- }
- if (renderWindow->getProperties().isModal)
- mModalWindowStack.push_back(renderWindow.get());
- renderWindow->initialize();
-
- return renderWindow;
- }
- void RenderWindowManager::notifyWindowDestroyed(RenderWindow* window)
- {
- {
- Lock lock(mWindowMutex);
- auto iterFind = std::find_if(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows),
- [&](const MoveOrResizeData& x) { return x.window == window; });
- if(iterFind != mMovedOrResizedWindows.end())
- mMovedOrResizedWindows.erase(iterFind);
- if (mNewWindowInFocus == window)
- mNewWindowInFocus = nullptr;
- mWindows.erase(window->mWindowId);
- mDirtyProperties.erase(window);
- }
- {
- auto iterFind = std::find(begin(mModalWindowStack), end(mModalWindowStack), window);
- if(iterFind != mModalWindowStack.end())
- mModalWindowStack.erase(iterFind);
- }
- }
- void RenderWindowManager::notifyFocusReceived(ct::RenderWindow* coreWindow)
- {
- Lock lock(mWindowMutex);
- RenderWindow* window = getNonCore(coreWindow);
- mNewWindowInFocus = window;
- }
- void RenderWindowManager::notifyFocusLost(ct::RenderWindow* coreWindow)
- {
- Lock lock(mWindowMutex);
- mNewWindowInFocus = nullptr;
- }
- void RenderWindowManager::notifyMovedOrResized(ct::RenderWindow* coreWindow)
- {
- Lock lock(mWindowMutex);
- RenderWindow* window = getNonCore(coreWindow);
- if (window == nullptr)
- return;
- auto iterFind = std::find_if(begin(mMovedOrResizedWindows), end(mMovedOrResizedWindows),
- [&](const MoveOrResizeData& x) { return x.window == window; });
- const RenderWindowProperties& props = coreWindow->getProperties();
- MoveOrResizeData* moveResizeData = nullptr;
- if (iterFind != end(mMovedOrResizedWindows))
- {
- moveResizeData = &*iterFind;
- }
- else
- {
- MoveOrResizeData newEntry;
- newEntry.window = window;
- mMovedOrResizedWindows.push_back(newEntry);
- moveResizeData = &mMovedOrResizedWindows.back();
- }
- moveResizeData->x = props.left;
- moveResizeData->y = props.top;
- moveResizeData->width = props.width;
- moveResizeData->height = props.height;
- }
- void RenderWindowManager::notifyMouseLeft(ct::RenderWindow* coreWindow)
- {
- Lock lock(mWindowMutex);
- RenderWindow* window = getNonCore(coreWindow);
- auto iterFind = std::find(begin(mMouseLeftWindows), end(mMouseLeftWindows), window);
- if (iterFind == end(mMouseLeftWindows))
- mMouseLeftWindows.push_back(window);
- }
- void RenderWindowManager::notifyCloseRequested(ct::RenderWindow* coreWindow)
- {
- Lock lock(mWindowMutex);
- RenderWindow* window = getNonCore(coreWindow);
- auto iterFind = std::find(begin(mCloseRequestedWindows), end(mCloseRequestedWindows), window);
- if (iterFind == end(mCloseRequestedWindows))
- mCloseRequestedWindows.push_back(window);
- }
- void RenderWindowManager::notifySyncDataDirty(ct::RenderWindow* coreWindow)
- {
- Lock lock(mWindowMutex);
- RenderWindow* window = getNonCore(coreWindow);
- if (window != nullptr)
- mDirtyProperties.insert(window);
- }
- void RenderWindowManager::_update()
- {
- RenderWindow* newWinInFocus = nullptr;
- Vector<MoveOrResizeData> movedOrResizedWindows;
- Vector<RenderWindow*> mouseLeftWindows;
- Vector<RenderWindow*> closeRequestedWindows;
- {
- Lock lock(mWindowMutex);
- newWinInFocus = mNewWindowInFocus;
- for (auto& moveResizeData : mMovedOrResizedWindows)
- {
- RenderWindow* window = moveResizeData.window;
- const RenderWindowProperties& props = window->getProperties();
- // Need to eliminate non-dirty ones because it's possible we already triggered the resize event
- // if the resize call originated from the sim thread, so we don't trigger it twice.
- bool isDirty = moveResizeData.x != props.left || moveResizeData.y != props.top
- || moveResizeData.width != props.width || moveResizeData.height != props.height;
- if (isDirty)
- movedOrResizedWindows.push_back(moveResizeData);
- }
- mMovedOrResizedWindows.clear();
- mouseLeftWindows = mMouseLeftWindows;
- mMouseLeftWindows.clear();
- for (auto& dirtyPropertyWindow : mDirtyProperties)
- dirtyPropertyWindow->syncProperties();
- mDirtyProperties.clear();
- std::swap(mCloseRequestedWindows, closeRequestedWindows);
- }
- if(mWindowInFocus != newWinInFocus)
- {
- if(mWindowInFocus != nullptr)
- onFocusLost(*mWindowInFocus);
- if(newWinInFocus != nullptr)
- onFocusGained(*newWinInFocus);
- mWindowInFocus = newWinInFocus;
- }
- for (auto& moveResizeData : movedOrResizedWindows)
- moveResizeData.window->onResized();
- if (!onMouseLeftWindow.empty())
- {
- for (auto& window : mouseLeftWindows)
- onMouseLeftWindow(*window);
- }
- SPtr<RenderWindow> primaryWindow = gCoreApplication().getPrimaryWindow();
- for(auto& entry : closeRequestedWindows)
- {
- // Default behaviour for primary window is to quit the app on close
- if(entry == primaryWindow.get() && entry->onCloseRequested.empty())
- {
- gCoreApplication().quitRequested();
- continue;
- }
- entry->onCloseRequested();
- }
- }
- Vector<RenderWindow*> RenderWindowManager::getRenderWindows() const
- {
- Lock lock(mWindowMutex);
- Vector<RenderWindow*> windows;
- for (auto& windowPair : mWindows)
- windows.push_back(windowPair.second);
- return windows;
- }
- RenderWindow* RenderWindowManager::getTopMostModal() const
- {
- if (mModalWindowStack.empty())
- return nullptr;
-
- return mModalWindowStack.back();
- }
- RenderWindow* RenderWindowManager::getNonCore(const ct::RenderWindow* window) const
- {
- auto iterFind = mWindows.find(window->mWindowId);
- if (iterFind != mWindows.end())
- return iterFind->second;
- return nullptr;
- }
- namespace ct
- {
- RenderWindowManager::RenderWindowManager()
- {
- mNextWindowId = 0;
- }
- SPtr<RenderWindow> RenderWindowManager::create(RENDER_WINDOW_DESC& desc)
- {
- UINT32 id = mNextWindowId.fetch_add(1, std::memory_order_relaxed);
- SPtr<RenderWindow> renderWindow = createInternal(desc, id);
- renderWindow->initialize();
- return renderWindow;
- }
- void RenderWindowManager::_update()
- {
- Lock lock(mWindowMutex);
- for (auto& dirtyPropertyWindow : mDirtyProperties)
- dirtyPropertyWindow->syncProperties();
- mDirtyProperties.clear();
- }
- void RenderWindowManager::windowCreated(RenderWindow* window)
- {
- Lock lock(mWindowMutex);
- mCreatedWindows.push_back(window);
- }
- void RenderWindowManager::windowDestroyed(RenderWindow* window)
- {
- {
- Lock lock(mWindowMutex);
- auto iterFind = std::find(begin(mCreatedWindows), end(mCreatedWindows), window);
- if (iterFind == mCreatedWindows.end())
- BS_EXCEPT(InternalErrorException, "Trying to destroy a window that is not in the created windows list.");
- mCreatedWindows.erase(iterFind);
- mDirtyProperties.erase(window);
- }
- }
- Vector<RenderWindow*> RenderWindowManager::getRenderWindows() const
- {
- Lock lock(mWindowMutex);
- return mCreatedWindows;
- }
- void RenderWindowManager::notifySyncDataDirty(RenderWindow* window)
- {
- Lock lock(mWindowMutex);
- mDirtyProperties.insert(window);
- }
- }
- }
|