I'm just going to implement it the way you've done it, rather then making it pretty. As much as I would like a pretty interface, the auto generated version will certainly be very different. And people are going to want D3D11, and who knows D3D13, at some point so it would be better if they all get generated similarly. Maybe I'll know enough about the toolchain to be able to help with that at some point. For now I'll just brute force it the way you've done.
Is that alright with you if I add a little boiler plate to IUnknown?
This:
public func GetGPUDescriptorHandleForHeapStart() throws -> D3D12_GPU_DESCRIPTOR_HANDLE {
guard let pUnk = UnsafeMutableRawPointer(self.pUnk) else {
throw COMError(hr: E_INVALIDARG)
}
let pThis = pUnk.bindMemory(to: WinSDK.ID3D12DescriptorHeap.self, capacity: 1)
return pThis.pointee.lpVtbl.pointee.GetGPUDescriptorHandleForHeapStart(pThis)
}
Becomes:
public func GetGPUDescriptorHandleForHeapStart() throws -> D3D12_GPU_DESCRIPTOR_HANDLE {
return try performComOperation(WinSDK.ID3D12DescriptorHeap.self) { (this, pThis) in
return this.lpVtbl.pointee.GetGPUDescriptorHandleForHeapStart(pThis)
}
}
And This:
public func GetDevice(_ riid: REFIID) throws -> UnsafeMutableRawPointer? throws {
guard let pUnk = UnsafeMutableRawPointer(self.pUnk) else {
throw COMError(hr: E_INVALIDARG)
}
let pThis = pUnk.bindMemory(to: WinSDK.ID3D12DeviceChild.self, capacity: 1)
var ppvDevice: UnsafeMutableRawPointer?
let hr: HRESULT = pThis.pointee.lpVtbl.pointee.GetDevice(pThis, riid, &ppvDevice)
guard hr == S_OK else { throw COMError(hr: hr) }
return ppvDevice
}
Becomes:
public func GetDevice(_ riid: REFIID) throws -> UnsafeMutableRawPointer? {
return try performComOperation(WinSDK.ID3D12DeviceChild.self) { (this, pThis, hresult) in
var ppvDevice: UnsafeMutableRawPointer?
hresult = this.lpVtbl.pointee.GetDevice(pThis, riid, &ppvDevice)
return ppvDevice
}
}
^ hresult throws when != S_OK here. I'll add a way to specify the "don't throw" HRESULT(s) if I come across an API that has a success(s) other then S_OK
And also this, for handling passed in objects from within the performComOperation closure:
let pSrc = try pSrcResource.getThisPointer(WinSDK.ID3D12Resource.self)
I know the goal is to auto-generate all this, but in the mean time this would be a nice quality of life improvement. The copy paste got tedious pretty quick. Some of these API's are really complex and being able to simplify the implementation for those complex ones would be super helpful. If you're cool with it I'll do the refactor of existing stuff in a separate commit too so everything is consistent.
Edit: I'm having decision remorse. I was just gonna update SwiftCOM, but I really, really want a pretty Swift API. I might just keep doing a separate package but using the WinSDK.D3D12 submodule when it's merged; I need to sleep on it.