Skip to content

Instantly share code, notes, and snippets.

@mlarouche
Last active February 24, 2020 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mlarouche/c558881a9e51c45ef05577363de1602f to your computer and use it in GitHub Desktop.
Save mlarouche/c558881a9e51c45ef05577363de1602f to your computer and use it in GitHub Desktop.
Generic COM call
fn comFindReturnType(comptime vTableType: type, comptime name: []const u8) type {
for (@typeInfo(vTableType).Struct.fields) |field| {
if (std.mem.eql(u8, field.name, name)) {
const funcType = @typeInfo(@typeInfo(field.field_type).Optional.child);
return funcType.Fn.return_type.?;
}
}
return void;
}
fn comFindVtableType(comptime parentType: type) type {
switch (@typeInfo(parentType)) {
.Struct => |structInfo| {
for (structInfo.fields) |field| {
if (std.mem.eql(u8, field.name, "lpVtbl")) {
return @typeInfo(field.field_type).Pointer.child;
}
}
},
.Pointer => |pointerInfo| {
for (@typeInfo(pointerInfo.child).Struct.fields) |field| {
if (std.mem.eql(u8, field.name, "lpVtbl")) {
return @typeInfo(field.field_type).Pointer.child;
}
}
},
else => {},
}
return void;
}
fn comCall(comptime name: []const u8, args: var) comFindReturnType(comFindVtableType(@TypeOf(args[0])), name) {
if (@field(args[0].lpVtbl[0], name)) |func| {
return @call(.{}, func, args);
}
return undefined;
}
fn cleanupRenderTarget() void {
if (dxContext.mainRenderTargetView) |mainRenderTargetView| {
_ = comCall("Release", .{mainRenderTargetView});
dxContext.mainRenderTargetView = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment