Skip to content

Commit

Permalink
allow setting vfuncs provided by interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
vixalien committed Jan 22, 2024
1 parent 70fef60 commit 093f042
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
1 change: 1 addition & 0 deletions src/bindings/girepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ const { g } = openLib(libName("girepository-1.0", 1), {
get_vfunc: $pointer($pointer, $i32),
get_n_properties: $i32($pointer),
get_property: $pointer($pointer, $i32),
get_iface_struct: $pointer($pointer),
},
property_info: {
get_flags: $i32($pointer),
Expand Down
39 changes: 29 additions & 10 deletions src/types/callable.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,24 +137,43 @@ export function handleCallable(target, info) {
set(value) {
const cName = g.base_info.get_name(info);

const objectInfo = g.base_info.get_container(info);
const classStruct = g.object_info.get_class_struct(objectInfo);
const fieldInfo = g.struct_info.find_field(classStruct, cName);
const containerInfo = g.base_info.get_container(info);
const containerType = g.base_info.get_type(containerInfo);

let containerStruct, pointer;

if (containerType === GIInfoType.INTERFACE) {
// we are setting a vfunc provided by an interface
containerStruct = g.interface_info.get_iface_struct(containerInfo);
const klass = g.type_class.ref(
Reflect.getOwnMetadata("gi:gtype", this.constructor),
);
// get the pointer to the interface struct of this class
pointer = g.type_interface.peek(
klass,
g.registered_type_info.get_g_type(containerInfo),
);
} else {
// we are directly setting a vfunc provided by a class
containerStruct = g.object_info.get_class_struct(containerInfo);
pointer = g.type_class.ref(
Reflect.getOwnMetadata("gi:gtype", this.constructor),
);
}

const fieldInfo = g.struct_info.find_field(containerStruct, cName);

if (!fieldInfo) {
// This vfunc doesn't have a corresponding field in the class struct
// This vfunc doesn't have a corresponding field in the class or
// interface struct
return;
}

const klass = g.type_class.ref(
Reflect.getOwnMetadata("gi:gtype", this.constructor),
);

const cb = createCallback(info, value);
const cb = createCallback(info, value, this);
const offset = g.field_info.get_offset(fieldInfo);
const dataView = new ExtendedDataView(
deref_buf(
klass,
pointer,
offset + 8,
offset,
),
Expand Down

0 comments on commit 093f042

Please sign in to comment.