@gtkx/runtime 0.0.1 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +171 -3
- package/dist/arg.d.ts +12 -0
- package/dist/arg.d.ts.map +1 -0
- package/dist/arg.js +5 -0
- package/dist/arg.js.map +1 -0
- package/dist/bind.d.ts +4 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +17 -0
- package/dist/bind.js.map +1 -0
- package/dist/callback.d.ts +13 -0
- package/dist/callback.d.ts.map +1 -0
- package/dist/callback.js +68 -0
- package/dist/callback.js.map +1 -0
- package/dist/descriptors.d.ts +155 -0
- package/dist/descriptors.d.ts.map +1 -0
- package/dist/descriptors.js +103 -0
- package/dist/descriptors.js.map +1 -0
- package/dist/error.d.ts +25 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +29 -0
- package/dist/error.js.map +1 -0
- package/dist/fn.d.ts +10 -0
- package/dist/fn.d.ts.map +1 -0
- package/dist/fn.js +79 -0
- package/dist/fn.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +5 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +5 -0
- package/dist/internal.js.map +1 -0
- package/dist/library.d.ts +7 -0
- package/dist/library.d.ts.map +1 -0
- package/dist/library.js +13 -0
- package/dist/library.js.map +1 -0
- package/dist/lifecycle.d.ts +41 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +55 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/listeners.d.ts +36 -0
- package/dist/listeners.d.ts.map +1 -0
- package/dist/listeners.js +72 -0
- package/dist/listeners.js.map +1 -0
- package/dist/mixin.d.ts +19 -0
- package/dist/mixin.d.ts.map +1 -0
- package/dist/mixin.js +39 -0
- package/dist/mixin.js.map +1 -0
- package/dist/native-value.d.ts +12 -0
- package/dist/native-value.d.ts.map +1 -0
- package/dist/native-value.js +72 -0
- package/dist/native-value.js.map +1 -0
- package/dist/object.d.ts +31 -0
- package/dist/object.d.ts.map +1 -0
- package/dist/object.js +63 -0
- package/dist/object.js.map +1 -0
- package/dist/promisify.d.ts +13 -0
- package/dist/promisify.d.ts.map +1 -0
- package/dist/promisify.js +36 -0
- package/dist/promisify.js.map +1 -0
- package/dist/register-class.d.ts +17 -0
- package/dist/register-class.d.ts.map +1 -0
- package/dist/register-class.js +124 -0
- package/dist/register-class.js.map +1 -0
- package/dist/registry.d.ts +67 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +167 -0
- package/dist/registry.js.map +1 -0
- package/dist/signal.d.ts +34 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +88 -0
- package/dist/signal.js.map +1 -0
- package/dist/t.d.ts +50 -0
- package/dist/t.d.ts.map +1 -0
- package/dist/t.js +48 -0
- package/dist/t.js.map +1 -0
- package/dist/tuple.d.ts +6 -0
- package/dist/tuple.d.ts.map +1 -0
- package/dist/tuple.js +23 -0
- package/dist/tuple.js.map +1 -0
- package/dist/type.d.ts +81 -0
- package/dist/type.d.ts.map +1 -0
- package/dist/type.js +174 -0
- package/dist/type.js.map +1 -0
- package/dist/value.d.ts +20 -0
- package/dist/value.d.ts.map +1 -0
- package/dist/value.js +227 -0
- package/dist/value.js.map +1 -0
- package/package.json +56 -13
- package/src/arg.ts +13 -0
- package/src/bind.ts +22 -0
- package/src/callback.ts +87 -0
- package/src/descriptors.ts +208 -0
- package/src/error.ts +49 -0
- package/src/fn.ts +108 -0
- package/src/index.ts +57 -0
- package/src/internal.ts +12 -0
- package/src/library.ts +15 -0
- package/src/lifecycle.ts +73 -0
- package/src/listeners.ts +84 -0
- package/src/mixin.ts +48 -0
- package/src/native-value.ts +78 -0
- package/src/object.ts +83 -0
- package/src/promisify.ts +40 -0
- package/src/register-class.ts +178 -0
- package/src/registry.ts +221 -0
- package/src/signal.ts +152 -0
- package/src/t.ts +88 -0
- package/src/tuple.ts +25 -0
- package/src/type.ts +200 -0
- package/src/value.ts +307 -0
package/dist/value.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { alloc, getType, read, write } from "@gtkx/native";
|
|
2
|
+
import { bind, createBindCache } from "./bind.js";
|
|
3
|
+
import { arrayT, bigint64T, biguint64T, booleanT, boxedT, float32T, float64T, int32T, objectT, stringT, uint32T, uint64T, voidT, } from "./descriptors.js";
|
|
4
|
+
import { LIB, PARAM_T, VALUE_SIZE, VALUE_T, VARIANT_T } from "./library.js";
|
|
5
|
+
import { toNative } from "./native-value.js";
|
|
6
|
+
import { getHandle, getWrapperClass, wrapHandle } from "./registry.js";
|
|
7
|
+
import { getStrvType, resolveBoxedType, resolveDescriptorType, resolveFundamentalType, resolveType, TYPE_BOOLEAN, TYPE_BOXED, TYPE_DOUBLE, TYPE_ENUM, TYPE_FLAGS, TYPE_FLOAT, TYPE_GTYPE, TYPE_INT, TYPE_INT64, TYPE_INVALID, TYPE_OBJECT, TYPE_PARAM, TYPE_POINTER, TYPE_STRING, TYPE_UINT, TYPE_UINT64, TYPE_VARIANT, typeFundamental, typeName, } from "./type.js";
|
|
8
|
+
const getBoxedTypeName = (type) => typeName(type) ?? "GBoxed";
|
|
9
|
+
const newValue = () => alloc(VALUE_SIZE, "GValue");
|
|
10
|
+
const setBoxedCache = createBindCache();
|
|
11
|
+
const setStaticBoxedCache = createBindCache();
|
|
12
|
+
const dupBoxedCache = createBindCache();
|
|
13
|
+
const gValueInit = bind(LIB, "g_value_init", [VALUE_T, biguint64T], voidT);
|
|
14
|
+
const gValueCopy = bind(LIB, "g_value_copy", [VALUE_T, VALUE_T], voidT);
|
|
15
|
+
const bindValueType = (symbol, descriptor) => ({
|
|
16
|
+
set: bind(LIB, `g_value_set_${symbol}`, [VALUE_T, descriptor], voidT),
|
|
17
|
+
get: bind(LIB, `g_value_get_${symbol}`, [VALUE_T], descriptor),
|
|
18
|
+
});
|
|
19
|
+
const setBoxedBind = (name) => setBoxedCache(name, LIB, "g_value_set_boxed", [VALUE_T, boxedT(name, { sharedLibrary: LIB })], voidT);
|
|
20
|
+
const setStaticBoxedBind = (name) => setStaticBoxedCache(name, LIB, "g_value_set_static_boxed", [VALUE_T, boxedT(name, { sharedLibrary: LIB })], voidT);
|
|
21
|
+
const dupBoxedBind = (name) => dupBoxedCache(name, LIB, "g_value_dup_boxed", [VALUE_T], boxedT(name, { ownership: "full", sharedLibrary: LIB }));
|
|
22
|
+
const booleanValueType = bindValueType("boolean", booleanT);
|
|
23
|
+
const typeValueType = bindValueType("gtype", biguint64T);
|
|
24
|
+
const intValueType = bindValueType("int", int32T);
|
|
25
|
+
const uintValueType = bindValueType("uint", uint32T);
|
|
26
|
+
const int64ValueType = bindValueType("int64", bigint64T);
|
|
27
|
+
const uint64ValueType = bindValueType("uint64", biguint64T);
|
|
28
|
+
const floatValueType = bindValueType("float", float32T);
|
|
29
|
+
const doubleValueType = bindValueType("double", float64T);
|
|
30
|
+
const stringValueType = bindValueType("string", stringT("borrowed"));
|
|
31
|
+
const enumValueType = bindValueType("enum", int32T);
|
|
32
|
+
const flagsValueType = bindValueType("flags", uint32T);
|
|
33
|
+
const objectValueType = bindValueType("object", objectT("borrowed"));
|
|
34
|
+
const paramValueType = bindValueType("param", PARAM_T);
|
|
35
|
+
const variantValueType = bindValueType("variant", VARIANT_T);
|
|
36
|
+
const pointerValueType = bindValueType("pointer", uint64T);
|
|
37
|
+
const strvValueType = {
|
|
38
|
+
set: bind(LIB, "g_value_set_boxed", [VALUE_T, arrayT(stringT("borrowed"))], voidT),
|
|
39
|
+
get: bind(LIB, "g_value_get_boxed", [VALUE_T], arrayT(stringT("borrowed"))),
|
|
40
|
+
};
|
|
41
|
+
const boxedValueType = (type) => {
|
|
42
|
+
const name = getBoxedTypeName(type);
|
|
43
|
+
return { set: setBoxedBind(name), get: dupBoxedBind(name) };
|
|
44
|
+
};
|
|
45
|
+
const enumOrFlagsValueType = (type) => typeFundamental(type) === TYPE_FLAGS ? flagsValueType : enumValueType;
|
|
46
|
+
const fundamentalValueType = (type) => {
|
|
47
|
+
switch (typeFundamental(type)) {
|
|
48
|
+
case TYPE_PARAM:
|
|
49
|
+
return paramValueType;
|
|
50
|
+
case TYPE_VARIANT:
|
|
51
|
+
return variantValueType;
|
|
52
|
+
case TYPE_BOXED:
|
|
53
|
+
return boxedValueType(type);
|
|
54
|
+
default:
|
|
55
|
+
throw new Error(`Unsupported fundamental type '${typeName(type) ?? String(type)}' for value`);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
export function getValueType(value) {
|
|
59
|
+
return read(value, biguint64T, 0);
|
|
60
|
+
}
|
|
61
|
+
export function copyValue(dest, src) {
|
|
62
|
+
if (getValueType(dest) === TYPE_INVALID) {
|
|
63
|
+
gValueInit(dest, getValueType(src));
|
|
64
|
+
}
|
|
65
|
+
gValueCopy(src, dest);
|
|
66
|
+
}
|
|
67
|
+
const newTypedValue = (type) => {
|
|
68
|
+
const value = newValue();
|
|
69
|
+
gValueInit(value, type);
|
|
70
|
+
return value;
|
|
71
|
+
};
|
|
72
|
+
const newBoxedValue = (descriptor, boxed, resolveSetBind) => {
|
|
73
|
+
const type = resolveDescriptorType(descriptor);
|
|
74
|
+
const value = newTypedValue(type);
|
|
75
|
+
resolveSetBind(getBoxedTypeName(type))(value, getHandle(boxed));
|
|
76
|
+
return value;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Reads the boxed pointer out of a GValue and returns it wrapped in its registered
|
|
80
|
+
* class, or null when the value does not hold a boxed type.
|
|
81
|
+
*/
|
|
82
|
+
export function getBoxedValue(value) {
|
|
83
|
+
const type = getValueType(value);
|
|
84
|
+
if (typeFundamental(type) !== TYPE_BOXED)
|
|
85
|
+
return null;
|
|
86
|
+
const cls = getWrapperClass(type);
|
|
87
|
+
const boxed = dupBoxedBind(getBoxedTypeName(type))(value);
|
|
88
|
+
return wrapHandle(boxed, cls);
|
|
89
|
+
}
|
|
90
|
+
/** Stores a boxed object, or null, into a GValue that holds a boxed type. */
|
|
91
|
+
export function setBoxedValue(value, boxed) {
|
|
92
|
+
const name = getBoxedTypeName(getValueType(value));
|
|
93
|
+
setBoxedBind(name)(value, boxed === null ? null : getHandle(boxed));
|
|
94
|
+
}
|
|
95
|
+
const resolveValueType = (descriptor) => {
|
|
96
|
+
if (descriptor.kind === "biguint64" && "type" in descriptor) {
|
|
97
|
+
return typeValueType;
|
|
98
|
+
}
|
|
99
|
+
switch (descriptor.kind) {
|
|
100
|
+
case "boolean":
|
|
101
|
+
return booleanValueType;
|
|
102
|
+
case "string":
|
|
103
|
+
return stringValueType;
|
|
104
|
+
case "int8":
|
|
105
|
+
case "int16":
|
|
106
|
+
case "int32":
|
|
107
|
+
return intValueType;
|
|
108
|
+
case "uint8":
|
|
109
|
+
case "uint16":
|
|
110
|
+
case "uint32":
|
|
111
|
+
return uintValueType;
|
|
112
|
+
case "int64":
|
|
113
|
+
case "bigint64":
|
|
114
|
+
return int64ValueType;
|
|
115
|
+
case "uint64":
|
|
116
|
+
case "biguint64":
|
|
117
|
+
return uint64ValueType;
|
|
118
|
+
case "float32":
|
|
119
|
+
return floatValueType;
|
|
120
|
+
case "float64":
|
|
121
|
+
return doubleValueType;
|
|
122
|
+
case "object":
|
|
123
|
+
return objectValueType;
|
|
124
|
+
case "enum":
|
|
125
|
+
case "flags":
|
|
126
|
+
return enumOrFlagsValueType(resolveType(descriptor.sharedLibrary, descriptor.getTypeFnName));
|
|
127
|
+
case "boxed":
|
|
128
|
+
return boxedValueType(resolveBoxedType(descriptor));
|
|
129
|
+
case "fundamental":
|
|
130
|
+
return fundamentalValueType(resolveFundamentalType(descriptor));
|
|
131
|
+
case "array":
|
|
132
|
+
if (descriptor.itemDescriptor.kind === "string" && descriptor.arrayKind === "array") {
|
|
133
|
+
return strvValueType;
|
|
134
|
+
}
|
|
135
|
+
throw new Error(`Unsupported array type ${descriptor.arrayKind} of ${descriptor.itemDescriptor.kind}`);
|
|
136
|
+
default:
|
|
137
|
+
throw new Error(`Unsupported type descriptor '${descriptor.kind}'`);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const resolveValueGetter = (fundamental) => {
|
|
141
|
+
switch (fundamental) {
|
|
142
|
+
case TYPE_BOOLEAN:
|
|
143
|
+
return booleanValueType.get;
|
|
144
|
+
case TYPE_GTYPE:
|
|
145
|
+
return typeValueType.get;
|
|
146
|
+
case TYPE_INT:
|
|
147
|
+
return intValueType.get;
|
|
148
|
+
case TYPE_UINT:
|
|
149
|
+
return uintValueType.get;
|
|
150
|
+
case TYPE_INT64:
|
|
151
|
+
return int64ValueType.get;
|
|
152
|
+
case TYPE_UINT64:
|
|
153
|
+
return uint64ValueType.get;
|
|
154
|
+
case TYPE_FLOAT:
|
|
155
|
+
return floatValueType.get;
|
|
156
|
+
case TYPE_DOUBLE:
|
|
157
|
+
return doubleValueType.get;
|
|
158
|
+
case TYPE_ENUM:
|
|
159
|
+
return enumValueType.get;
|
|
160
|
+
case TYPE_FLAGS:
|
|
161
|
+
return flagsValueType.get;
|
|
162
|
+
case TYPE_STRING:
|
|
163
|
+
return (value) => stringValueType.get(value) ?? null;
|
|
164
|
+
case TYPE_OBJECT:
|
|
165
|
+
return (value) => wrapHandle(objectValueType.get(value));
|
|
166
|
+
case TYPE_PARAM:
|
|
167
|
+
return (value) => wrapHandle(paramValueType.get(value), getWrapperClass(TYPE_PARAM));
|
|
168
|
+
case TYPE_VARIANT:
|
|
169
|
+
return (value) => wrapHandle(variantValueType.get(value), getWrapperClass(TYPE_VARIANT));
|
|
170
|
+
case TYPE_BOXED:
|
|
171
|
+
return getBoxedValue;
|
|
172
|
+
case TYPE_POINTER:
|
|
173
|
+
return (value) => {
|
|
174
|
+
if (pointerValueType.get(value)) {
|
|
175
|
+
throw new Error("G_TYPE_POINTER non-null values cannot be marshalled to JS");
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
};
|
|
179
|
+
default:
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
export function toValue(descriptor, value) {
|
|
184
|
+
const isHandleKind = descriptor.kind === "object" || descriptor.kind === "boxed";
|
|
185
|
+
const nativeValue = isHandleKind
|
|
186
|
+
? value == null
|
|
187
|
+
? null
|
|
188
|
+
: getHandle(value)
|
|
189
|
+
: toNative(descriptor, value);
|
|
190
|
+
const type = descriptor.kind === "object"
|
|
191
|
+
? nativeValue == null
|
|
192
|
+
? TYPE_OBJECT
|
|
193
|
+
: getType(nativeValue)
|
|
194
|
+
: resolveDescriptorType(descriptor);
|
|
195
|
+
const gValue = newTypedValue(type);
|
|
196
|
+
resolveValueType(descriptor).set(gValue, nativeValue);
|
|
197
|
+
return gValue;
|
|
198
|
+
}
|
|
199
|
+
export function fromValue(value) {
|
|
200
|
+
const type = getValueType(value);
|
|
201
|
+
if (type === getStrvType())
|
|
202
|
+
return strvValueType.get(value);
|
|
203
|
+
const get = resolveValueGetter(typeFundamental(type));
|
|
204
|
+
if (get === undefined) {
|
|
205
|
+
throw new Error(`Unsupported type for fromValue: ${typeName(type) ?? String(type)}`);
|
|
206
|
+
}
|
|
207
|
+
return get(value);
|
|
208
|
+
}
|
|
209
|
+
export function newValueForDescriptor(descriptor) {
|
|
210
|
+
return newTypedValue(resolveDescriptorType(descriptor));
|
|
211
|
+
}
|
|
212
|
+
export function outValueForDescriptor(descriptor, initial) {
|
|
213
|
+
const storage = alloc(8);
|
|
214
|
+
write(storage, uint64T, 0, 0);
|
|
215
|
+
if (initial !== undefined)
|
|
216
|
+
write(storage, descriptor, 0, initial);
|
|
217
|
+
const value = newTypedValue(TYPE_POINTER);
|
|
218
|
+
pointerValueType.set(value, storage);
|
|
219
|
+
return { value, read: () => read(storage, descriptor, 0) };
|
|
220
|
+
}
|
|
221
|
+
export function outValueForBoxedDescriptor(descriptor, boxed) {
|
|
222
|
+
return newBoxedValue(descriptor, boxed, setBoxedBind);
|
|
223
|
+
}
|
|
224
|
+
export function inoutValueForBoxedDescriptor(descriptor, boxed) {
|
|
225
|
+
return newBoxedValue(descriptor, boxed, setStaticBoxedBind);
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value.js","sourceRoot":"","sources":["../src/value.ts"],"names":[],"mappings":"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","sourcesContent":["import { alloc, type Descriptor, type ExternalObject, getType, type Handle, read, write } from \"@gtkx/native\";\nimport { bind, createBindCache } from \"./bind.js\";\nimport {\n arrayT,\n bigint64T,\n biguint64T,\n booleanT,\n boxedT,\n float32T,\n float64T,\n int32T,\n objectT,\n stringT,\n uint32T,\n uint64T,\n voidT,\n} from \"./descriptors.js\";\nimport { LIB, PARAM_T, VALUE_SIZE, VALUE_T, VARIANT_T } from \"./library.js\";\nimport { toNative } from \"./native-value.js\";\nimport { getHandle, getWrapperClass, wrapHandle } from \"./registry.js\";\nimport {\n getStrvType,\n resolveBoxedType,\n resolveDescriptorType,\n resolveFundamentalType,\n resolveType,\n TYPE_BOOLEAN,\n TYPE_BOXED,\n TYPE_DOUBLE,\n TYPE_ENUM,\n TYPE_FLAGS,\n TYPE_FLOAT,\n TYPE_GTYPE,\n TYPE_INT,\n TYPE_INT64,\n TYPE_INVALID,\n TYPE_OBJECT,\n TYPE_PARAM,\n TYPE_POINTER,\n TYPE_STRING,\n TYPE_UINT,\n TYPE_UINT64,\n TYPE_VARIANT,\n typeFundamental,\n typeName,\n} from \"./type.js\";\n\ntype ValueType = {\n set: (value: ExternalObject<Handle>, nativeValue: unknown) => void;\n get: (value: ExternalObject<Handle>) => unknown;\n};\n\nconst getBoxedTypeName = (type: bigint): string => typeName(type) ?? \"GBoxed\";\nconst newValue = (): ExternalObject<Handle> => alloc(VALUE_SIZE, \"GValue\");\n\nconst setBoxedCache = createBindCache();\nconst setStaticBoxedCache = createBindCache();\nconst dupBoxedCache = createBindCache();\n\nconst gValueInit = bind(LIB, \"g_value_init\", [VALUE_T, biguint64T], voidT);\nconst gValueCopy = bind(LIB, \"g_value_copy\", [VALUE_T, VALUE_T], voidT);\n\nconst bindValueType = (symbol: string, descriptor: Descriptor): ValueType => ({\n set: bind(LIB, `g_value_set_${symbol}`, [VALUE_T, descriptor], voidT),\n get: bind(LIB, `g_value_get_${symbol}`, [VALUE_T], descriptor),\n});\n\nconst setBoxedBind = (name: string) =>\n setBoxedCache(name, LIB, \"g_value_set_boxed\", [VALUE_T, boxedT(name, { sharedLibrary: LIB })], voidT);\n\nconst setStaticBoxedBind = (name: string) =>\n setStaticBoxedCache(name, LIB, \"g_value_set_static_boxed\", [VALUE_T, boxedT(name, { sharedLibrary: LIB })], voidT);\n\nconst dupBoxedBind = (name: string) =>\n dupBoxedCache(name, LIB, \"g_value_dup_boxed\", [VALUE_T], boxedT(name, { ownership: \"full\", sharedLibrary: LIB }));\n\nconst booleanValueType = bindValueType(\"boolean\", booleanT);\nconst typeValueType = bindValueType(\"gtype\", biguint64T);\nconst intValueType = bindValueType(\"int\", int32T);\nconst uintValueType = bindValueType(\"uint\", uint32T);\nconst int64ValueType = bindValueType(\"int64\", bigint64T);\nconst uint64ValueType = bindValueType(\"uint64\", biguint64T);\nconst floatValueType = bindValueType(\"float\", float32T);\nconst doubleValueType = bindValueType(\"double\", float64T);\nconst stringValueType = bindValueType(\"string\", stringT(\"borrowed\"));\nconst enumValueType = bindValueType(\"enum\", int32T);\nconst flagsValueType = bindValueType(\"flags\", uint32T);\nconst objectValueType = bindValueType(\"object\", objectT(\"borrowed\"));\nconst paramValueType = bindValueType(\"param\", PARAM_T);\nconst variantValueType = bindValueType(\"variant\", VARIANT_T);\nconst pointerValueType = bindValueType(\"pointer\", uint64T);\n\nconst strvValueType: ValueType = {\n set: bind(LIB, \"g_value_set_boxed\", [VALUE_T, arrayT(stringT(\"borrowed\"))], voidT),\n get: bind(LIB, \"g_value_get_boxed\", [VALUE_T], arrayT(stringT(\"borrowed\"))),\n};\n\nconst boxedValueType = (type: bigint): ValueType => {\n const name = getBoxedTypeName(type);\n return { set: setBoxedBind(name), get: dupBoxedBind(name) };\n};\n\nconst enumOrFlagsValueType = (type: bigint): ValueType =>\n typeFundamental(type) === TYPE_FLAGS ? flagsValueType : enumValueType;\n\nconst fundamentalValueType = (type: bigint): ValueType => {\n switch (typeFundamental(type)) {\n case TYPE_PARAM:\n return paramValueType;\n case TYPE_VARIANT:\n return variantValueType;\n case TYPE_BOXED:\n return boxedValueType(type);\n default:\n throw new Error(`Unsupported fundamental type '${typeName(type) ?? String(type)}' for value`);\n }\n};\n\nexport function getValueType(value: ExternalObject<Handle>): bigint {\n return read(value, biguint64T, 0) as bigint;\n}\n\nexport function copyValue(dest: ExternalObject<Handle>, src: ExternalObject<Handle>): void {\n if (getValueType(dest) === TYPE_INVALID) {\n gValueInit(dest, getValueType(src));\n }\n gValueCopy(src, dest);\n}\n\nconst newTypedValue = (type: bigint): ExternalObject<Handle> => {\n const value = newValue();\n gValueInit(value, type);\n return value;\n};\n\nconst newBoxedValue = (\n descriptor: Descriptor,\n boxed: object,\n resolveSetBind: (name: string) => ValueType[\"set\"],\n): ExternalObject<Handle> => {\n const type = resolveDescriptorType(descriptor);\n const value = newTypedValue(type);\n resolveSetBind(getBoxedTypeName(type))(value, getHandle(boxed));\n return value;\n};\n\n/**\n * Reads the boxed pointer out of a GValue and returns it wrapped in its registered\n * class, or null when the value does not hold a boxed type.\n */\nexport function getBoxedValue(value: ExternalObject<Handle>): object | null {\n const type = getValueType(value);\n if (typeFundamental(type) !== TYPE_BOXED) return null;\n const cls = getWrapperClass(type);\n const boxed = dupBoxedBind(getBoxedTypeName(type))(value) as ExternalObject<Handle> | null;\n return wrapHandle(boxed, cls);\n}\n\n/** Stores a boxed object, or null, into a GValue that holds a boxed type. */\nexport function setBoxedValue(value: ExternalObject<Handle>, boxed: object | null): void {\n const name = getBoxedTypeName(getValueType(value));\n setBoxedBind(name)(value, boxed === null ? null : getHandle(boxed));\n}\n\nconst resolveValueType = (descriptor: Descriptor): ValueType => {\n if (descriptor.kind === \"biguint64\" && \"type\" in descriptor) {\n return typeValueType;\n }\n switch (descriptor.kind) {\n case \"boolean\":\n return booleanValueType;\n case \"string\":\n return stringValueType;\n case \"int8\":\n case \"int16\":\n case \"int32\":\n return intValueType;\n case \"uint8\":\n case \"uint16\":\n case \"uint32\":\n return uintValueType;\n case \"int64\":\n case \"bigint64\":\n return int64ValueType;\n case \"uint64\":\n case \"biguint64\":\n return uint64ValueType;\n case \"float32\":\n return floatValueType;\n case \"float64\":\n return doubleValueType;\n case \"object\":\n return objectValueType;\n case \"enum\":\n case \"flags\":\n return enumOrFlagsValueType(resolveType(descriptor.sharedLibrary, descriptor.getTypeFnName));\n case \"boxed\":\n return boxedValueType(resolveBoxedType(descriptor));\n case \"fundamental\":\n return fundamentalValueType(resolveFundamentalType(descriptor));\n case \"array\":\n if (descriptor.itemDescriptor.kind === \"string\" && descriptor.arrayKind === \"array\") {\n return strvValueType;\n }\n throw new Error(`Unsupported array type ${descriptor.arrayKind} of ${descriptor.itemDescriptor.kind}`);\n default:\n throw new Error(`Unsupported type descriptor '${descriptor.kind}'`);\n }\n};\n\nconst resolveValueGetter = (fundamental: bigint): ((value: ExternalObject<Handle>) => unknown) | undefined => {\n switch (fundamental) {\n case TYPE_BOOLEAN:\n return booleanValueType.get;\n case TYPE_GTYPE:\n return typeValueType.get;\n case TYPE_INT:\n return intValueType.get;\n case TYPE_UINT:\n return uintValueType.get;\n case TYPE_INT64:\n return int64ValueType.get;\n case TYPE_UINT64:\n return uint64ValueType.get;\n case TYPE_FLOAT:\n return floatValueType.get;\n case TYPE_DOUBLE:\n return doubleValueType.get;\n case TYPE_ENUM:\n return enumValueType.get;\n case TYPE_FLAGS:\n return flagsValueType.get;\n case TYPE_STRING:\n return (value) => stringValueType.get(value) ?? null;\n case TYPE_OBJECT:\n return (value) => wrapHandle(objectValueType.get(value) as ExternalObject<Handle> | null);\n case TYPE_PARAM:\n return (value) =>\n wrapHandle(paramValueType.get(value) as ExternalObject<Handle> | null, getWrapperClass(TYPE_PARAM));\n case TYPE_VARIANT:\n return (value) =>\n wrapHandle(variantValueType.get(value) as ExternalObject<Handle> | null, getWrapperClass(TYPE_VARIANT));\n case TYPE_BOXED:\n return getBoxedValue;\n case TYPE_POINTER:\n return (value) => {\n if (pointerValueType.get(value)) {\n throw new Error(\"G_TYPE_POINTER non-null values cannot be marshalled to JS\");\n }\n return null;\n };\n default:\n return undefined;\n }\n};\n\nexport function toValue(descriptor: Descriptor, value: unknown): ExternalObject<Handle> {\n const isHandleKind = descriptor.kind === \"object\" || descriptor.kind === \"boxed\";\n const nativeValue = isHandleKind\n ? value == null\n ? null\n : getHandle(value as object)\n : toNative(descriptor, value);\n const type =\n descriptor.kind === \"object\"\n ? nativeValue == null\n ? TYPE_OBJECT\n : getType(nativeValue as ExternalObject<Handle>)\n : resolveDescriptorType(descriptor);\n const gValue = newTypedValue(type);\n resolveValueType(descriptor).set(gValue, nativeValue);\n return gValue;\n}\n\nexport function fromValue(value: ExternalObject<Handle>): unknown {\n const type = getValueType(value);\n if (type === getStrvType()) return strvValueType.get(value);\n const get = resolveValueGetter(typeFundamental(type));\n if (get === undefined) {\n throw new Error(`Unsupported type for fromValue: ${typeName(type) ?? String(type)}`);\n }\n return get(value);\n}\n\nexport function newValueForDescriptor(descriptor: Descriptor): ExternalObject<Handle> {\n return newTypedValue(resolveDescriptorType(descriptor));\n}\n\nexport function outValueForDescriptor(\n descriptor: Descriptor,\n initial?: unknown,\n): { value: ExternalObject<Handle>; read: () => unknown } {\n const storage = alloc(8);\n write(storage, uint64T, 0, 0);\n if (initial !== undefined) write(storage, descriptor, 0, initial);\n const value = newTypedValue(TYPE_POINTER);\n pointerValueType.set(value, storage);\n return { value, read: () => read(storage, descriptor, 0) };\n}\n\nexport function outValueForBoxedDescriptor(descriptor: Descriptor, boxed: object): ExternalObject<Handle> {\n return newBoxedValue(descriptor, boxed, setBoxedBind);\n}\n\nexport function inoutValueForBoxedDescriptor(descriptor: Descriptor, boxed: object): ExternalObject<Handle> {\n return newBoxedValue(descriptor, boxed, setStaticBoxedBind);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,16 +1,59 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
"name": "@gtkx/runtime",
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
|
+
"description": "FFI runtime the generated GTKX bindings call into: type descriptors, GValue marshalling, signals, GObject lifecycle",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"gtkx",
|
|
7
|
+
"gtk",
|
|
8
|
+
"gtk4",
|
|
9
|
+
"ffi",
|
|
10
|
+
"bindings",
|
|
11
|
+
"typescript",
|
|
12
|
+
"linux",
|
|
13
|
+
"desktop"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://gtkx.dev",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/gtkx-org/gtkx/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/gtkx-org/gtkx.git",
|
|
22
|
+
"directory": "packages/runtime"
|
|
23
|
+
},
|
|
24
|
+
"license": "MPL-2.0",
|
|
25
|
+
"author": "Eugenio Depalo <eugeniodepalo@gmail.com>",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"sideEffects": true,
|
|
28
|
+
"exports": {
|
|
29
|
+
"./package.json": "./package.json",
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
12
33
|
},
|
|
13
|
-
"
|
|
14
|
-
|
|
34
|
+
"./internal": {
|
|
35
|
+
"types": "./dist/internal.d.ts",
|
|
36
|
+
"default": "./dist/internal.js"
|
|
15
37
|
}
|
|
16
|
-
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"src",
|
|
42
|
+
"!**/*.tsbuildinfo"
|
|
43
|
+
],
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=24"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@gtkx/native": "1.0.0-rc.1",
|
|
49
|
+
"@gtkx/utils": "1.0.0-rc.1"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@gtkx/vitest": "1.0.0-rc.1"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc -b tsconfig.lib.json",
|
|
56
|
+
"typecheck": "tsc -b --emitDeclarationOnly",
|
|
57
|
+
"release": "tsx ../../scripts/release-package.ts"
|
|
58
|
+
}
|
|
59
|
+
}
|
package/src/arg.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Descriptor } from "@gtkx/native";
|
|
2
|
+
|
|
3
|
+
export type Arg = {
|
|
4
|
+
type: Descriptor;
|
|
5
|
+
direction?: "out" | "inout";
|
|
6
|
+
callerAllocated?: boolean;
|
|
7
|
+
consumed?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const isOutputArg = (arg: Arg): boolean => arg.direction !== undefined;
|
|
11
|
+
export const isInoutArg = (arg: Arg): boolean => arg.direction === "inout";
|
|
12
|
+
export const isCallerAllocatedArg = (arg: Arg): boolean => arg.callerAllocated === true;
|
|
13
|
+
export const isRefArg = (arg: Arg): boolean => arg.direction !== undefined && arg.callerAllocated !== true;
|
package/src/bind.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { call, type Descriptor, bind as nativeBind } from "@gtkx/native";
|
|
2
|
+
|
|
3
|
+
export function bind(
|
|
4
|
+
sharedLibrary: string,
|
|
5
|
+
symbol: string,
|
|
6
|
+
argDescriptors: Descriptor[],
|
|
7
|
+
returnDescriptor: Descriptor,
|
|
8
|
+
): (...values: unknown[]) => unknown {
|
|
9
|
+
const descriptor = nativeBind(sharedLibrary, symbol, argDescriptors, returnDescriptor);
|
|
10
|
+
return (...values) => call(descriptor, values);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createBindCache(): (key: string, ...args: Parameters<typeof bind>) => ReturnType<typeof bind> {
|
|
14
|
+
const cache = new Map<string, ReturnType<typeof bind>>();
|
|
15
|
+
return (key, ...args) => {
|
|
16
|
+
const existing = cache.get(key);
|
|
17
|
+
if (existing !== undefined) return existing;
|
|
18
|
+
const bound = bind(...args);
|
|
19
|
+
cache.set(key, bound);
|
|
20
|
+
return bound;
|
|
21
|
+
};
|
|
22
|
+
}
|
package/src/callback.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { copy, type Descriptor } from "@gtkx/native";
|
|
2
|
+
import type { CallbackDescriptor } from "./descriptors.js";
|
|
3
|
+
import { fromNative, toNative } from "./native-value.js";
|
|
4
|
+
import { getHandle } from "./registry.js";
|
|
5
|
+
import { splitTupleResult } from "./tuple.js";
|
|
6
|
+
import { copyValue } from "./value.js";
|
|
7
|
+
|
|
8
|
+
type Callback = (...args: unknown[]) => unknown;
|
|
9
|
+
type CallbackReceiver = "this" | "emitter" | "none";
|
|
10
|
+
type OutParam = { value: unknown; descriptor: Descriptor };
|
|
11
|
+
|
|
12
|
+
type CallbackSpec = {
|
|
13
|
+
argDescriptors: Descriptor[];
|
|
14
|
+
returnDescriptor: Descriptor;
|
|
15
|
+
userDataIndex?: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {
|
|
19
|
+
if (descriptor.kind === "boxed" && descriptor.typeName === "GValue") {
|
|
20
|
+
copyValue(getHandle(target), getHandle(source));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if ((descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.size !== undefined) {
|
|
24
|
+
copy(getHandle(target), getHandle(source), descriptor.size);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
throw new Error(`Cannot write caller-allocated ${descriptor.kind} out-parameter: no known byte size`);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const partitionCallbackArgs = (
|
|
31
|
+
effectiveTypes: Descriptor[],
|
|
32
|
+
wrapped: unknown[],
|
|
33
|
+
start: number,
|
|
34
|
+
): { inputs: unknown[]; outParams: OutParam[] } => {
|
|
35
|
+
const inputs: unknown[] = [];
|
|
36
|
+
const outParams: OutParam[] = [];
|
|
37
|
+
for (let i = start; i < effectiveTypes.length; i++) {
|
|
38
|
+
const descriptor = effectiveTypes[i];
|
|
39
|
+
if (descriptor !== undefined && descriptor.kind === "ref") {
|
|
40
|
+
if (descriptor.inout === true) inputs.push((wrapped[i] as { value: unknown }).value);
|
|
41
|
+
outParams.push({ value: wrapped[i], descriptor });
|
|
42
|
+
} else if (
|
|
43
|
+
descriptor !== undefined &&
|
|
44
|
+
(descriptor.kind === "boxed" || descriptor.kind === "struct") &&
|
|
45
|
+
descriptor.callerAllocated === true
|
|
46
|
+
) {
|
|
47
|
+
inputs.push(wrapped[i]);
|
|
48
|
+
outParams.push({ value: wrapped[i], descriptor });
|
|
49
|
+
} else {
|
|
50
|
+
inputs.push(wrapped[i]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { inputs, outParams };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const writeOutParams = (outParams: OutParam[], outValues: unknown[]): void => {
|
|
57
|
+
outParams.forEach((outParam, position) => {
|
|
58
|
+
const outValue = outValues[position];
|
|
59
|
+
if (outParam.descriptor.kind === "ref") {
|
|
60
|
+
(outParam.value as { value: unknown }).value = outValue;
|
|
61
|
+
} else if (outValue != null && outParam.value != null) {
|
|
62
|
+
fillCallerAllocatedBuffer(outParam.descriptor, outParam.value as object, outValue as object);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>
|
|
68
|
+
callback == null ? callback : wrapCallback(callback as Callback, spec, "none");
|
|
69
|
+
|
|
70
|
+
export function wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {
|
|
71
|
+
const { returnDescriptor, userDataIndex } = spec;
|
|
72
|
+
const effectiveTypes =
|
|
73
|
+
userDataIndex === undefined ? spec.argDescriptors : spec.argDescriptors.filter((_, i) => i !== userDataIndex);
|
|
74
|
+
const start = receiver === "none" ? 0 : 1;
|
|
75
|
+
return (...rawArgs: unknown[]): unknown => {
|
|
76
|
+
const wrapped = effectiveTypes.map((descriptor, i) => fromNative(descriptor, rawArgs[i]));
|
|
77
|
+
const thisArg = receiver === "this" ? (wrapped[0] ?? null) : null;
|
|
78
|
+
const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, wrapped, start);
|
|
79
|
+
const result = (fn as (this: unknown, ...args: unknown[]) => unknown).apply(thisArg, inputs);
|
|
80
|
+
if (outParams.length === 0) {
|
|
81
|
+
return toNative(returnDescriptor, result);
|
|
82
|
+
}
|
|
83
|
+
const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== "void", outParams.length);
|
|
84
|
+
writeOutParams(outParams, outValues);
|
|
85
|
+
return toNative(returnDescriptor, primary);
|
|
86
|
+
};
|
|
87
|
+
}
|