@gtkx/runtime 0.0.1 → 1.0.0-rc.2
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 +13 -0
- package/dist/arg.d.ts.map +1 -0
- package/dist/arg.js +6 -0
- package/dist/arg.js.map +1 -0
- package/dist/bind.d.ts +5 -0
- package/dist/bind.d.ts.map +1 -0
- package/dist/bind.js +19 -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 +86 -0
- package/dist/callback.js.map +1 -0
- package/dist/descriptors.d.ts +158 -0
- package/dist/descriptors.d.ts.map +1 -0
- package/dist/descriptors.js +135 -0
- package/dist/descriptors.js.map +1 -0
- package/dist/error.d.ts +24 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +33 -0
- package/dist/error.js.map +1 -0
- package/dist/exit-hook.d.ts +2 -0
- package/dist/exit-hook.d.ts.map +1 -0
- package/dist/exit-hook.js +3 -0
- package/dist/exit-hook.js.map +1 -0
- package/dist/fn.d.ts +10 -0
- package/dist/fn.d.ts.map +1 -0
- package/dist/fn.js +90 -0
- package/dist/fn.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -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 +8 -0
- package/dist/library.d.ts.map +1 -0
- package/dist/library.js +14 -0
- package/dist/library.js.map +1 -0
- package/dist/lifecycle.d.ts +42 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +70 -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 +85 -0
- package/dist/listeners.js.map +1 -0
- package/dist/mixin.d.ts +13 -0
- package/dist/mixin.d.ts.map +1 -0
- package/dist/mixin.js +49 -0
- package/dist/mixin.js.map +1 -0
- package/dist/native-value.d.ts +13 -0
- package/dist/native-value.d.ts.map +1 -0
- package/dist/native-value.js +105 -0
- package/dist/native-value.js.map +1 -0
- package/dist/object.d.ts +32 -0
- package/dist/object.d.ts.map +1 -0
- package/dist/object.js +66 -0
- package/dist/object.js.map +1 -0
- package/dist/promisify.d.ts +21 -0
- package/dist/promisify.d.ts.map +1 -0
- package/dist/promisify.js +39 -0
- package/dist/promisify.js.map +1 -0
- package/dist/properties.d.ts +14 -0
- package/dist/properties.d.ts.map +1 -0
- package/dist/properties.js +79 -0
- package/dist/properties.js.map +1 -0
- package/dist/register-class.d.ts +25 -0
- package/dist/register-class.d.ts.map +1 -0
- package/dist/register-class.js +178 -0
- package/dist/register-class.js.map +1 -0
- package/dist/registry.d.ts +69 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +186 -0
- package/dist/registry.js.map +1 -0
- package/dist/signal.d.ts +35 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +95 -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 +49 -0
- package/dist/t.js.map +1 -0
- package/dist/tuple.d.ts +7 -0
- package/dist/tuple.d.ts.map +1 -0
- package/dist/tuple.js +26 -0
- package/dist/tuple.js.map +1 -0
- package/dist/type.d.ts +88 -0
- package/dist/type.d.ts.map +1 -0
- package/dist/type.js +194 -0
- package/dist/type.js.map +1 -0
- package/dist/value.d.ts +29 -0
- package/dist/value.d.ts.map +1 -0
- package/dist/value.js +292 -0
- package/dist/value.js.map +1 -0
- package/package.json +54 -13
- package/src/arg.ts +15 -0
- package/src/bind.ts +31 -0
- package/src/callback.ts +149 -0
- package/src/descriptors.ts +350 -0
- package/src/error.ts +58 -0
- package/src/exit-hook.ts +3 -0
- package/src/fn.ts +139 -0
- package/src/index.ts +59 -0
- package/src/internal.ts +12 -0
- package/src/library.ts +17 -0
- package/src/lifecycle.ts +101 -0
- package/src/listeners.ts +112 -0
- package/src/mixin.ts +73 -0
- package/src/native-value.ts +135 -0
- package/src/object.ts +95 -0
- package/src/promisify.ts +67 -0
- package/src/properties.ts +115 -0
- package/src/register-class.ts +305 -0
- package/src/registry.ts +311 -0
- package/src/signal.ts +192 -0
- package/src/t.ts +90 -0
- package/src/tuple.ts +37 -0
- package/src/type.ts +290 -0
- package/src/value.ts +430 -0
package/src/value.ts
ADDED
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import { alloc, type Descriptor, type ExternalObject, getType, type Handle, read, write } from "@gtkx/native";
|
|
2
|
+
import { bind, createBindCache } from "./bind.js";
|
|
3
|
+
import {
|
|
4
|
+
type ArrayDescriptor,
|
|
5
|
+
arrayT,
|
|
6
|
+
bigint64T,
|
|
7
|
+
biguint64T,
|
|
8
|
+
booleanT,
|
|
9
|
+
boxedT,
|
|
10
|
+
float32T,
|
|
11
|
+
float64T,
|
|
12
|
+
int32T,
|
|
13
|
+
objectT,
|
|
14
|
+
stringT,
|
|
15
|
+
uint32T,
|
|
16
|
+
uint64T,
|
|
17
|
+
voidT,
|
|
18
|
+
} from "./descriptors.js";
|
|
19
|
+
import { LIB, PARAM_T, VALUE_SIZE, VALUE_T, VARIANT_T } from "./library.js";
|
|
20
|
+
import { toNative } from "./native-value.js";
|
|
21
|
+
import { getHandle, getWrapperClass, wrapHandle } from "./registry.js";
|
|
22
|
+
import {
|
|
23
|
+
getStrvType,
|
|
24
|
+
isResolvableDescriptor,
|
|
25
|
+
resolveBoxedType,
|
|
26
|
+
resolveDescriptorType,
|
|
27
|
+
resolveFundamentalType,
|
|
28
|
+
resolveType,
|
|
29
|
+
TYPE_BOOLEAN,
|
|
30
|
+
TYPE_BOXED,
|
|
31
|
+
TYPE_DOUBLE,
|
|
32
|
+
TYPE_ENUM,
|
|
33
|
+
TYPE_FLAGS,
|
|
34
|
+
TYPE_FLOAT,
|
|
35
|
+
TYPE_GTYPE,
|
|
36
|
+
TYPE_INT,
|
|
37
|
+
TYPE_INT64,
|
|
38
|
+
TYPE_INVALID,
|
|
39
|
+
TYPE_OBJECT,
|
|
40
|
+
TYPE_PARAM,
|
|
41
|
+
TYPE_POINTER,
|
|
42
|
+
TYPE_STRING,
|
|
43
|
+
TYPE_UINT,
|
|
44
|
+
TYPE_UINT64,
|
|
45
|
+
TYPE_VARIANT,
|
|
46
|
+
typeFundamental,
|
|
47
|
+
typeName,
|
|
48
|
+
} from "./type.js";
|
|
49
|
+
|
|
50
|
+
type ValueType = {
|
|
51
|
+
set: (value: ExternalObject<Handle>, nativeValue: unknown) => void;
|
|
52
|
+
get: (value: ExternalObject<Handle>) => unknown;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type ValueGetter = (value: ExternalObject<Handle>) => unknown;
|
|
56
|
+
|
|
57
|
+
const setBoxedCache = createBindCache();
|
|
58
|
+
const setStaticBoxedCache = createBindCache();
|
|
59
|
+
const dupBoxedCache = createBindCache();
|
|
60
|
+
const gValueInit = bind(LIB, "g_value_init", [VALUE_T, biguint64T], voidT);
|
|
61
|
+
const gValueCopy = bind(LIB, "g_value_copy", [VALUE_T, VALUE_T], voidT);
|
|
62
|
+
const booleanValueType = bindValueType("boolean", booleanT);
|
|
63
|
+
const typeValueType = bindValueType("gtype", biguint64T);
|
|
64
|
+
const intValueType = bindValueType("int", int32T);
|
|
65
|
+
const uintValueType = bindValueType("uint", uint32T);
|
|
66
|
+
const int64ValueType = bindValueType("int64", bigint64T);
|
|
67
|
+
const uint64ValueType = bindValueType("uint64", biguint64T);
|
|
68
|
+
const floatValueType = bindValueType("float", float32T);
|
|
69
|
+
const doubleValueType = bindValueType("double", float64T);
|
|
70
|
+
const stringValueType = bindValueType("string", stringT("borrowed"));
|
|
71
|
+
const enumValueType = bindValueType("enum", int32T);
|
|
72
|
+
const flagsValueType = bindValueType("flags", uint32T);
|
|
73
|
+
const objectValueType = bindValueType("object", objectT("borrowed"));
|
|
74
|
+
const paramValueType = bindValueType("param", PARAM_T);
|
|
75
|
+
const variantValueType = bindValueType("variant", VARIANT_T);
|
|
76
|
+
const pointerValueType = bindValueType("pointer", uint64T);
|
|
77
|
+
|
|
78
|
+
const strvValueType: ValueType = {
|
|
79
|
+
set: bind(LIB, "g_value_set_boxed", [VALUE_T, arrayT(stringT("borrowed"))], voidT),
|
|
80
|
+
get: bind(LIB, "g_value_get_boxed", [VALUE_T], arrayT(stringT("borrowed"))),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const PLAIN_VALUE_TYPES: Partial<Record<Descriptor["kind"], ValueType>> = {
|
|
84
|
+
boolean: booleanValueType,
|
|
85
|
+
string: stringValueType,
|
|
86
|
+
int8: intValueType,
|
|
87
|
+
int16: intValueType,
|
|
88
|
+
int32: intValueType,
|
|
89
|
+
uint8: uintValueType,
|
|
90
|
+
uint16: uintValueType,
|
|
91
|
+
uint32: uintValueType,
|
|
92
|
+
int64: int64ValueType,
|
|
93
|
+
bigint64: int64ValueType,
|
|
94
|
+
uint64: uint64ValueType,
|
|
95
|
+
biguint64: uint64ValueType,
|
|
96
|
+
float32: floatValueType,
|
|
97
|
+
float64: doubleValueType,
|
|
98
|
+
object: objectValueType,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const PLAIN_VALUE_GETTERS: Map<bigint, ValueGetter> = new Map([
|
|
102
|
+
[TYPE_BOOLEAN, booleanValueType.get],
|
|
103
|
+
[TYPE_GTYPE, typeValueType.get],
|
|
104
|
+
[TYPE_INT, intValueType.get],
|
|
105
|
+
[TYPE_UINT, uintValueType.get],
|
|
106
|
+
[TYPE_INT64, int64ValueType.get],
|
|
107
|
+
[TYPE_UINT64, uint64ValueType.get],
|
|
108
|
+
[TYPE_FLOAT, floatValueType.get],
|
|
109
|
+
[TYPE_DOUBLE, doubleValueType.get],
|
|
110
|
+
[TYPE_ENUM, enumValueType.get],
|
|
111
|
+
[TYPE_FLAGS, flagsValueType.get],
|
|
112
|
+
]);
|
|
113
|
+
|
|
114
|
+
const PLAIN_VALUE_SETTERS: Map<bigint, ValueType["set"]> = new Map([
|
|
115
|
+
[TYPE_BOOLEAN, booleanValueType.set],
|
|
116
|
+
[TYPE_GTYPE, typeValueType.set],
|
|
117
|
+
[TYPE_INT, intValueType.set],
|
|
118
|
+
[TYPE_UINT, uintValueType.set],
|
|
119
|
+
[TYPE_INT64, int64ValueType.set],
|
|
120
|
+
[TYPE_UINT64, uint64ValueType.set],
|
|
121
|
+
[TYPE_FLOAT, floatValueType.set],
|
|
122
|
+
[TYPE_DOUBLE, doubleValueType.set],
|
|
123
|
+
[TYPE_ENUM, enumValueType.set],
|
|
124
|
+
[TYPE_FLAGS, flagsValueType.set],
|
|
125
|
+
]);
|
|
126
|
+
|
|
127
|
+
const WRAPPED_VALUE_SETTERS: Map<bigint, ValueType["set"]> = new Map([
|
|
128
|
+
[TYPE_STRING, setStringValue],
|
|
129
|
+
[TYPE_OBJECT, handleSetter(objectValueType)],
|
|
130
|
+
[TYPE_PARAM, handleSetter(paramValueType)],
|
|
131
|
+
[TYPE_VARIANT, handleSetter(variantValueType)],
|
|
132
|
+
[TYPE_BOXED, setBoxedFromValue],
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
const getBoxedTypeName = (type: bigint): string => typeName(type) ?? "GBoxed";
|
|
136
|
+
const newValue = (): ExternalObject<Handle> => alloc(VALUE_SIZE, resolveBoxedType(VALUE_T));
|
|
137
|
+
|
|
138
|
+
function bindValueType(symbol: string, descriptor: Descriptor): ValueType {
|
|
139
|
+
return {
|
|
140
|
+
set: bind(LIB, `g_value_set_${symbol}`, [VALUE_T, descriptor], voidT),
|
|
141
|
+
get: bind(LIB, `g_value_get_${symbol}`, [VALUE_T], descriptor),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const setBoxedBind = (name: string) =>
|
|
146
|
+
setBoxedCache(name, LIB, "g_value_set_boxed", [VALUE_T, boxedT(name, { sharedLibrary: LIB })], voidT);
|
|
147
|
+
|
|
148
|
+
const setStaticBoxedBind = (name: string) =>
|
|
149
|
+
setStaticBoxedCache(name, LIB, "g_value_set_static_boxed", [VALUE_T, boxedT(name, { sharedLibrary: LIB })], voidT);
|
|
150
|
+
|
|
151
|
+
const dupBoxedBind = (name: string) =>
|
|
152
|
+
dupBoxedCache(name, LIB, "g_value_dup_boxed", [VALUE_T], boxedT(name, { ownership: "full", sharedLibrary: LIB }));
|
|
153
|
+
|
|
154
|
+
const boxedValueType = (type: bigint): ValueType => {
|
|
155
|
+
const name = getBoxedTypeName(type);
|
|
156
|
+
|
|
157
|
+
return { set: setBoxedBind(name), get: dupBoxedBind(name) };
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const enumOrFlagsValueType = (type: bigint): ValueType =>
|
|
161
|
+
typeFundamental(type) === TYPE_FLAGS ? flagsValueType : enumValueType;
|
|
162
|
+
|
|
163
|
+
const fundamentalValueType = (type: bigint): ValueType => {
|
|
164
|
+
switch (typeFundamental(type)) {
|
|
165
|
+
case TYPE_PARAM: {
|
|
166
|
+
return paramValueType;
|
|
167
|
+
}
|
|
168
|
+
case TYPE_VARIANT: {
|
|
169
|
+
return variantValueType;
|
|
170
|
+
}
|
|
171
|
+
case TYPE_BOXED: {
|
|
172
|
+
return boxedValueType(type);
|
|
173
|
+
}
|
|
174
|
+
default: {
|
|
175
|
+
throw new Error(`Unsupported fundamental type '${typeName(type) ?? String(type)}' for value`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
function getValueType(value: ExternalObject<Handle>): bigint {
|
|
181
|
+
return read(value, biguint64T, 0) as bigint;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function copyValue(dest: ExternalObject<Handle>, src: ExternalObject<Handle>): void {
|
|
185
|
+
if (getValueType(dest) === TYPE_INVALID) {
|
|
186
|
+
gValueInit(dest, getValueType(src));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
gValueCopy(src, dest);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const newTypedValue = (type: bigint): ExternalObject<Handle> => {
|
|
193
|
+
const value = newValue();
|
|
194
|
+
gValueInit(value, type);
|
|
195
|
+
|
|
196
|
+
return value;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const newBoxedValue = (
|
|
200
|
+
descriptor: Descriptor,
|
|
201
|
+
boxed: object,
|
|
202
|
+
resolveSetBind: (name: string) => ValueType["set"],
|
|
203
|
+
): ExternalObject<Handle> => {
|
|
204
|
+
const type = resolveDescriptorType(descriptor);
|
|
205
|
+
const value = newTypedValue(type);
|
|
206
|
+
resolveSetBind(getBoxedTypeName(type))(value, getHandle(boxed));
|
|
207
|
+
|
|
208
|
+
return value;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Reads the boxed pointer out of a GValue and returns it wrapped in its registered
|
|
213
|
+
* class, or null when the value does not hold a boxed type.
|
|
214
|
+
*/
|
|
215
|
+
function getBoxedValue(value: ExternalObject<Handle>): object | null {
|
|
216
|
+
const type = getValueType(value);
|
|
217
|
+
|
|
218
|
+
if (typeFundamental(type) !== TYPE_BOXED) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const cls = getWrapperClass(type);
|
|
223
|
+
const boxed = dupBoxedBind(getBoxedTypeName(type))(value) as ExternalObject<Handle> | null;
|
|
224
|
+
|
|
225
|
+
return wrapHandle(boxed, cls);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Stores a boxed object, or null, into a GValue that holds a boxed type. */
|
|
229
|
+
function setBoxedValue(value: ExternalObject<Handle>, boxed: object | null): void {
|
|
230
|
+
const name = getBoxedTypeName(getValueType(value));
|
|
231
|
+
setBoxedBind(name)(value, boxed === null ? null : getHandle(boxed));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const arrayValueType = (descriptor: ArrayDescriptor): ValueType => {
|
|
235
|
+
if (descriptor.itemDescriptor.kind === "string" && descriptor.arrayKind === "array") {
|
|
236
|
+
return strvValueType;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
throw new Error(`Unsupported array type ${descriptor.arrayKind} of ${descriptor.itemDescriptor.kind}`);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
const resolveValueType = (descriptor: Descriptor): ValueType => {
|
|
243
|
+
if (descriptor.kind === "biguint64" && "type" in descriptor) {
|
|
244
|
+
return typeValueType;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const plain = PLAIN_VALUE_TYPES[descriptor.kind];
|
|
248
|
+
|
|
249
|
+
if (plain !== undefined) {
|
|
250
|
+
return plain;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (!isResolvableDescriptor(descriptor)) {
|
|
254
|
+
throw new Error(`Unsupported type descriptor '${descriptor.kind}'`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
switch (descriptor.kind) {
|
|
258
|
+
case "enum":
|
|
259
|
+
case "flags": {
|
|
260
|
+
return enumOrFlagsValueType(resolveType(descriptor.sharedLibrary, descriptor.getTypeFnName));
|
|
261
|
+
}
|
|
262
|
+
case "boxed": {
|
|
263
|
+
return boxedValueType(resolveBoxedType(descriptor));
|
|
264
|
+
}
|
|
265
|
+
case "fundamental": {
|
|
266
|
+
return fundamentalValueType(resolveFundamentalType(descriptor));
|
|
267
|
+
}
|
|
268
|
+
case "array": {
|
|
269
|
+
return arrayValueType(descriptor);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
const wrappedValueGetter = (fundamental: bigint): ValueGetter | undefined => {
|
|
275
|
+
switch (fundamental) {
|
|
276
|
+
case TYPE_STRING: {
|
|
277
|
+
return (value) => stringValueType.get(value) ?? null;
|
|
278
|
+
}
|
|
279
|
+
case TYPE_OBJECT: {
|
|
280
|
+
return (value) => wrapHandle(objectValueType.get(value) as ExternalObject<Handle> | null);
|
|
281
|
+
}
|
|
282
|
+
case TYPE_PARAM: {
|
|
283
|
+
return (value) =>
|
|
284
|
+
wrapHandle(paramValueType.get(value) as ExternalObject<Handle> | null, getWrapperClass(TYPE_PARAM));
|
|
285
|
+
}
|
|
286
|
+
case TYPE_VARIANT: {
|
|
287
|
+
return (value) =>
|
|
288
|
+
wrapHandle(variantValueType.get(value) as ExternalObject<Handle> | null, getWrapperClass(TYPE_VARIANT));
|
|
289
|
+
}
|
|
290
|
+
case TYPE_BOXED: {
|
|
291
|
+
return getBoxedValue;
|
|
292
|
+
}
|
|
293
|
+
case TYPE_POINTER: {
|
|
294
|
+
return (value) => {
|
|
295
|
+
if (pointerValueType.get(value)) {
|
|
296
|
+
throw new Error("G_TYPE_POINTER non-null values cannot be marshalled to JS");
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return null;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
default: {
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
function setStringValue(value: ExternalObject<Handle>, nativeValue: unknown): void {
|
|
309
|
+
stringValueType.set(value, nativeValue ?? null);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function handleSetter(target: ValueType): ValueType["set"] {
|
|
313
|
+
return (value, nativeValue) => {
|
|
314
|
+
target.set(value, nativeValue == null ? null : getHandle(nativeValue));
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function setBoxedFromValue(value: ExternalObject<Handle>, nativeValue: unknown): void {
|
|
319
|
+
setBoxedValue(value, nativeValue ?? null);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const resolveValueGetter = (fundamental: bigint): ValueGetter | undefined =>
|
|
323
|
+
PLAIN_VALUE_GETTERS.get(fundamental) ?? wrappedValueGetter(fundamental);
|
|
324
|
+
|
|
325
|
+
const resolveValueSetter = (fundamental: bigint): ValueType["set"] | undefined =>
|
|
326
|
+
PLAIN_VALUE_SETTERS.get(fundamental) ?? WRAPPED_VALUE_SETTERS.get(fundamental);
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Stores a JavaScript value into an already-initialized GValue, converting it to
|
|
330
|
+
* whatever type the GValue holds.
|
|
331
|
+
*
|
|
332
|
+
* @param value The initialized GValue to write into.
|
|
333
|
+
* @param jsValue The JavaScript value to store.
|
|
334
|
+
*/
|
|
335
|
+
function intoValue(value: ExternalObject<Handle>, jsValue: unknown): void {
|
|
336
|
+
const type = getValueType(value);
|
|
337
|
+
const set = resolveValueSetter(typeFundamental(type));
|
|
338
|
+
|
|
339
|
+
if (set === undefined) {
|
|
340
|
+
throw new Error(`Unsupported type for intoValue: ${typeName(type) ?? String(type)}`);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
set(value, jsValue);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const resolveNativeValue = (descriptor: Descriptor, value: unknown): unknown => {
|
|
347
|
+
const isHandleKind = descriptor.kind === "object" || descriptor.kind === "boxed";
|
|
348
|
+
|
|
349
|
+
if (!isHandleKind) {
|
|
350
|
+
return toNative(descriptor, value);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return value == null ? null : getHandle(value);
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
const resolveValueGType = (descriptor: Descriptor, nativeValue: unknown): bigint => {
|
|
357
|
+
if (descriptor.kind !== "object") {
|
|
358
|
+
return resolveDescriptorType(descriptor);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return nativeValue == null ? TYPE_OBJECT : getType(nativeValue as ExternalObject<Handle>);
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
function toValue(descriptor: Descriptor, value: unknown): ExternalObject<Handle> {
|
|
365
|
+
const nativeValue = resolveNativeValue(descriptor, value);
|
|
366
|
+
const type = resolveValueGType(descriptor, nativeValue);
|
|
367
|
+
const gValue = newTypedValue(type);
|
|
368
|
+
resolveValueType(descriptor).set(gValue, nativeValue);
|
|
369
|
+
|
|
370
|
+
return gValue;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function fromValue(value: ExternalObject<Handle>): unknown {
|
|
374
|
+
const type = getValueType(value);
|
|
375
|
+
|
|
376
|
+
if (type === getStrvType()) {
|
|
377
|
+
return strvValueType.get(value);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const get = resolveValueGetter(typeFundamental(type));
|
|
381
|
+
|
|
382
|
+
if (get === undefined) {
|
|
383
|
+
throw new Error(`Unsupported type for fromValue: ${typeName(type) ?? String(type)}`);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return get(value);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function newValueForDescriptor(descriptor: Descriptor): ExternalObject<Handle> {
|
|
390
|
+
return newTypedValue(resolveDescriptorType(descriptor));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function outValueForDescriptor(
|
|
394
|
+
descriptor: Descriptor,
|
|
395
|
+
initial?: unknown,
|
|
396
|
+
): { value: ExternalObject<Handle>; read: () => unknown } {
|
|
397
|
+
const storage = alloc(8);
|
|
398
|
+
write(storage, uint64T, 0, 0);
|
|
399
|
+
|
|
400
|
+
if (initial !== undefined) {
|
|
401
|
+
write(storage, descriptor, 0, initial);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const value = newTypedValue(TYPE_POINTER);
|
|
405
|
+
pointerValueType.set(value, storage);
|
|
406
|
+
|
|
407
|
+
return { value, read: () => read(storage, descriptor, 0) };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function outValueForBoxedDescriptor(descriptor: Descriptor, boxed: object): ExternalObject<Handle> {
|
|
411
|
+
return newBoxedValue(descriptor, boxed, setBoxedBind);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function inoutValueForBoxedDescriptor(descriptor: Descriptor, boxed: object): ExternalObject<Handle> {
|
|
415
|
+
return newBoxedValue(descriptor, boxed, setStaticBoxedBind);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
export {
|
|
419
|
+
getValueType,
|
|
420
|
+
intoValue,
|
|
421
|
+
copyValue,
|
|
422
|
+
getBoxedValue,
|
|
423
|
+
setBoxedValue,
|
|
424
|
+
toValue,
|
|
425
|
+
fromValue,
|
|
426
|
+
newValueForDescriptor,
|
|
427
|
+
outValueForDescriptor,
|
|
428
|
+
outValueForBoxedDescriptor,
|
|
429
|
+
inoutValueForBoxedDescriptor,
|
|
430
|
+
};
|