@gtkx/runtime 1.0.0-rc.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/dist/arg.d.ts +6 -5
- package/dist/arg.d.ts.map +1 -1
- package/dist/arg.js +5 -4
- package/dist/arg.js.map +1 -1
- package/dist/bind.d.ts +3 -2
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +5 -3
- package/dist/bind.js.map +1 -1
- package/dist/callback.d.ts +3 -3
- package/dist/callback.d.ts.map +1 -1
- package/dist/callback.js +51 -33
- package/dist/callback.js.map +1 -1
- package/dist/descriptors.d.ts +67 -64
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +92 -60
- package/dist/descriptors.js.map +1 -1
- package/dist/error.d.ts +5 -6
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +10 -6
- package/dist/error.js.map +1 -1
- 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 +2 -2
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +26 -15
- package/dist/fn.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/library.d.ts +6 -5
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +6 -5
- package/dist/library.js.map +1 -1
- package/dist/lifecycle.d.ts +10 -9
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +38 -23
- package/dist/lifecycle.js.map +1 -1
- package/dist/listeners.d.ts +8 -8
- package/dist/listeners.d.ts.map +1 -1
- package/dist/listeners.js +28 -15
- package/dist/listeners.js.map +1 -1
- package/dist/mixin.d.ts +5 -11
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +24 -14
- package/dist/mixin.js.map +1 -1
- package/dist/native-value.d.ts +3 -2
- package/dist/native-value.d.ts.map +1 -1
- package/dist/native-value.js +75 -42
- package/dist/native-value.js.map +1 -1
- package/dist/object.d.ts +4 -3
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +8 -5
- package/dist/object.js.map +1 -1
- package/dist/promisify.d.ts +9 -1
- package/dist/promisify.d.ts.map +1 -1
- package/dist/promisify.js +18 -15
- package/dist/promisify.js.map +1 -1
- 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 +10 -2
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +83 -29
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +23 -21
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +54 -35
- package/dist/registry.js.map +1 -1
- package/dist/signal.d.ts +7 -6
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +19 -12
- package/dist/signal.js.map +1 -1
- package/dist/t.d.ts +2 -2
- package/dist/t.d.ts.map +1 -1
- package/dist/t.js +2 -1
- package/dist/t.js.map +1 -1
- package/dist/tuple.d.ts +3 -2
- package/dist/tuple.d.ts.map +1 -1
- package/dist/tuple.js +7 -4
- package/dist/tuple.js.map +1 -1
- package/dist/type.d.ts +48 -41
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +107 -87
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts +19 -10
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +164 -99
- package/dist/value.js.map +1 -1
- package/package.json +4 -6
- package/src/arg.ts +7 -5
- package/src/bind.ts +13 -4
- package/src/callback.ts +97 -35
- package/src/descriptors.ts +227 -85
- package/src/error.ts +18 -9
- package/src/exit-hook.ts +3 -0
- package/src/fn.ts +53 -22
- package/src/index.ts +4 -2
- package/src/library.ts +7 -5
- package/src/lifecycle.ts +54 -26
- package/src/listeners.ts +46 -18
- package/src/mixin.ts +39 -14
- package/src/native-value.ts +103 -46
- package/src/object.ts +19 -7
- package/src/promisify.ts +42 -15
- package/src/properties.ts +115 -0
- package/src/register-class.ts +157 -30
- package/src/registry.ts +144 -54
- package/src/signal.ts +53 -13
- package/src/t.ts +3 -1
- package/src/tuple.ts +16 -4
- package/src/type.ts +183 -93
- package/src/value.ts +231 -108
package/src/callback.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { copy, type Descriptor } from "@gtkx/native";
|
|
2
|
-
import type { CallbackDescriptor } from "./descriptors.js";
|
|
2
|
+
import type { CallbackDescriptor, RefDescriptor } from "./descriptors.js";
|
|
3
3
|
import { fromNative, toNative } from "./native-value.js";
|
|
4
4
|
import { getHandle } from "./registry.js";
|
|
5
5
|
import { splitTupleResult } from "./tuple.js";
|
|
@@ -15,18 +15,65 @@ type CallbackSpec = {
|
|
|
15
15
|
userDataIndex?: number;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
type CallbackPlan = {
|
|
19
|
+
fn: Callback;
|
|
20
|
+
effectiveTypes: Descriptor[];
|
|
21
|
+
returnDescriptor: Descriptor;
|
|
22
|
+
start: number;
|
|
23
|
+
receiver: CallbackReceiver;
|
|
24
|
+
};
|
|
25
|
+
|
|
18
26
|
const fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {
|
|
19
27
|
if (descriptor.kind === "boxed" && descriptor.typeName === "GValue") {
|
|
20
28
|
copyValue(getHandle(target), getHandle(source));
|
|
29
|
+
|
|
21
30
|
return;
|
|
22
31
|
}
|
|
32
|
+
|
|
23
33
|
if ((descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.size !== undefined) {
|
|
24
34
|
copy(getHandle(target), getHandle(source), descriptor.size);
|
|
35
|
+
|
|
25
36
|
return;
|
|
26
37
|
}
|
|
38
|
+
|
|
27
39
|
throw new Error(`Cannot write caller-allocated ${descriptor.kind} out-parameter: no known byte size`);
|
|
28
40
|
};
|
|
29
41
|
|
|
42
|
+
const isCallerAllocatedOut = (descriptor: Descriptor): boolean =>
|
|
43
|
+
(descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.callerAllocated === true;
|
|
44
|
+
|
|
45
|
+
const collectRefArg = (
|
|
46
|
+
descriptor: RefDescriptor,
|
|
47
|
+
wrappedValue: unknown,
|
|
48
|
+
inputs: unknown[],
|
|
49
|
+
outParams: OutParam[],
|
|
50
|
+
): void => {
|
|
51
|
+
if (descriptor.inout === true) {
|
|
52
|
+
inputs.push((wrappedValue as { value: unknown }).value);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
outParams.push({ value: wrappedValue, descriptor });
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const collectCallbackArg = (
|
|
59
|
+
descriptor: Descriptor | undefined,
|
|
60
|
+
wrappedValue: unknown,
|
|
61
|
+
inputs: unknown[],
|
|
62
|
+
outParams: OutParam[],
|
|
63
|
+
): void => {
|
|
64
|
+
if (descriptor?.kind === "ref") {
|
|
65
|
+
collectRefArg(descriptor, wrappedValue, inputs, outParams);
|
|
66
|
+
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
inputs.push(wrappedValue);
|
|
71
|
+
|
|
72
|
+
if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {
|
|
73
|
+
outParams.push({ value: wrappedValue, descriptor });
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
30
77
|
const partitionCallbackArgs = (
|
|
31
78
|
effectiveTypes: Descriptor[],
|
|
32
79
|
wrapped: unknown[],
|
|
@@ -34,54 +81,69 @@ const partitionCallbackArgs = (
|
|
|
34
81
|
): { inputs: unknown[]; outParams: OutParam[] } => {
|
|
35
82
|
const inputs: unknown[] = [];
|
|
36
83
|
const outParams: OutParam[] = [];
|
|
84
|
+
|
|
37
85
|
for (let i = start; i < effectiveTypes.length; i++) {
|
|
38
|
-
|
|
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
|
-
}
|
|
86
|
+
collectCallbackArg(effectiveTypes[i], wrapped[i], inputs, outParams);
|
|
52
87
|
}
|
|
88
|
+
|
|
53
89
|
return { inputs, outParams };
|
|
54
90
|
};
|
|
55
91
|
|
|
56
92
|
const writeOutParams = (outParams: OutParam[], outValues: unknown[]): void => {
|
|
57
|
-
outParams.
|
|
93
|
+
for (const [position, outParam] of outParams.entries()) {
|
|
58
94
|
const outValue = outValues[position];
|
|
95
|
+
|
|
59
96
|
if (outParam.descriptor.kind === "ref") {
|
|
60
97
|
(outParam.value as { value: unknown }).value = outValue;
|
|
61
98
|
} else if (outValue != null && outParam.value != null) {
|
|
62
|
-
fillCallerAllocatedBuffer(outParam.descriptor, outParam.value
|
|
99
|
+
fillCallerAllocatedBuffer(outParam.descriptor, outParam.value, outValue);
|
|
63
100
|
}
|
|
64
|
-
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const getThisArg = (receiver: CallbackReceiver, wrapped: unknown[]): unknown =>
|
|
105
|
+
receiver === "this" ? (wrapped[0] ?? null) : null;
|
|
106
|
+
|
|
107
|
+
const runCallback = (plan: CallbackPlan, rawArgs: unknown[]): unknown => {
|
|
108
|
+
const { effectiveTypes, returnDescriptor } = plan;
|
|
109
|
+
const wrapped = effectiveTypes.map((descriptor, i) => fromNative(descriptor, rawArgs[i]));
|
|
110
|
+
const thisArg = getThisArg(plan.receiver, wrapped);
|
|
111
|
+
const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, wrapped, plan.start);
|
|
112
|
+
const result = plan.fn.apply(thisArg, inputs);
|
|
113
|
+
|
|
114
|
+
if (outParams.length === 0) {
|
|
115
|
+
return toNative(returnDescriptor, result);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== "void", outParams.length);
|
|
119
|
+
writeOutParams(outParams, outValues);
|
|
120
|
+
|
|
121
|
+
return toNative(returnDescriptor, primary);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {
|
|
125
|
+
const { userDataIndex } = spec;
|
|
126
|
+
|
|
127
|
+
if (userDataIndex === undefined) {
|
|
128
|
+
return spec.argDescriptors;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return spec.argDescriptors.filter((_, i) => i !== userDataIndex);
|
|
65
132
|
};
|
|
66
133
|
|
|
67
|
-
|
|
134
|
+
const wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>
|
|
68
135
|
callback == null ? callback : wrapCallback(callback as Callback, spec, "none");
|
|
69
136
|
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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);
|
|
137
|
+
function wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {
|
|
138
|
+
const plan: CallbackPlan = {
|
|
139
|
+
fn,
|
|
140
|
+
effectiveTypes: getEffectiveTypes(spec),
|
|
141
|
+
returnDescriptor: spec.returnDescriptor,
|
|
142
|
+
start: receiver === "none" ? 0 : 1,
|
|
143
|
+
receiver,
|
|
86
144
|
};
|
|
145
|
+
|
|
146
|
+
return (...rawArgs: unknown[]): unknown => runCallback(plan, rawArgs);
|
|
87
147
|
}
|
|
148
|
+
|
|
149
|
+
export { wrapCallbackValue, wrapCallback };
|
package/src/descriptors.ts
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
import type { ArrayKind, Descriptor, Ownership } from "@gtkx/native";
|
|
2
2
|
import type { AnyClass } from "@gtkx/utils";
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
4
|
+
type Int8Descriptor = Extract<Descriptor, { kind: "int8" }>;
|
|
5
|
+
type Uint8Descriptor = Extract<Descriptor, { kind: "uint8" }>;
|
|
6
|
+
type Int16Descriptor = Extract<Descriptor, { kind: "int16" }>;
|
|
7
|
+
type Uint16Descriptor = Extract<Descriptor, { kind: "uint16" }>;
|
|
8
|
+
type Int32Descriptor = Extract<Descriptor, { kind: "int32" }>;
|
|
9
|
+
type Uint32Descriptor = Extract<Descriptor, { kind: "uint32" }>;
|
|
10
|
+
type Int64Descriptor = Extract<Descriptor, { kind: "int64" }>;
|
|
11
|
+
type Uint64Descriptor = Extract<Descriptor, { kind: "uint64" }>;
|
|
12
|
+
type BigInt64Descriptor = Extract<Descriptor, { kind: "bigint64" }>;
|
|
13
|
+
type BigUint64Descriptor = Extract<Descriptor, { kind: "biguint64" }>;
|
|
14
|
+
type Float32Descriptor = Extract<Descriptor, { kind: "float32" }>;
|
|
15
|
+
type Float64Descriptor = Extract<Descriptor, { kind: "float64" }>;
|
|
16
|
+
type EnumDescriptor = Extract<Descriptor, { kind: "enum" }>;
|
|
17
|
+
type FlagsDescriptor = Extract<Descriptor, { kind: "flags" }>;
|
|
18
|
+
type BooleanDescriptor = Extract<Descriptor, { kind: "boolean" }>;
|
|
19
|
+
type StringDescriptor = Extract<Descriptor, { kind: "string" }>;
|
|
20
|
+
type ObjectDescriptor = Extract<Descriptor, { kind: "object" }>;
|
|
21
|
+
type UnicharDescriptor = Extract<Descriptor, { kind: "unichar" }>;
|
|
22
|
+
type VoidDescriptor = Extract<Descriptor, { kind: "void" }>;
|
|
23
|
+
type BufferDescriptor = Extract<Descriptor, { kind: "buffer" }>;
|
|
24
|
+
type BoxedDescriptor = Extract<Descriptor, { kind: "boxed" }>;
|
|
25
|
+
type StructDescriptor = Extract<Descriptor, { kind: "struct" }> & { wrapperClass?: AnyClass };
|
|
26
|
+
type FundamentalDescriptor = Extract<Descriptor, { kind: "fundamental" }> & { wrapperClass?: AnyClass };
|
|
27
|
+
type ArrayDescriptor = Extract<Descriptor, { kind: "array" }>;
|
|
28
|
+
type HashTableDescriptor = Extract<Descriptor, { kind: "hashtable" }>;
|
|
29
|
+
type CallbackDescriptor = Extract<Descriptor, { kind: "callback" }>;
|
|
30
|
+
type RefDescriptor = Extract<Descriptor, { kind: "ref" }>;
|
|
31
|
+
type TypeDescriptor = BigUint64Descriptor & { type: true };
|
|
32
32
|
|
|
33
33
|
type BoxedOptions = {
|
|
34
34
|
callerAllocated?: boolean;
|
|
35
|
+
inline?: boolean;
|
|
35
36
|
ownership?: Ownership;
|
|
36
37
|
sharedLibrary?: string;
|
|
37
38
|
getTypeFnName?: string;
|
|
@@ -55,41 +56,43 @@ type FundamentalOptions = {
|
|
|
55
56
|
ownership?: Ownership;
|
|
56
57
|
typeName?: string;
|
|
57
58
|
wrapperClass?: AnyClass;
|
|
59
|
+
inline?: boolean;
|
|
58
60
|
};
|
|
59
61
|
|
|
60
62
|
type StructOptions = {
|
|
61
63
|
callerAllocated?: boolean;
|
|
64
|
+
inline?: boolean;
|
|
62
65
|
size?: number;
|
|
63
66
|
wrapperClass?: AnyClass;
|
|
64
67
|
};
|
|
65
68
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
69
|
+
const int8T: Int8Descriptor = { kind: "int8" };
|
|
70
|
+
const uint8T: Uint8Descriptor = { kind: "uint8" };
|
|
71
|
+
const int16T: Int16Descriptor = { kind: "int16" };
|
|
72
|
+
const uint16T: Uint16Descriptor = { kind: "uint16" };
|
|
73
|
+
const int32T: Int32Descriptor = { kind: "int32" };
|
|
74
|
+
const uint32T: Uint32Descriptor = { kind: "uint32" };
|
|
75
|
+
const int64T: Int64Descriptor = { kind: "int64" };
|
|
76
|
+
const uint64T: Uint64Descriptor = { kind: "uint64" };
|
|
77
|
+
const bigint64T: BigInt64Descriptor = { kind: "bigint64" };
|
|
78
|
+
const biguint64T: BigUint64Descriptor = { kind: "biguint64" };
|
|
79
|
+
const gtypeT: TypeDescriptor = { kind: "biguint64", type: true };
|
|
80
|
+
const float32T: Float32Descriptor = { kind: "float32" };
|
|
81
|
+
const float64T: Float64Descriptor = { kind: "float64" };
|
|
82
|
+
const booleanT: BooleanDescriptor = { kind: "boolean" };
|
|
83
|
+
const voidT: VoidDescriptor = { kind: "void" };
|
|
84
|
+
const unicharT: UnicharDescriptor = { kind: "unichar" };
|
|
85
|
+
const bufferT: BufferDescriptor = { kind: "buffer" };
|
|
86
|
+
|
|
87
|
+
const stringT = (ownership: Ownership = "borrowed", length?: number): StringDescriptor =>
|
|
85
88
|
length === undefined ? { kind: "string", ownership } : { kind: "string", ownership, length };
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
const objectT = (ownership: Ownership = "borrowed"): ObjectDescriptor => ({ kind: "object", ownership });
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
const refT = (innerDescriptor: Descriptor, isInout = false): RefDescriptor =>
|
|
93
|
+
isInout ? { kind: "ref", innerDescriptor, inout: true } : { kind: "ref", innerDescriptor };
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
const hashTableT = (
|
|
93
96
|
keyDescriptor: Descriptor,
|
|
94
97
|
valueDescriptor: Descriptor,
|
|
95
98
|
ownership: Ownership = "borrowed",
|
|
@@ -100,43 +103,85 @@ export const hashTableT = (
|
|
|
100
103
|
ownership,
|
|
101
104
|
});
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
const enumT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): EnumDescriptor => ({
|
|
104
107
|
kind: "enum",
|
|
105
108
|
sharedLibrary,
|
|
106
|
-
getTypeFnName,
|
|
107
|
-
signed,
|
|
109
|
+
getTypeFnName: typeFnName,
|
|
110
|
+
signed: isSigned,
|
|
108
111
|
});
|
|
109
112
|
|
|
110
|
-
|
|
113
|
+
const flagsT = (sharedLibrary: string, typeFnName: string, isSigned: boolean): FlagsDescriptor => ({
|
|
111
114
|
kind: "flags",
|
|
112
115
|
sharedLibrary,
|
|
113
|
-
getTypeFnName,
|
|
114
|
-
signed,
|
|
116
|
+
getTypeFnName: typeFnName,
|
|
117
|
+
signed: isSigned,
|
|
115
118
|
});
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
const applyBoxedNames = (result: BoxedDescriptor, options: BoxedOptions): void => {
|
|
121
|
+
if (options.sharedLibrary !== undefined) {
|
|
122
|
+
result.sharedLibrary = options.sharedLibrary;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (options.getTypeFnName !== undefined) {
|
|
126
|
+
result.getTypeFnName = options.getTypeFnName;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (options.freeFnName !== undefined) {
|
|
130
|
+
result.freeFnName = options.freeFnName;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const applyBoxedOptions = (result: BoxedDescriptor, options: BoxedOptions): void => {
|
|
135
|
+
applyBoxedNames(result, options);
|
|
136
|
+
|
|
137
|
+
if (options.callerAllocated) {
|
|
138
|
+
result.callerAllocated = true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (options.inline) {
|
|
142
|
+
result.inline = true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (options.size !== undefined) {
|
|
146
|
+
result.size = options.size;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const boxedT = (typeName: string, options: BoxedOptions = {}): BoxedDescriptor => {
|
|
118
151
|
const result: BoxedDescriptor = {
|
|
119
152
|
kind: "boxed",
|
|
120
153
|
ownership: options.ownership ?? "borrowed",
|
|
121
154
|
typeName,
|
|
122
155
|
};
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (options.callerAllocated) result.callerAllocated = true;
|
|
127
|
-
if (options.size !== undefined) result.size = options.size;
|
|
156
|
+
|
|
157
|
+
applyBoxedOptions(result, options);
|
|
158
|
+
|
|
128
159
|
return result;
|
|
129
160
|
};
|
|
130
161
|
|
|
131
|
-
|
|
162
|
+
const structT = (ownership: Ownership = "borrowed", options: StructOptions = {}): StructDescriptor => {
|
|
132
163
|
const result: StructDescriptor = { kind: "struct", ownership };
|
|
133
|
-
|
|
134
|
-
if (options.
|
|
135
|
-
|
|
164
|
+
|
|
165
|
+
if (options.size !== undefined) {
|
|
166
|
+
result.size = options.size;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (options.wrapperClass !== undefined) {
|
|
170
|
+
result.wrapperClass = options.wrapperClass;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (options.callerAllocated) {
|
|
174
|
+
result.callerAllocated = true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (options.inline) {
|
|
178
|
+
result.inline = true;
|
|
179
|
+
}
|
|
180
|
+
|
|
136
181
|
return result;
|
|
137
182
|
};
|
|
138
183
|
|
|
139
|
-
|
|
184
|
+
const fundamentalT = (
|
|
140
185
|
sharedLibrary: string,
|
|
141
186
|
refFnName: string,
|
|
142
187
|
unrefFnName: string,
|
|
@@ -144,65 +189,162 @@ export const fundamentalT = (
|
|
|
144
189
|
): FundamentalDescriptor => {
|
|
145
190
|
const ownership = options.ownership ?? "borrowed";
|
|
146
191
|
const result: FundamentalDescriptor = { kind: "fundamental", ownership, sharedLibrary, refFnName, unrefFnName };
|
|
147
|
-
|
|
148
|
-
if (options.
|
|
192
|
+
|
|
193
|
+
if (options.typeName !== undefined) {
|
|
194
|
+
result.typeName = options.typeName;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (options.wrapperClass !== undefined) {
|
|
198
|
+
result.wrapperClass = options.wrapperClass;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (options.inline) {
|
|
202
|
+
result.inline = true;
|
|
203
|
+
}
|
|
204
|
+
|
|
149
205
|
return result;
|
|
150
206
|
};
|
|
151
207
|
|
|
152
|
-
|
|
208
|
+
const arrayT = (
|
|
153
209
|
itemDescriptor: Descriptor,
|
|
154
210
|
arrayKind: ArrayKind = "array",
|
|
155
211
|
ownership: Ownership = "borrowed",
|
|
156
212
|
options?: ArrayOptions,
|
|
157
213
|
): ArrayDescriptor => {
|
|
158
214
|
const result: ArrayDescriptor = { kind: "array", itemDescriptor, arrayKind, ownership };
|
|
159
|
-
|
|
160
|
-
if (options?.
|
|
161
|
-
|
|
215
|
+
|
|
216
|
+
if (options?.elementSize !== undefined) {
|
|
217
|
+
result.elementSize = options.elementSize;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (options?.sizeParamIndex !== undefined) {
|
|
221
|
+
result.sizeParamIndex = options.sizeParamIndex;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (options?.fixedSize !== undefined) {
|
|
225
|
+
result.fixedSize = options.fixedSize;
|
|
226
|
+
}
|
|
227
|
+
|
|
162
228
|
return result;
|
|
163
229
|
};
|
|
164
230
|
|
|
165
|
-
|
|
231
|
+
const listT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
166
232
|
arrayT(itemDescriptor, "glist", ownership);
|
|
167
233
|
|
|
168
|
-
|
|
234
|
+
const slistT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
169
235
|
arrayT(itemDescriptor, "gslist", ownership);
|
|
170
236
|
|
|
171
|
-
|
|
237
|
+
const ptrArrayT = (itemDescriptor: Descriptor, ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
172
238
|
arrayT(itemDescriptor, "gptrarray", ownership);
|
|
173
239
|
|
|
174
|
-
|
|
240
|
+
const gArrayT = (
|
|
175
241
|
itemDescriptor: Descriptor,
|
|
176
242
|
ownership: Ownership = "borrowed",
|
|
177
243
|
elementSize?: number,
|
|
178
244
|
): ArrayDescriptor =>
|
|
179
245
|
arrayT(itemDescriptor, "garray", ownership, elementSize === undefined ? undefined : { elementSize });
|
|
180
246
|
|
|
181
|
-
|
|
247
|
+
const byteArrayT = (ownership: Ownership = "borrowed"): ArrayDescriptor =>
|
|
182
248
|
arrayT(uint8T, "gbytearray", ownership);
|
|
183
249
|
|
|
184
|
-
|
|
250
|
+
const sizedArrayT = (
|
|
185
251
|
itemDescriptor: Descriptor,
|
|
186
252
|
sizeParamIndex: number,
|
|
187
253
|
ownership: Ownership = "borrowed",
|
|
188
254
|
elementSize?: number,
|
|
189
255
|
): ArrayDescriptor => arrayT(itemDescriptor, "sized", ownership, { sizeParamIndex, elementSize });
|
|
190
256
|
|
|
191
|
-
|
|
257
|
+
const fixedArrayT = (
|
|
192
258
|
itemDescriptor: Descriptor,
|
|
193
259
|
fixedSize: number,
|
|
194
260
|
ownership: Ownership = "borrowed",
|
|
195
261
|
elementSize?: number,
|
|
196
262
|
): ArrayDescriptor => arrayT(itemDescriptor, "fixed", ownership, { fixedSize, elementSize });
|
|
197
263
|
|
|
198
|
-
|
|
264
|
+
const callbackT = (
|
|
199
265
|
argDescriptors: Descriptor[],
|
|
200
266
|
returnDescriptor: Descriptor,
|
|
201
267
|
options?: CallbackOptions,
|
|
202
268
|
): CallbackDescriptor => {
|
|
203
269
|
const result: CallbackDescriptor = { kind: "callback", argDescriptors, returnDescriptor };
|
|
204
|
-
|
|
205
|
-
if (options?.
|
|
206
|
-
|
|
270
|
+
|
|
271
|
+
if (options?.hasDestroy !== undefined) {
|
|
272
|
+
result.hasDestroy = options.hasDestroy;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (options?.userDataIndex !== undefined) {
|
|
276
|
+
result.userDataIndex = options.userDataIndex;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (options?.scope !== undefined) {
|
|
280
|
+
result.scope = options.scope;
|
|
281
|
+
}
|
|
282
|
+
|
|
207
283
|
return result;
|
|
208
284
|
};
|
|
285
|
+
|
|
286
|
+
export {
|
|
287
|
+
int8T,
|
|
288
|
+
uint8T,
|
|
289
|
+
int16T,
|
|
290
|
+
uint16T,
|
|
291
|
+
int32T,
|
|
292
|
+
uint32T,
|
|
293
|
+
int64T,
|
|
294
|
+
uint64T,
|
|
295
|
+
bigint64T,
|
|
296
|
+
biguint64T,
|
|
297
|
+
gtypeT,
|
|
298
|
+
float32T,
|
|
299
|
+
float64T,
|
|
300
|
+
booleanT,
|
|
301
|
+
voidT,
|
|
302
|
+
unicharT,
|
|
303
|
+
bufferT,
|
|
304
|
+
stringT,
|
|
305
|
+
objectT,
|
|
306
|
+
refT,
|
|
307
|
+
hashTableT,
|
|
308
|
+
enumT,
|
|
309
|
+
flagsT,
|
|
310
|
+
boxedT,
|
|
311
|
+
structT,
|
|
312
|
+
fundamentalT,
|
|
313
|
+
arrayT,
|
|
314
|
+
listT,
|
|
315
|
+
slistT,
|
|
316
|
+
ptrArrayT,
|
|
317
|
+
gArrayT,
|
|
318
|
+
byteArrayT,
|
|
319
|
+
sizedArrayT,
|
|
320
|
+
fixedArrayT,
|
|
321
|
+
callbackT,
|
|
322
|
+
type Int8Descriptor,
|
|
323
|
+
type Uint8Descriptor,
|
|
324
|
+
type Int16Descriptor,
|
|
325
|
+
type Uint16Descriptor,
|
|
326
|
+
type Int32Descriptor,
|
|
327
|
+
type Uint32Descriptor,
|
|
328
|
+
type Int64Descriptor,
|
|
329
|
+
type Uint64Descriptor,
|
|
330
|
+
type BigInt64Descriptor,
|
|
331
|
+
type BigUint64Descriptor,
|
|
332
|
+
type Float32Descriptor,
|
|
333
|
+
type Float64Descriptor,
|
|
334
|
+
type EnumDescriptor,
|
|
335
|
+
type FlagsDescriptor,
|
|
336
|
+
type BooleanDescriptor,
|
|
337
|
+
type StringDescriptor,
|
|
338
|
+
type ObjectDescriptor,
|
|
339
|
+
type UnicharDescriptor,
|
|
340
|
+
type VoidDescriptor,
|
|
341
|
+
type BufferDescriptor,
|
|
342
|
+
type BoxedDescriptor,
|
|
343
|
+
type StructDescriptor,
|
|
344
|
+
type FundamentalDescriptor,
|
|
345
|
+
type ArrayDescriptor,
|
|
346
|
+
type HashTableDescriptor,
|
|
347
|
+
type CallbackDescriptor,
|
|
348
|
+
type RefDescriptor,
|
|
349
|
+
type TypeDescriptor,
|
|
350
|
+
};
|
package/src/error.ts
CHANGED
|
@@ -2,26 +2,29 @@ import type { ExternalObject, Handle, Ref } from "@gtkx/native";
|
|
|
2
2
|
import { getWrapperClass, wrapHandle } from "./registry.js";
|
|
3
3
|
import { getErrorType, isTypedClass } from "./type.js";
|
|
4
4
|
|
|
5
|
-
type ErrorLike = {
|
|
5
|
+
type ErrorLike = Error & {
|
|
6
6
|
domain: number;
|
|
7
7
|
code: number;
|
|
8
|
-
message: string;
|
|
9
8
|
};
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* An error enum object carrying its member codes plus an `instanceof` check that
|
|
13
12
|
* matches wrapped GLib errors belonging to a specific error domain.
|
|
14
13
|
*/
|
|
15
|
-
|
|
14
|
+
type ErrorDomain<T extends Record<string, number>> = T & {
|
|
16
15
|
[Symbol.hasInstance]: (value: unknown) => value is ErrorLike;
|
|
17
16
|
};
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
if (error.value
|
|
21
|
-
|
|
22
|
-
Error.captureStackTrace(gerror, checkError);
|
|
23
|
-
throw gerror;
|
|
18
|
+
function checkError(error: Ref): void {
|
|
19
|
+
if (error.value === null) {
|
|
20
|
+
return;
|
|
24
21
|
}
|
|
22
|
+
|
|
23
|
+
const gerror = wrapHandle(error.value as ExternalObject<Handle>, getWrapperClass(getErrorType())) as ErrorLike;
|
|
24
|
+
const callSite = new Error("gtkx call site");
|
|
25
|
+
const callerFrames = (callSite.stack ?? "").split("\n").slice(2);
|
|
26
|
+
gerror.stack = [`${gerror.name}: ${gerror.message}`, ...callerFrames].join("\n");
|
|
27
|
+
throw gerror;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
const isError = (value: unknown): value is ErrorLike => isTypedClass(value) && value.__type__ === getErrorType();
|
|
@@ -34,16 +37,22 @@ const isError = (value: unknown): value is ErrorLike => isTypedClass(value) && v
|
|
|
34
37
|
* @param resolveDomain Called once, on first `instanceof` check, to obtain the domain quark.
|
|
35
38
|
* @param members The error code enum members to expose on the returned object.
|
|
36
39
|
*/
|
|
37
|
-
|
|
40
|
+
function createErrorDomain<const T extends Record<string, number>>(
|
|
38
41
|
resolveDomain: () => number,
|
|
39
42
|
members: T,
|
|
40
43
|
): ErrorDomain<T> {
|
|
41
44
|
let domain: number | undefined;
|
|
45
|
+
|
|
42
46
|
const hasInstance = (value: unknown): value is ErrorLike => {
|
|
43
47
|
domain ??= resolveDomain();
|
|
48
|
+
|
|
44
49
|
return isError(value) && value.domain === domain;
|
|
45
50
|
};
|
|
51
|
+
|
|
46
52
|
const enumObject: Record<string, unknown> = { ...members };
|
|
47
53
|
Object.defineProperty(enumObject, Symbol.hasInstance, { value: hasInstance });
|
|
54
|
+
|
|
48
55
|
return enumObject as ErrorDomain<T>;
|
|
49
56
|
}
|
|
57
|
+
|
|
58
|
+
export { checkError, createErrorDomain, type ErrorDomain };
|
package/src/exit-hook.ts
ADDED