@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/src/signal.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { Descriptor, ExternalObject, Handle } from "@gtkx/native";
|
|
2
|
+
import { type Arg, isCallerAllocatedArg, isInoutArg, isOutputArg } from "./arg.js";
|
|
3
|
+
import { bind, createBindCache } from "./bind.js";
|
|
4
|
+
import { wrapCallback } from "./callback.js";
|
|
5
|
+
import {
|
|
6
|
+
arrayT,
|
|
7
|
+
biguint64T,
|
|
8
|
+
type CallbackDescriptor,
|
|
9
|
+
objectT,
|
|
10
|
+
stringT,
|
|
11
|
+
uint32T,
|
|
12
|
+
uint64T,
|
|
13
|
+
voidT,
|
|
14
|
+
} from "./descriptors.js";
|
|
15
|
+
import { LIB, VALUE_SIZE, VALUE_T } from "./library.js";
|
|
16
|
+
import { getHandle } from "./registry.js";
|
|
17
|
+
import { packTupleResult } from "./tuple.js";
|
|
18
|
+
import type { TypedClass } from "./type.js";
|
|
19
|
+
import {
|
|
20
|
+
fromValue,
|
|
21
|
+
getBoxedValue,
|
|
22
|
+
inoutValueForBoxedDescriptor,
|
|
23
|
+
newValueForDescriptor,
|
|
24
|
+
outValueForBoxedDescriptor,
|
|
25
|
+
outValueForDescriptor,
|
|
26
|
+
toValue,
|
|
27
|
+
} from "./value.js";
|
|
28
|
+
|
|
29
|
+
/** Function invoked when a connected GObject signal is emitted. */
|
|
30
|
+
export type SignalHandler = (...args: unknown[]) => unknown;
|
|
31
|
+
|
|
32
|
+
type SignalConnectSpec = {
|
|
33
|
+
callback: CallbackDescriptor;
|
|
34
|
+
handler: SignalHandler;
|
|
35
|
+
after: boolean;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type EmitArg = Arg & { value?: unknown };
|
|
39
|
+
|
|
40
|
+
const connectCache = createBindCache();
|
|
41
|
+
const gQuarkFromString = bind(LIB, "g_quark_from_string", [stringT("borrowed")], uint32T);
|
|
42
|
+
const gSignalLookup = bind(LIB, "g_signal_lookup", [stringT("borrowed"), biguint64T], uint32T);
|
|
43
|
+
|
|
44
|
+
const gSignalEmitv = bind(
|
|
45
|
+
LIB,
|
|
46
|
+
"g_signal_emitv",
|
|
47
|
+
[arrayT(VALUE_T, "array", "borrowed", { elementSize: VALUE_SIZE }), uint32T, uint32T, VALUE_T],
|
|
48
|
+
voidT,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const gSignalHandlersBlockMatched = bind(
|
|
52
|
+
LIB,
|
|
53
|
+
"g_signal_handlers_block_matched",
|
|
54
|
+
[objectT("borrowed"), uint32T, uint32T, uint32T, objectT("borrowed"), objectT("borrowed"), objectT("borrowed")],
|
|
55
|
+
uint32T,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
/** Returns the signal name without its detail suffix (the part after `::`). */
|
|
59
|
+
export const getSignalBaseName = (signal: string): string => {
|
|
60
|
+
const detailIndex = signal.indexOf("::");
|
|
61
|
+
return detailIndex === -1 ? signal : signal.slice(0, detailIndex);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
function getQuarkForSignalDetail(signal: string): number {
|
|
65
|
+
const detailIndex = signal.indexOf("::");
|
|
66
|
+
if (detailIndex === -1) return 0;
|
|
67
|
+
return gQuarkFromString(signal.slice(detailIndex + 2)) as number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const getSignalId = (instance: object, signal: string): number => {
|
|
71
|
+
const type: bigint = (instance as TypedClass).__type__;
|
|
72
|
+
return gSignalLookup(getSignalBaseName(signal), type) as number;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
function connectBind(type: bigint, signal: string, callback: CallbackDescriptor): (...values: unknown[]) => unknown {
|
|
76
|
+
const key = `${type}\0${getSignalBaseName(signal)}`;
|
|
77
|
+
return connectCache(
|
|
78
|
+
key,
|
|
79
|
+
LIB,
|
|
80
|
+
"g_signal_connect_data",
|
|
81
|
+
[objectT("borrowed"), stringT("borrowed"), callback, uint32T],
|
|
82
|
+
uint64T,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Connects a handler to a GObject signal on an instance and returns the handler id.
|
|
88
|
+
* @param instance Emitter to connect to.
|
|
89
|
+
* @param signal Signal name, optionally including a `::detail` suffix.
|
|
90
|
+
* @param spec Callback descriptor, handler function, and whether to run after the default handler.
|
|
91
|
+
*/
|
|
92
|
+
export function connectSignal(instance: object, signal: string, spec: SignalConnectSpec): number {
|
|
93
|
+
const { callback, handler, after } = spec;
|
|
94
|
+
const wrapped = wrapCallback(handler, callback, "emitter");
|
|
95
|
+
const type: bigint = (instance as TypedClass).__type__;
|
|
96
|
+
const connect = connectBind(type, signal, callback);
|
|
97
|
+
return connect(getHandle(instance), signal, wrapped, after ? 1 : 0) as number;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function blockMatchedSignalHandlers(instance: object, signal: string): void {
|
|
101
|
+
const signalId = getSignalId(instance, signal);
|
|
102
|
+
gSignalHandlersBlockMatched(getHandle(instance), 1, signalId, 0, undefined, undefined, undefined);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const createEmitValue = (arg: EmitArg): { value: ExternalObject<Handle>; read?: () => unknown } => {
|
|
106
|
+
if (!isOutputArg(arg)) return { value: toValue(arg.type, arg.value) };
|
|
107
|
+
if (isCallerAllocatedArg(arg)) {
|
|
108
|
+
if (isInoutArg(arg)) return { value: inoutValueForBoxedDescriptor(arg.type, arg.value as object) };
|
|
109
|
+
const value = outValueForBoxedDescriptor(arg.type, arg.value as object);
|
|
110
|
+
return { value, read: () => getBoxedValue(value) };
|
|
111
|
+
}
|
|
112
|
+
return isInoutArg(arg) ? outValueForDescriptor(arg.type, arg.value) : outValueForDescriptor(arg.type);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Emits a signal on an instance with the given arguments and returns its result
|
|
117
|
+
* combined with any output-argument values.
|
|
118
|
+
* @param instance Emitter to emit the signal on.
|
|
119
|
+
* @param signal Signal name, optionally including a `::detail` suffix.
|
|
120
|
+
* @param args Arguments to pass, including output and inout arguments.
|
|
121
|
+
* @param returnDescriptor Descriptor for the signal's return value, omitted when it returns void.
|
|
122
|
+
*/
|
|
123
|
+
export function emitSignal(instance: object, signal: string, args: EmitArg[], returnDescriptor?: Descriptor): unknown {
|
|
124
|
+
const signalId = getSignalId(instance, signal);
|
|
125
|
+
const detail = getQuarkForSignalDetail(signal);
|
|
126
|
+
const values: ExternalObject<Handle>[] = [toValue(objectT("full"), instance)];
|
|
127
|
+
const reads: (() => unknown)[] = [];
|
|
128
|
+
|
|
129
|
+
for (const arg of args) {
|
|
130
|
+
const { value, read } = createEmitValue(arg);
|
|
131
|
+
values.push(value);
|
|
132
|
+
if (read) reads.push(read);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (returnDescriptor !== undefined) {
|
|
136
|
+
const returnValue = newValueForDescriptor(returnDescriptor);
|
|
137
|
+
gSignalEmitv(values, signalId, detail, returnValue);
|
|
138
|
+
return packTupleResult(
|
|
139
|
+
reads.map((read) => read()),
|
|
140
|
+
fromValue(returnValue),
|
|
141
|
+
true,
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
gSignalEmitv(values, signalId, detail, undefined);
|
|
146
|
+
|
|
147
|
+
return packTupleResult(
|
|
148
|
+
reads.map((read) => read()),
|
|
149
|
+
undefined,
|
|
150
|
+
false,
|
|
151
|
+
);
|
|
152
|
+
}
|
package/src/t.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { bind } from "./bind.js";
|
|
2
|
+
import * as helpers from "./descriptors.js";
|
|
3
|
+
import { fn } from "./fn.js";
|
|
4
|
+
|
|
5
|
+
type T = {
|
|
6
|
+
bind: typeof bind;
|
|
7
|
+
int8: typeof helpers.int8T;
|
|
8
|
+
uint8: typeof helpers.uint8T;
|
|
9
|
+
int16: typeof helpers.int16T;
|
|
10
|
+
uint16: typeof helpers.uint16T;
|
|
11
|
+
int32: typeof helpers.int32T;
|
|
12
|
+
uint32: typeof helpers.uint32T;
|
|
13
|
+
int64: typeof helpers.int64T;
|
|
14
|
+
uint64: typeof helpers.uint64T;
|
|
15
|
+
bigint64: typeof helpers.bigint64T;
|
|
16
|
+
biguint64: typeof helpers.biguint64T;
|
|
17
|
+
gtype: typeof helpers.gtypeT;
|
|
18
|
+
float32: typeof helpers.float32T;
|
|
19
|
+
float64: typeof helpers.float64T;
|
|
20
|
+
boolean: typeof helpers.booleanT;
|
|
21
|
+
void: typeof helpers.voidT;
|
|
22
|
+
unichar: typeof helpers.unicharT;
|
|
23
|
+
buffer: typeof helpers.bufferT;
|
|
24
|
+
string: typeof helpers.stringT;
|
|
25
|
+
object: typeof helpers.objectT;
|
|
26
|
+
boxed: typeof helpers.boxedT;
|
|
27
|
+
struct: typeof helpers.structT;
|
|
28
|
+
fundamental: typeof helpers.fundamentalT;
|
|
29
|
+
ref: typeof helpers.refT;
|
|
30
|
+
hashTable: typeof helpers.hashTableT;
|
|
31
|
+
enum: typeof helpers.enumT;
|
|
32
|
+
flags: typeof helpers.flagsT;
|
|
33
|
+
array: typeof helpers.arrayT;
|
|
34
|
+
list: typeof helpers.listT;
|
|
35
|
+
slist: typeof helpers.slistT;
|
|
36
|
+
ptrArray: typeof helpers.ptrArrayT;
|
|
37
|
+
gArray: typeof helpers.gArrayT;
|
|
38
|
+
byteArray: typeof helpers.byteArrayT;
|
|
39
|
+
sizedArray: typeof helpers.sizedArrayT;
|
|
40
|
+
fixedArray: typeof helpers.fixedArrayT;
|
|
41
|
+
callback: typeof helpers.callbackT;
|
|
42
|
+
fn: typeof fn;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Type descriptor builder: a collection of factory helpers that describe C types for
|
|
47
|
+
* FFI marshalling, plus `bind` to bind a native function and `fn` to describe a
|
|
48
|
+
* function signature.
|
|
49
|
+
*/
|
|
50
|
+
export const t: T = {
|
|
51
|
+
bind,
|
|
52
|
+
int8: helpers.int8T,
|
|
53
|
+
uint8: helpers.uint8T,
|
|
54
|
+
int16: helpers.int16T,
|
|
55
|
+
uint16: helpers.uint16T,
|
|
56
|
+
int32: helpers.int32T,
|
|
57
|
+
uint32: helpers.uint32T,
|
|
58
|
+
int64: helpers.int64T,
|
|
59
|
+
uint64: helpers.uint64T,
|
|
60
|
+
bigint64: helpers.bigint64T,
|
|
61
|
+
biguint64: helpers.biguint64T,
|
|
62
|
+
gtype: helpers.gtypeT,
|
|
63
|
+
float32: helpers.float32T,
|
|
64
|
+
float64: helpers.float64T,
|
|
65
|
+
boolean: helpers.booleanT,
|
|
66
|
+
void: helpers.voidT,
|
|
67
|
+
unichar: helpers.unicharT,
|
|
68
|
+
buffer: helpers.bufferT,
|
|
69
|
+
string: helpers.stringT,
|
|
70
|
+
object: helpers.objectT,
|
|
71
|
+
boxed: helpers.boxedT,
|
|
72
|
+
struct: helpers.structT,
|
|
73
|
+
fundamental: helpers.fundamentalT,
|
|
74
|
+
ref: helpers.refT,
|
|
75
|
+
hashTable: helpers.hashTableT,
|
|
76
|
+
enum: helpers.enumT,
|
|
77
|
+
flags: helpers.flagsT,
|
|
78
|
+
array: helpers.arrayT,
|
|
79
|
+
list: helpers.listT,
|
|
80
|
+
slist: helpers.slistT,
|
|
81
|
+
ptrArray: helpers.ptrArrayT,
|
|
82
|
+
gArray: helpers.gArrayT,
|
|
83
|
+
byteArray: helpers.byteArrayT,
|
|
84
|
+
sizedArray: helpers.sizedArrayT,
|
|
85
|
+
fixedArray: helpers.fixedArrayT,
|
|
86
|
+
callback: helpers.callbackT,
|
|
87
|
+
fn,
|
|
88
|
+
};
|
package/src/tuple.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const packTupleResult = (outs: unknown[], primary: unknown, hasPrimary: boolean): unknown => {
|
|
2
|
+
if (hasPrimary) {
|
|
3
|
+
return outs.length === 0 ? primary : [primary, ...outs];
|
|
4
|
+
}
|
|
5
|
+
if (outs.length === 0) return undefined;
|
|
6
|
+
if (outs.length === 1) return outs[0];
|
|
7
|
+
return outs;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const splitTupleResult = (
|
|
11
|
+
result: unknown,
|
|
12
|
+
hasPrimary: boolean,
|
|
13
|
+
outCount: number,
|
|
14
|
+
): { primary: unknown; outValues: unknown[] } => {
|
|
15
|
+
if (hasPrimary) {
|
|
16
|
+
if (Array.isArray(result)) {
|
|
17
|
+
return { primary: result[0], outValues: result.slice(1) };
|
|
18
|
+
}
|
|
19
|
+
return { primary: result, outValues: [] };
|
|
20
|
+
}
|
|
21
|
+
if (outCount === 1) {
|
|
22
|
+
return { primary: undefined, outValues: [result] };
|
|
23
|
+
}
|
|
24
|
+
return { primary: undefined, outValues: Array.isArray(result) ? result : [] };
|
|
25
|
+
};
|
package/src/type.ts
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { type Descriptor, resolveType as nativeResolveType } from "@gtkx/native";
|
|
2
|
+
import { bind } from "./bind.js";
|
|
3
|
+
import {
|
|
4
|
+
type BoxedDescriptor,
|
|
5
|
+
biguint64T,
|
|
6
|
+
booleanT,
|
|
7
|
+
type FundamentalDescriptor,
|
|
8
|
+
refT,
|
|
9
|
+
sizedArrayT,
|
|
10
|
+
stringT,
|
|
11
|
+
uint32T,
|
|
12
|
+
} from "./descriptors.js";
|
|
13
|
+
import { LIB } from "./library.js";
|
|
14
|
+
|
|
15
|
+
/** Object tagged with its GLib type through a `__type__` GType field. */
|
|
16
|
+
export type TypedClass = {
|
|
17
|
+
__type__: bigint;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const resolvedTypeCache = new Map<string, bigint>();
|
|
21
|
+
|
|
22
|
+
const gTypeFromName = bind(LIB, "g_type_from_name", [stringT("borrowed")], biguint64T);
|
|
23
|
+
const gTypeIsA = bind(LIB, "g_type_is_a", [biguint64T, biguint64T], booleanT);
|
|
24
|
+
const gTypeParent = bind(LIB, "g_type_parent", [biguint64T], biguint64T);
|
|
25
|
+
const gTypeFundamental = bind(LIB, "g_type_fundamental", [biguint64T], biguint64T);
|
|
26
|
+
const gTypeName = bind(LIB, "g_type_name", [biguint64T], stringT("borrowed"));
|
|
27
|
+
const gTypeInterfaces = bind(LIB, "g_type_interfaces", [biguint64T, refT(uint32T)], sizedArrayT(biguint64T, 1, "full"));
|
|
28
|
+
|
|
29
|
+
const lazyType = (name: string): (() => bigint) => {
|
|
30
|
+
let cached: bigint | undefined;
|
|
31
|
+
return () => {
|
|
32
|
+
cached ??= typeFromName(name);
|
|
33
|
+
return cached;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const isTypedClass = (value: unknown): value is TypedClass =>
|
|
38
|
+
typeof value === "object" && value !== null && "__type__" in value && typeof value.__type__ === "bigint";
|
|
39
|
+
|
|
40
|
+
/** GType tag for an invalid or uninitialized type. */
|
|
41
|
+
export const TYPE_INVALID: bigint = 0n;
|
|
42
|
+
/** GType tag for the absence of a value (`void`). */
|
|
43
|
+
export const TYPE_NONE: bigint = typeFromName("void");
|
|
44
|
+
/** GType tag for the base GInterface type. */
|
|
45
|
+
export const TYPE_INTERFACE: bigint = typeFromName("GInterface");
|
|
46
|
+
/** GType tag for `gchar` (signed 8-bit integer). */
|
|
47
|
+
export const TYPE_CHAR: bigint = typeFromName("gchar");
|
|
48
|
+
/** GType tag for `guchar` (unsigned 8-bit integer). */
|
|
49
|
+
export const TYPE_UCHAR: bigint = typeFromName("guchar");
|
|
50
|
+
/** GType tag for `gboolean`. */
|
|
51
|
+
export const TYPE_BOOLEAN: bigint = typeFromName("gboolean");
|
|
52
|
+
/** GType tag for `gint`. */
|
|
53
|
+
export const TYPE_INT: bigint = typeFromName("gint");
|
|
54
|
+
/** GType tag for `guint`. */
|
|
55
|
+
export const TYPE_UINT: bigint = typeFromName("guint");
|
|
56
|
+
/** GType tag for `glong`. */
|
|
57
|
+
export const TYPE_LONG: bigint = typeFromName("glong");
|
|
58
|
+
/** GType tag for `gulong`. */
|
|
59
|
+
export const TYPE_ULONG: bigint = typeFromName("gulong");
|
|
60
|
+
/** GType tag for `gint64`. */
|
|
61
|
+
export const TYPE_INT64: bigint = typeFromName("gint64");
|
|
62
|
+
/** GType tag for `guint64`. */
|
|
63
|
+
export const TYPE_UINT64: bigint = typeFromName("guint64");
|
|
64
|
+
/** GType tag for the base GEnum type. */
|
|
65
|
+
export const TYPE_ENUM: bigint = typeFromName("GEnum");
|
|
66
|
+
/** GType tag for the base GFlags type. */
|
|
67
|
+
export const TYPE_FLAGS: bigint = typeFromName("GFlags");
|
|
68
|
+
/** GType tag for `gfloat`. */
|
|
69
|
+
export const TYPE_FLOAT: bigint = typeFromName("gfloat");
|
|
70
|
+
/** GType tag for `gdouble`. */
|
|
71
|
+
export const TYPE_DOUBLE: bigint = typeFromName("gdouble");
|
|
72
|
+
/** GType tag for `gchararray` (a nul-terminated C string). */
|
|
73
|
+
export const TYPE_STRING: bigint = typeFromName("gchararray");
|
|
74
|
+
/** GType tag for `gpointer` (an opaque pointer). */
|
|
75
|
+
export const TYPE_POINTER: bigint = typeFromName("gpointer");
|
|
76
|
+
/** GType tag for the base GBoxed type. */
|
|
77
|
+
export const TYPE_BOXED: bigint = typeFromName("GBoxed");
|
|
78
|
+
/** GType tag for the base GParam type. */
|
|
79
|
+
export const TYPE_PARAM: bigint = typeFromName("GParam");
|
|
80
|
+
/** GType tag for the base GObject type. */
|
|
81
|
+
export const TYPE_OBJECT: bigint = typeFromName("GObject");
|
|
82
|
+
/** GType tag for a GType value itself. */
|
|
83
|
+
export const TYPE_GTYPE: bigint = typeFromName("GType");
|
|
84
|
+
/** GType tag for GVariant. */
|
|
85
|
+
export const TYPE_VARIANT: bigint = typeFromName("GVariant");
|
|
86
|
+
/** GType tag for a Unicode character stored as `guint`. */
|
|
87
|
+
export const TYPE_UNICHAR: bigint = typeFromName("guint");
|
|
88
|
+
export const getErrorType: () => bigint = lazyType("GError");
|
|
89
|
+
export const getStrvType: () => bigint = lazyType("GStrv");
|
|
90
|
+
|
|
91
|
+
/** Returns whether `type` is `isAType` or descends from it. */
|
|
92
|
+
export function typeIsA(type: bigint, isAType: bigint): boolean {
|
|
93
|
+
return gTypeIsA(type, isAType) as boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Returns the immediate parent GType of the given type. */
|
|
97
|
+
export function typeParent(type: bigint): bigint {
|
|
98
|
+
return gTypeParent(type) as bigint;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Returns the GTypes of the interfaces implemented by the given type. */
|
|
102
|
+
export function typeInterfaces(type: bigint): bigint[] {
|
|
103
|
+
const nInterfacesRef = { value: 0 };
|
|
104
|
+
return gTypeInterfaces(type, nInterfacesRef) as bigint[];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Returns the GType registered under the given name, or `TYPE_INVALID` if none exists. */
|
|
108
|
+
export function typeFromName(name: string): bigint {
|
|
109
|
+
return gTypeFromName(name) as bigint;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function typeFundamental(type: bigint): bigint {
|
|
113
|
+
return gTypeFundamental(type) as bigint;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Returns the registered name of a GType, or null if it has none. */
|
|
117
|
+
export function typeName(type: bigint): string | null {
|
|
118
|
+
return (gTypeName(type) ?? null) as string | null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Returns whether `value` is a typed wrapper whose GType is or descends from `gtype`. */
|
|
122
|
+
export function valueIsA(value: unknown, gtype: bigint): boolean {
|
|
123
|
+
return isTypedClass(value) && typeIsA(value.__type__, gtype);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Resolves the GType produced by a `get_type` function in a shared library, caching
|
|
128
|
+
* the result per library and function name.
|
|
129
|
+
* @param sharedLibrary Path or name of the shared library exporting the function.
|
|
130
|
+
* @param getTypeFnName Name of the `*_get_type` function to call.
|
|
131
|
+
*/
|
|
132
|
+
export const resolveType = (sharedLibrary: string, getTypeFnName: string): bigint => {
|
|
133
|
+
const key = `${sharedLibrary}:${getTypeFnName}`;
|
|
134
|
+
const cached = resolvedTypeCache.get(key);
|
|
135
|
+
if (cached !== undefined) return cached;
|
|
136
|
+
const gtype = nativeResolveType(sharedLibrary, getTypeFnName);
|
|
137
|
+
resolvedTypeCache.set(key, gtype);
|
|
138
|
+
return gtype;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export const resolveBoxedType = (descriptor: BoxedDescriptor): bigint => {
|
|
142
|
+
if (descriptor.getTypeFnName && descriptor.sharedLibrary) {
|
|
143
|
+
return resolveType(descriptor.sharedLibrary, descriptor.getTypeFnName);
|
|
144
|
+
}
|
|
145
|
+
const gtype = typeFromName(descriptor.typeName);
|
|
146
|
+
if (gtype === TYPE_INVALID) {
|
|
147
|
+
throw new Error(`Cannot resolve gtype for boxed type '${descriptor.typeName}'`);
|
|
148
|
+
}
|
|
149
|
+
return gtype;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export const resolveFundamentalType = (descriptor: FundamentalDescriptor): bigint => {
|
|
153
|
+
if (descriptor.typeName) {
|
|
154
|
+
const gtype = typeFromName(descriptor.typeName);
|
|
155
|
+
if (gtype !== TYPE_INVALID) return gtype;
|
|
156
|
+
}
|
|
157
|
+
throw new Error(`Cannot resolve gtype for fundamental type without a typeName`);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
export function resolveDescriptorType(descriptor: Descriptor): bigint {
|
|
161
|
+
if (descriptor.kind === "biguint64" && "type" in descriptor) return TYPE_GTYPE;
|
|
162
|
+
switch (descriptor.kind) {
|
|
163
|
+
case "boolean":
|
|
164
|
+
return TYPE_BOOLEAN;
|
|
165
|
+
case "string":
|
|
166
|
+
return TYPE_STRING;
|
|
167
|
+
case "int8":
|
|
168
|
+
case "int16":
|
|
169
|
+
case "int32":
|
|
170
|
+
return TYPE_INT;
|
|
171
|
+
case "uint8":
|
|
172
|
+
case "uint16":
|
|
173
|
+
case "uint32":
|
|
174
|
+
return TYPE_UINT;
|
|
175
|
+
case "int64":
|
|
176
|
+
case "bigint64":
|
|
177
|
+
return TYPE_INT64;
|
|
178
|
+
case "uint64":
|
|
179
|
+
case "biguint64":
|
|
180
|
+
return TYPE_UINT64;
|
|
181
|
+
case "float32":
|
|
182
|
+
return TYPE_FLOAT;
|
|
183
|
+
case "float64":
|
|
184
|
+
return TYPE_DOUBLE;
|
|
185
|
+
case "object":
|
|
186
|
+
return TYPE_OBJECT;
|
|
187
|
+
case "enum":
|
|
188
|
+
case "flags":
|
|
189
|
+
return resolveType(descriptor.sharedLibrary, descriptor.getTypeFnName);
|
|
190
|
+
case "boxed":
|
|
191
|
+
return resolveBoxedType(descriptor);
|
|
192
|
+
case "fundamental":
|
|
193
|
+
return resolveFundamentalType(descriptor);
|
|
194
|
+
case "array":
|
|
195
|
+
if (descriptor.itemDescriptor.kind === "string" && descriptor.arrayKind === "array") return getStrvType();
|
|
196
|
+
throw new Error(`Unsupported array type ${descriptor.arrayKind} of ${descriptor.itemDescriptor.kind}`);
|
|
197
|
+
default:
|
|
198
|
+
throw new Error(`Unsupported type descriptor '${descriptor.kind}'`);
|
|
199
|
+
}
|
|
200
|
+
}
|