Skip to content

Commit

Permalink
allow modifying vfuncs
Browse files Browse the repository at this point in the history
  • Loading branch information
vixalien committed Dec 26, 2023
1 parent b54147a commit bb69dc0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 9 deletions.
4 changes: 3 additions & 1 deletion src/bindings/girepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const { g } = openLib(libName("girepository-1.0", 1), {
},
base_info: {
get_name: $string($pointer),
get_container: $pointer($pointer),
is_deprecated: $bool($pointer),
get_type: $i32($pointer),
ref: $void($pointer),
Expand Down Expand Up @@ -74,6 +75,7 @@ const { g } = openLib(libName("girepository-1.0", 1), {
get_n_fields: $i32($pointer),
get_field: $pointer($pointer, $i32),
get_size: $i32($pointer),
find_field: $pointer($pointer, $string),
},
object_info: {
get_n_methods: $i32($pointer),
Expand Down Expand Up @@ -109,7 +111,7 @@ const { g } = openLib(libName("girepository-1.0", 1), {
field_info: {
get_flags: $i32($pointer),
get_type: $pointer($pointer),
get_field: $i32($pointer,$pointer, $buffer),
get_field: $bool($pointer,$pointer, $buffer),
set_field: $i32($pointer,$pointer, $buffer),
get_offset: $i32($pointer),
},
Expand Down
43 changes: 35 additions & 8 deletions src/types/callable.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { cast_ptr_u64, deref_buf } from "../base_utils/convert.ts";
import {
GIDirection,
GIFunctionInfoFlags,
Expand All @@ -11,6 +12,7 @@ import { createConstructor } from "./callable/constructor.js";
import { createFunction } from "./callable/function.js";
import { createMethod } from "./callable/method.js";
import { createVFunc } from "./callable/vfunc.js";
import { createCallback } from "./callback.js";

export function createArg(info) {
const type = g.arg_info.get_type(info);
Expand Down Expand Up @@ -120,19 +122,44 @@ export function handleCallable(target, info) {
}

case GIInfoType.VFUNC: {
if (Object.hasOwn(target.prototype, name)) {
return;
}

const value = createVFunc(info);
Object.defineProperty(target.prototype, `vfunc_` + name, {
enumerable: true,
value(...args) {
return value(
Reflect.getOwnMetadata("gi:ref", this),
get() {
return (...args) => {
return value(
Reflect.getOwnMetadata("gi:ref", this),
Reflect.getOwnMetadata("gi:gtype", this.constructor),
...args,
);
};
},
set(value) {
const baseName = 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, baseName);

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

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

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

0 comments on commit bb69dc0

Please sign in to comment.