Defer Cocoa window destuction post-iteration

This commit is contained in:
Jack Andersen 2016-01-09 22:01:09 -10:00
parent 6afe4eaff7
commit 5550909f7e
2 changed files with 20 additions and 15 deletions

View File

@ -116,8 +116,10 @@ public:
m_clientReturn = m_callback.appMain(this); m_clientReturn = m_callback.appMain(this);
/* Cleanup here */ /* Cleanup here */
std::vector<std::unique_ptr<IWindow>> toDelete;
toDelete.reserve(m_windows.size());
for (auto& window : m_windows) for (auto& window : m_windows)
delete window.second; toDelete.emplace_back(window.second);
}); });
/* Already in Cocoa's event loop; return now */ /* Already in Cocoa's event loop; return now */

View File

@ -1222,13 +1222,12 @@ class WindowCocoa : public IWindow
WindowCocoaInternal* m_nsWindow; WindowCocoaInternal* m_nsWindow;
GraphicsContextCocoa* m_gfxCtx; GraphicsContextCocoa* m_gfxCtx;
EMouseCursor m_cursor = EMouseCursor::None; EMouseCursor m_cursor = EMouseCursor::None;
bool m_closed = false;
public: public:
WindowCocoa(const std::string& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx) WindowCocoa(const std::string& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx)
{ {
dispatch_sync(dispatch_get_main_queue(),
^{
m_nsWindow = [[WindowCocoaInternal alloc] initWithBooWindow:this title:title]; m_nsWindow = [[WindowCocoaInternal alloc] initWithBooWindow:this title:title];
#if BOO_HAS_METAL #if BOO_HAS_METAL
if (metalCtx->m_dev) if (metalCtx->m_dev)
@ -1237,18 +1236,16 @@ public:
#endif #endif
m_gfxCtx = static_cast<GraphicsContextCocoa*>(_GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, lastGLCtx)); m_gfxCtx = static_cast<GraphicsContextCocoa*>(_GraphicsContextCocoaGLNew(IGraphicsContext::EGraphicsAPI::OpenGL3_3, this, lastGLCtx));
m_gfxCtx->initializeContext(); m_gfxCtx->initializeContext();
});
} }
void _clearWindow() void _clearWindow()
{ {
/* Caller consumes reference on its own */ m_closed = true;
(void)(__bridge_retained void*)m_nsWindow;
m_nsWindow = nullptr;
} }
~WindowCocoa() ~WindowCocoa()
{ {
if (!m_closed)
[m_nsWindow orderOut:nil]; [m_nsWindow orderOut:nil];
delete m_gfxCtx; delete m_gfxCtx;
APP->_deletedWindow(this); APP->_deletedWindow(this);
@ -1494,7 +1491,12 @@ public:
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx) IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx)
{ {
return new WindowCocoa(title, lastGLCtx, metalCtx); __block IWindow* window = nullptr;
dispatch_sync(dispatch_get_main_queue(),
^{
window = new WindowCocoa(title, lastGLCtx, metalCtx);
});
return window;
} }
} }
@ -1509,6 +1511,7 @@ IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx,
NSResizableWindowMask NSResizableWindowMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:YES]; defer:YES];
self.releasedWhenClosed = NO;
self.title = [NSString stringWithUTF8String:title.c_str()]; self.title = [NSString stringWithUTF8String:title.c_str()];
booWindow = bw; booWindow = bw;
return self; return self;