Skip to content

Commit

Permalink
Fixed missing bits, getting tests to pass.
Browse files Browse the repository at this point in the history
  • Loading branch information
tristanlabelle committed Mar 29, 2024
1 parent 5ce046b commit 06b1d1a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 54 deletions.
42 changes: 22 additions & 20 deletions swiftwinrt/Resources/Support/IInspectable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,28 +79,30 @@ public enum __ABI_ {
public static func tryUnwrapFrom(raw pUnk: UnsafeMutableRawPointer?) -> AnyObject? {
tryUnwrapFromBase(raw: pUnk)
}

internal static func queryInterface(_ pUnk: UnsafeMutablePointer<C_IInspectable>?, _ riid: UnsafePointer<SUPPORT_MODULE.IID>?, _ ppvObject: UnsafeMutablePointer<UnsafeMutableRawPointer?>?) -> HRESULT {
guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG }
ppvObject.pointee = nil
if riid.pointee == IUnknown.IID ||
riid.pointee == IInspectable.IID ||
riid.pointee == ISwiftImplemented.IID ||
riid.pointee == IAgileObject.IID {
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
ppvObject.pointee = UnsafeMutableRawPointer(pUnk)
return S_OK
}
let swiftObj = AnyWrapper.tryUnwrapFrom(raw: pUnk)
if let customQueryInterface = swiftObj as? CustomQueryInterface,
let result = customQueryInterface.queryInterface(riid.pointee) {
ppvObject.pointee = result.detach()
return S_OK
}
return E_NOINTERFACE
}
}

internal static var IInspectableVTable: C_IInspectableVtbl = .init(
QueryInterface: {
guard let pUnk = $0, let riid = $1, let ppvObject = $2 else { return E_INVALIDARG }
ppvObject.pointee = nil
if riid.pointee == IUnknown.IID ||
riid.pointee == IInspectable.IID ||
riid.pointee == ISwiftImplemented.IID ||
riid.pointee == IAgileObject.IID {
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
ppvObject.pointee = UnsafeMutableRawPointer(pUnk)
return S_OK
}
let swiftObj = AnyWrapper.tryUnwrapFrom(raw: pUnk)
if let customQueryInterface = swiftObj as? CustomQueryInterface,
let result = customQueryInterface.queryInterface(riid.pointee) {
ppvObject.pointee = result.detach()
return S_OK
}
return E_NOINTERFACE
},
QueryInterface: { AnyWrapper.queryInterface($0, $1, $2) },
AddRef: { AnyWrapper.addRef($0) },
Release: { AnyWrapper.release($0) },
GetIids: {
Expand Down Expand Up @@ -138,4 +140,4 @@ extension ComposableImpl where CABI == C_IInspectable {
let vtblPtr = withUnsafeMutablePointer(to: &__ABI_.IInspectableVTable) { $0 }
return .init(lpVtbl: vtblPtr)
}
}
}
51 changes: 28 additions & 23 deletions swiftwinrt/Resources/Support/IWeakReference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ fileprivate class WeakReferenceWrapper: WinRTAbiBridgeWrapper<IWeakReferenceBrid
init(_ weakReference: WeakReference){
super.init(IWeakReferenceBridge.makeAbi(), weakReference)
}

internal static func queryInterface(_ pUnk: UnsafeMutablePointer<C_IInspectable>?, _ riid: UnsafePointer<SUPPORT_MODULE.IID>?, _ ppvObject: UnsafeMutablePointer<UnsafeMutableRawPointer?>?) -> HRESULT {
guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG }
switch riid.pointee {
case IID_IWeakReference:
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
return S_OK
default:
guard let obj = WeakReferenceWrapper.tryUnwrapFromBase(raw: pUnk) else { return E_NOINTERFACE }
let anyWrapper = __ABI_.AnyWrapper(obj)!
return __ABI_.AnyWrapper.queryInterface(try! anyWrapper.toABI { $0 }, riid, ppvObject)
}
}
}

fileprivate enum IWeakReferenceBridge: AbiBridge {
Expand All @@ -43,35 +56,27 @@ fileprivate enum IWeakReferenceBridge: AbiBridge {
}

fileprivate var IWeakReferenceVTable: C_IWeakReferenceVtbl = .init(
QueryInterface: { pUnk, riid, ppvObject in
guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG }
switch riid.pointee {
case IID_IWeakReference:
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
return S_OK
default:
guard let obj = WeakReferenceWrapper.tryUnwrapFromBase(raw: pUnk) else { return E_NOINTERFACE }
fatalError("\(#function): Not implemented: something like obj.QueryInterface")
}
},
QueryInterface: { WeakReferenceWrapper.queryInterface($0, $1, $2) },
AddRef: { WeakReferenceWrapper.addRef($0) },
Release: { WeakReferenceWrapper.release($0) },
Resolve: { Resolve($0, $1, $2) }
)

fileprivate func Resolve(
_ this: UnsafeMutablePointer<C_IWeakReference>?,
_ iid: UnsafePointer<GUID_Workaround>?,
_ inspectable: UnsafeMutablePointer<UnsafeMutablePointer<C_IInspectable>?>?) -> HRESULT {
_ riid: UnsafePointer<GUID_Workaround>?,
_ ppvObject: UnsafeMutablePointer<UnsafeMutablePointer<C_IInspectable>?>?) -> HRESULT {
guard let this, let riid, let ppvObject else { return E_INVALIDARG }
guard let weakReference = WeakReferenceWrapper.tryUnwrapFrom(abi: ComPtr(this)) else { return E_FAIL }
guard let iid, let inspectable else { return E_INVALIDARG }
if let target = weakReference.target {
_ = target
_ = iid
fatalError("\(#function): Not implemented: something like target.QueryInterface")
}
else {
inspectable.pointee = nil
return S_OK
}
ppvObject.pointee = nil
// https://learn.microsoft.com/en-us/windows/win32/api/weakreference/nf-weakreference-iweakreference-resolve(refiid_iinspectable):
// "If you try to resolve a weak reference to a strong reference for an object that is no longer available,
// then IWeakReference::Resolve returns S_OK, but the objectReference parameter points to null.
guard let target = weakReference.target else { return S_OK }

let anyWrapper = __ABI_.AnyWrapper(target)!
var rawObject: UnsafeMutableRawPointer? = nil
let result = __ABI_.AnyWrapper.queryInterface(try! anyWrapper.toABI { $0 }, riid, &rawObject)
ppvObject.pointee = rawObject?.bindMemory(to: C_IInspectable.self, capacity: 1)
return result
}
25 changes: 14 additions & 11 deletions swiftwinrt/Resources/Support/IWeakReferenceSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ fileprivate class WeakReferenceSourceWrapper: WinRTAbiBridgeWrapper<IWeakReferen
init(_ object: AnyObject){
super.init(IWeakReferenceSourceBridge.makeAbi(), object)
}

internal static func queryInterface(_ pUnk: UnsafeMutablePointer<C_IInspectable>?, _ riid: UnsafePointer<SUPPORT_MODULE.IID>?, _ ppvObject: UnsafeMutablePointer<UnsafeMutableRawPointer?>?) -> HRESULT {
guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG }
switch riid.pointee {
case IID_IWeakReferenceSource:
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
return S_OK
default:
guard let obj = WeakReferenceSourceWrapper.tryUnwrapFromBase(raw: pUnk) else { return E_NOINTERFACE }
let anyWrapper = __ABI_.AnyWrapper(obj)!
return __ABI_.AnyWrapper.queryInterface(try! anyWrapper.toABI { $0 }, riid, ppvObject)
}
}
}

fileprivate enum IWeakReferenceSourceBridge: AbiBridge {
Expand All @@ -36,17 +49,7 @@ fileprivate enum IWeakReferenceSourceBridge: AbiBridge {
}

fileprivate var IWeakReferenceSourceVTable: C_IWeakReferenceSourceVtbl = .init(
QueryInterface: { pUnk, riid, ppvObject in
guard let pUnk, let riid, let ppvObject else { return E_INVALIDARG }
switch riid.pointee {
case IID_IWeakReferenceSource:
_ = pUnk.pointee.lpVtbl.pointee.AddRef(pUnk)
return S_OK
default:
guard let obj = WeakReferenceSourceWrapper.tryUnwrapFromBase(raw: pUnk) else { return E_NOINTERFACE }
fatalError("\(#function): Not implemented: something like obj.QueryInterface")
}
},
QueryInterface: { WeakReferenceSourceWrapper.queryInterface($0, $1, $2) },
AddRef: { WeakReferenceSourceWrapper.addRef($0) },
Release: { WeakReferenceSourceWrapper.release($0) },
GetWeakReference: { GetWeakReference($0, $1) }
Expand Down

0 comments on commit 06b1d1a

Please sign in to comment.