-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added WeakReference<T> to ease consuming IWeakReferenceSource.
- Loading branch information
1 parent
0562eed
commit 4780bdc
Showing
9 changed files
with
132 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import XCTest | ||
import WindowsRuntime | ||
import WinRTComponent | ||
|
||
class WeakReferenceTests: WinRTTestCase { | ||
func testNulledWhenUnreferencedFromSwift() throws { | ||
var target: MinimalClass! = try MinimalClass() | ||
let weakReference = try WeakReference<MinimalClassProjection>(target) | ||
XCTAssertNotNil(try weakReference.resolve()) | ||
target = nil | ||
XCTAssertNil(try weakReference.resolve()) | ||
} | ||
|
||
func testNulledWhenUnreferencedFromWinRT() throws { | ||
var target: MinimalClass! = try MinimalClass() | ||
let strongReferencer = try StrongReferencer(target) | ||
let weakReference = try WeakReference<MinimalClassProjection>(target) | ||
target = nil | ||
|
||
XCTAssertNotNil(try strongReferencer._target()) | ||
XCTAssertNotNil(try weakReference.resolve()) | ||
|
||
try strongReferencer.clear() | ||
|
||
XCTAssertNil(try NullResult.catch(strongReferencer._target())) | ||
XCTAssertNil(try weakReference.resolve()) | ||
} | ||
|
||
func testThroughIWeakReferenceSource() throws { | ||
var target: MinimalClass! = try MinimalClass() | ||
var weakReferenceSource: IWeakReferenceSource! = try target.queryInterface(IWeakReferenceSourceProjection.self) | ||
let weakReference = try weakReferenceSource.getWeakReference() | ||
XCTAssertNotNil(try weakReference.resolve()) | ||
target = nil | ||
weakReferenceSource = nil | ||
XCTAssertNil(try weakReference.resolve()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#include "pch.h" | ||
#include "StrongReferencer.h" | ||
#include "StrongReferencer.g.cpp" | ||
|
||
namespace winrt::WinRTComponent::implementation | ||
{ | ||
StrongReferencer::StrongReferencer(winrt::Windows::Foundation::IInspectable const& target) | ||
{ | ||
this->target = target; | ||
} | ||
winrt::Windows::Foundation::IInspectable StrongReferencer::Target() | ||
{ | ||
return target; | ||
} | ||
void StrongReferencer::Clear() | ||
{ | ||
target = nullptr; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#pragma once | ||
#include "StrongReferencer.g.h" | ||
|
||
namespace winrt::WinRTComponent::implementation | ||
{ | ||
struct StrongReferencer : StrongReferencerT<StrongReferencer> | ||
{ | ||
StrongReferencer(winrt::Windows::Foundation::IInspectable const& target); | ||
winrt::Windows::Foundation::IInspectable Target(); | ||
void Clear(); | ||
|
||
private: | ||
winrt::Windows::Foundation::IInspectable target; | ||
}; | ||
} | ||
namespace winrt::WinRTComponent::factory_implementation | ||
{ | ||
struct StrongReferencer : StrongReferencerT<StrongReferencer, implementation::StrongReferencer> | ||
{ | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace WinRTComponent | ||
{ | ||
runtimeclass StrongReferencer | ||
{ | ||
StrongReferencer(Object target); | ||
Object Target { get; }; | ||
void Clear(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import COM | ||
import WindowsRuntime_ABI | ||
|
||
/// A weak reference to a WinRT object. | ||
public final class WeakReference<Projection: WinRTReferenceTypeProjection> { | ||
private var weakReference: COMReference<WindowsRuntime_ABI.SWRT_IWeakReference> | ||
|
||
public init(_ target: Projection.SwiftObject) throws { | ||
guard let targetInspectable = target as? IInspectable else { throw HResult.Error.invalidArg } | ||
let source = try targetInspectable._queryInterface(WindowsRuntime_ABI.SWRT_IWeakReferenceSource.iid) | ||
.reinterpret(to: WindowsRuntime_ABI.SWRT_IWeakReferenceSource.self) | ||
var weakReference: UnsafeMutablePointer<WindowsRuntime_ABI.SWRT_IWeakReference>? | ||
try WinRTError.throwIfFailed(source.pointer.pointee.VirtualTable.pointee.GetWeakReference(source.pointer, &weakReference)) | ||
guard let weakReference else { throw HResult.Error.fail } | ||
self.weakReference = .init(transferringRef: weakReference) | ||
} | ||
|
||
public func resolve() throws -> Projection.SwiftObject? { | ||
var inspectableTarget: UnsafeMutablePointer<WindowsRuntime_ABI.SWRT_IInspectable>? = nil | ||
var iid = GUIDProjection.toABI(Projection.interfaceID) | ||
try WinRTError.throwIfFailed(weakReference.pointer.pointee.VirtualTable.pointee.Resolve( | ||
weakReference.pointer, &iid, &inspectableTarget)) | ||
var target = Projection.COMPointer(OpaquePointer(inspectableTarget)) | ||
return Projection.toSwift(consuming: &target) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters