Explorar o código

Deallocation control

Nikita Tsukanov %!s(int64=7) %!d(string=hai) anos
pai
achega
05878ba746

+ 7 - 0
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

+ 15 - 11
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");
         }
     }
     

+ 1 - 0
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 <NSWindowDelegate>

+ 34 - 4
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<IAvnWindowBaseEvents> BaseEvents;
@@ -351,7 +356,7 @@ private:
     INTERFACE_MAP_ENTRY(IAvnWindow, IID_IAvnWindow)
     END_INTERFACE_MAP()
     virtual ~WindowImpl(){
-        NSLog(@"~WindowImpl");
+        NSDebugLog(@"~WindowImpl");
     }
     
     ComPtr<IAvnWindowEvents> 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<WindowBaseImpl> 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];
 }
 

+ 15 - 3
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();