From 05878ba74683550e815607cf65effc80683eadaa Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Fri, 12 Oct 2018 22:35:45 +0300 Subject: [PATCH] Deallocation control --- src/Avalonia.Native.OSX/common.h | 7 ++++ src/Avalonia.Native.OSX/platformthreading.mm | 26 ++++++++------ src/Avalonia.Native.OSX/window.h | 1 + src/Avalonia.Native.OSX/window.mm | 38 +++++++++++++++++--- src/Avalonia.Native/WindowImplBase.cs | 18 ++++++++-- 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/Avalonia.Native.OSX/common.h b/src/Avalonia.Native.OSX/common.h index 902aed895d..11ee753aeb 100644 --- a/src/Avalonia.Native.OSX/common.h +++ b/src/Avalonia.Native.OSX/common.h @@ -22,4 +22,11 @@ extern NSPoint ToNSPoint (AvnPoint p); extern AvnPoint ToAvnPoint (NSPoint p); extern AvnPoint ConvertPointY (AvnPoint p); extern NSSize ToNSSize (AvnSize s); + +#ifdef DEBUG +#define NSDebugLog(...) NSLog(__VA_ARGS__) +#else +#define NSDebugLog(...) (void)0 +#endif + #endif diff --git a/src/Avalonia.Native.OSX/platformthreading.mm b/src/Avalonia.Native.OSX/platformthreading.mm index 5cd64155a3..07e307af74 100644 --- a/src/Avalonia.Native.OSX/platformthreading.mm +++ b/src/Avalonia.Native.OSX/platformthreading.mm @@ -106,18 +106,22 @@ public: [[NSApplication sharedApplication] activateIgnoringOtherApps:true]; while(true) { - if(can != NULL && can->Cancelled) - return; - NSEvent* ev = [[NSApplication sharedApplication] - nextEventMatchingMask:NSEventMaskAny - untilDate: [NSDate dateWithTimeIntervalSinceNow:1] - inMode:NSDefaultRunLoopMode - dequeue:true]; - if(can != NULL && can->Cancelled) - return; - if(ev != NULL) - [[NSApplication sharedApplication] sendEvent:ev]; + @autoreleasepool + { + if(can != NULL && can->Cancelled) + return; + NSEvent* ev = [[NSApplication sharedApplication] + nextEventMatchingMask:NSEventMaskAny + untilDate: [NSDate dateWithTimeIntervalSinceNow:1] + inMode:NSDefaultRunLoopMode + dequeue:true]; + if(can != NULL && can->Cancelled) + return; + if(ev != NULL) + [[NSApplication sharedApplication] sendEvent:ev]; + } } + NSDebugLog(@"RunLoop exited"); } } diff --git a/src/Avalonia.Native.OSX/window.h b/src/Avalonia.Native.OSX/window.h index 3a9ef22df1..34592993c3 100644 --- a/src/Avalonia.Native.OSX/window.h +++ b/src/Avalonia.Native.OSX/window.h @@ -11,6 +11,7 @@ class WindowBaseImpl; -(NSEvent* _Nonnull) lastMouseDownEvent; -(AvnPoint) translateLocalPoint:(AvnPoint)pt; -(void) setSwRenderedFrame: (AvnFramebuffer* _Nonnull) fb dispose: (IUnknown* _Nonnull) dispose; +-(void) onClosed; @end @interface AvnWindow : NSWindow diff --git a/src/Avalonia.Native.OSX/window.mm b/src/Avalonia.Native.OSX/window.mm index e5093c426c..e80c0e67b3 100644 --- a/src/Avalonia.Native.OSX/window.mm +++ b/src/Avalonia.Native.OSX/window.mm @@ -13,7 +13,12 @@ private: public: FORWARD_IUNKNOWN() - virtual ~WindowBaseImpl(){} + virtual ~WindowBaseImpl() + { + NSDebugLog(@"~WindowBaseImpl()"); + View = NULL; + Window = NULL; + } AvnView* View; AvnWindow* Window; ComPtr BaseEvents; @@ -351,7 +356,7 @@ private: INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow) END_INTERFACE_MAP() virtual ~WindowImpl(){ - NSLog(@"~WindowImpl"); + NSDebugLog(@"~WindowImpl"); } ComPtr WindowEvents; @@ -601,6 +606,17 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent bool _lastKeyHandled; } +- (void)dealloc +{ + NSDebugLog(@"AvnView dealloc"); +} + + +- (void)onClosed +{ + _parent = NULL; +} + - (NSEvent*) lastMouseDownEvent { return _lastMouseDownEvent; @@ -985,6 +1001,11 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent bool _closed; } +- (void)dealloc +{ + NSDebugLog(@"AvnWindow dealloc"); +} + - (void)pollModalSession:(nonnull NSModalSession)session { auto response = [NSApp runModalSession:session]; @@ -1031,9 +1052,17 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent - (void)windowWillClose:(NSNotification *)notification { _closed = true; - _parent->BaseEvents->Closed(); + if(_parent) + { + ComPtr parent = _parent; + _parent = NULL; + parent->BaseEvents->Closed(); + [parent->View onClosed]; + [self setContentView: nil]; + } } + -(BOOL)canBecomeKeyWindow { return _canBecomeKeyAndMain; @@ -1057,7 +1086,8 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent -(void)resignKeyWindow { - _parent->BaseEvents->Deactivated(); + if(_parent) + _parent->BaseEvents->Deactivated(); [super resignKeyWindow]; } diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs index 2895145cf3..ef3ec00ff4 100644 --- a/src/Avalonia.Native/WindowImplBase.cs +++ b/src/Avalonia.Native/WindowImplBase.cs @@ -110,7 +110,19 @@ namespace Avalonia.Native _parent = parent; } - void IAvnWindowBaseEvents.Closed() => _parent.Closed?.Invoke(); + void IAvnWindowBaseEvents.Closed() + { + var n = _parent._native; + _parent._native = null; + try + { + _parent?.Closed?.Invoke(); + } + finally + { + n?.Dispose(); + } + } void IAvnWindowBaseEvents.Activated() => _parent.Activated?.Invoke(); @@ -234,8 +246,8 @@ namespace Avalonia.Native public virtual void Dispose() { - _native.Close(); - _native.Dispose(); + _native?.Close(); + _native?.Dispose(); _native = null; (Screen as ScreenImpl)?.Dispose();