@gtkx/runtime 1.0.0-rc.3 → 1.0.0
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/README.md +8 -9
- package/dist/application-class.d.ts +32 -0
- package/dist/application-class.d.ts.map +1 -0
- package/dist/application-class.js +68 -0
- package/dist/application-class.js.map +1 -0
- package/dist/arg.d.ts +9 -3
- package/dist/arg.d.ts.map +1 -1
- package/dist/arg.js +4 -3
- package/dist/arg.js.map +1 -1
- package/dist/bind.d.ts +11 -0
- package/dist/bind.d.ts.map +1 -1
- package/dist/bind.js +11 -0
- package/dist/bind.js.map +1 -1
- package/dist/callback.d.ts +2 -1
- package/dist/callback.d.ts.map +1 -1
- package/dist/callback.js +119 -21
- package/dist/callback.js.map +1 -1
- package/dist/closure.d.ts +26 -0
- package/dist/closure.d.ts.map +1 -0
- package/dist/closure.js +99 -0
- package/dist/closure.js.map +1 -0
- package/dist/descriptors.d.ts +105 -6
- package/dist/descriptors.d.ts.map +1 -1
- package/dist/descriptors.js +56 -12
- package/dist/descriptors.js.map +1 -1
- package/dist/error.d.ts +7 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +1 -1
- package/dist/error.js.map +1 -1
- package/dist/fn.d.ts +24 -3
- package/dist/fn.d.ts.map +1 -1
- package/dist/fn.js +70 -33
- package/dist/fn.js.map +1 -1
- package/dist/index.d.ts +29 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -4
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -0
- package/dist/internal.js.map +1 -1
- package/dist/library.d.ts +2 -1
- package/dist/library.d.ts.map +1 -1
- package/dist/library.js +2 -1
- package/dist/library.js.map +1 -1
- package/dist/lifecycle.d.ts +52 -10
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +62 -18
- package/dist/lifecycle.js.map +1 -1
- package/dist/listeners.d.ts +6 -0
- package/dist/listeners.d.ts.map +1 -1
- package/dist/listeners.js +3 -1
- package/dist/listeners.js.map +1 -1
- package/dist/mixin.d.ts +16 -2
- package/dist/mixin.d.ts.map +1 -1
- package/dist/mixin.js +18 -6
- package/dist/mixin.js.map +1 -1
- package/dist/native-value.d.ts +8 -0
- package/dist/native-value.d.ts.map +1 -1
- package/dist/native-value.js +12 -3
- package/dist/native-value.js.map +1 -1
- package/dist/object.d.ts +34 -6
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +89 -25
- package/dist/object.js.map +1 -1
- package/dist/param-spec.d.ts +11 -0
- package/dist/param-spec.d.ts.map +1 -0
- package/dist/param-spec.js +149 -0
- package/dist/param-spec.js.map +1 -0
- package/dist/promisify.d.ts +3 -5
- package/dist/promisify.d.ts.map +1 -1
- package/dist/promisify.js +4 -3
- package/dist/promisify.js.map +1 -1
- package/dist/properties.d.ts +39 -7
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +305 -42
- package/dist/properties.js.map +1 -1
- package/dist/register-class.d.ts +119 -14
- package/dist/register-class.d.ts.map +1 -1
- package/dist/register-class.js +109 -80
- package/dist/register-class.js.map +1 -1
- package/dist/registry.d.ts +81 -17
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +72 -26
- package/dist/registry.js.map +1 -1
- package/dist/signal.d.ts +22 -3
- package/dist/signal.d.ts.map +1 -1
- package/dist/signal.js +64 -8
- package/dist/signal.js.map +1 -1
- package/dist/t.d.ts +44 -0
- package/dist/t.d.ts.map +1 -1
- package/dist/t.js.map +1 -1
- package/dist/type.d.ts +2 -2
- package/dist/type.d.ts.map +1 -1
- package/dist/type.js +2 -0
- package/dist/type.js.map +1 -1
- package/dist/value.d.ts +10 -10
- package/dist/value.d.ts.map +1 -1
- package/dist/value.js +44 -22
- package/dist/value.js.map +1 -1
- package/dist/vfunc-call.d.ts +37 -0
- package/dist/vfunc-call.d.ts.map +1 -0
- package/dist/vfunc-call.js +168 -0
- package/dist/vfunc-call.js.map +1 -0
- package/dist/vfunc-seeds.d.ts +12 -0
- package/dist/vfunc-seeds.d.ts.map +1 -0
- package/dist/vfunc-seeds.js +19 -0
- package/dist/vfunc-seeds.js.map +1 -0
- package/dist/vfunc.d.ts +8 -0
- package/dist/vfunc.d.ts.map +1 -0
- package/dist/vfunc.js +23 -0
- package/dist/vfunc.js.map +1 -0
- package/package.json +4 -4
- package/src/application-class.ts +116 -0
- package/src/arg.ts +11 -5
- package/src/bind.ts +11 -0
- package/src/callback.ts +163 -23
- package/src/closure.ts +136 -0
- package/src/descriptors.ts +137 -41
- package/src/error.ts +8 -1
- package/src/fn.ts +104 -39
- package/src/index.ts +36 -7
- package/src/internal.ts +1 -0
- package/src/library.ts +2 -1
- package/src/lifecycle.ts +99 -22
- package/src/listeners.ts +9 -1
- package/src/mixin.ts +27 -8
- package/src/native-value.ts +13 -3
- package/src/object.ts +128 -34
- package/src/param-spec.ts +235 -0
- package/src/promisify.ts +8 -8
- package/src/properties.ts +459 -45
- package/src/register-class.ts +329 -114
- package/src/registry.ts +150 -38
- package/src/signal.ts +101 -17
- package/src/t.ts +44 -0
- package/src/type.ts +3 -2
- package/src/value.ts +57 -19
- package/src/vfunc-call.ts +243 -0
- package/src/vfunc-seeds.ts +36 -0
- package/src/vfunc.ts +31 -0
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
The React framework for Linux.<br />
|
|
9
|
-
|
|
9
|
+
Write native Linux applications with React and TypeScript.
|
|
10
|
+
Built on the GNOME stack and standard web tooling.
|
|
10
11
|
</p>
|
|
11
12
|
|
|
12
13
|
<p align="center">
|
|
@@ -20,15 +21,13 @@
|
|
|
20
21
|
|
|
21
22
|
<p align="center">
|
|
22
23
|
<a href="https://gtkx.dev">Homepage</a> ·
|
|
23
|
-
<a href="https://gtkx.dev/guide/
|
|
24
|
+
<a href="https://gtkx.dev/guide/getting-started">Documentation</a> ·
|
|
24
25
|
<a href="https://github.com/gtkx-org/gtkx/tree/main/examples">Examples</a> ·
|
|
25
26
|
<a href="https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md">Contributing</a>
|
|
26
27
|
</p>
|
|
27
28
|
|
|
28
29
|
---
|
|
29
30
|
|
|
30
|
-
GTKX generates fully typed bindings for the entire GTK4 and Adwaita surface directly from GObject-Introspection. On top of those bindings you get the React programming model: components and hooks driving GObject instances, with Fast Refresh while you develop.
|
|
31
|
-
|
|
32
31
|
<p align="center">
|
|
33
32
|
<img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/examples/tutorial/assets/screenshot.png" alt="The Tasks app: an Adwaita window with a sidebar of smart views and colored lists on the left, and a boxed task list on the right." />
|
|
34
33
|
</p>
|
|
@@ -109,7 +108,7 @@ React Native and similar frameworks hide the native toolkit so one API can run e
|
|
|
109
108
|
|
|
110
109
|
### Why Node.js, and why generated bindings
|
|
111
110
|
|
|
112
|
-
GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [
|
|
111
|
+
GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [Why GTKX guide](https://gtkx.dev/guide/why-gtkx) covers what running on Node.js means day to day.
|
|
113
112
|
|
|
114
113
|
GTKX generates the TypeScript types and the native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. Codegen covers the whole GTK4 and Adwaita surface.
|
|
115
114
|
|
|
@@ -122,10 +121,10 @@ GTKX is Linux-only and needs Node.js 24 or later. See [Requirements](#requiremen
|
|
|
122
121
|
Scaffold a new app with the `create-gtkx` initializer:
|
|
123
122
|
|
|
124
123
|
```sh
|
|
125
|
-
npm create gtkx
|
|
124
|
+
npm create gtkx
|
|
126
125
|
```
|
|
127
126
|
|
|
128
|
-
The same command works with other package managers: `pnpm create gtkx
|
|
127
|
+
The same command works with other package managers: `pnpm create gtkx` or `yarn create gtkx`.
|
|
129
128
|
|
|
130
129
|
Then run your new app:
|
|
131
130
|
|
|
@@ -146,7 +145,7 @@ The documentation at **[gtkx.dev](https://gtkx.dev)** includes a step-by-step tu
|
|
|
146
145
|
|
|
147
146
|
GTKX is Linux-only. You need:
|
|
148
147
|
|
|
149
|
-
- Linux with the GTK4 (4.20 or later), Adwaita (1.8 or later)
|
|
148
|
+
- Linux with the GTK4 (4.20 or later) and GLib development libraries, plus Adwaita (1.8 or later) once your project binds `Adw-1`
|
|
150
149
|
- Node.js 24 or later
|
|
151
150
|
|
|
152
151
|
The `@gtkx/native` addon ships prebuilt for x64 and arm64 glibc Linux; other targets need to build it from the GTKX repository, which requires a Rust toolchain.
|
|
@@ -162,7 +161,7 @@ Explore the [example apps](https://github.com/gtkx-org/gtkx/tree/main/examples):
|
|
|
162
161
|
|
|
163
162
|
## Status
|
|
164
163
|
|
|
165
|
-
GTKX 1.0 is
|
|
164
|
+
GTKX 1.0 is released.
|
|
166
165
|
|
|
167
166
|
## Contributing
|
|
168
167
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type AnyClass } from "@gtkx/utils";
|
|
2
|
+
type CommandLineResult = [boolean, string[], number];
|
|
3
|
+
/**
|
|
4
|
+
* The GIO application surface {@link createApplication} builds on, which `Gio.Application` and
|
|
5
|
+
* every subclass of it satisfies structurally.
|
|
6
|
+
*/
|
|
7
|
+
type CommandLineApplication = {
|
|
8
|
+
/** Marks the application as quitting, so GLib's own `run` returns without driving a main loop. */
|
|
9
|
+
quit(): void;
|
|
10
|
+
};
|
|
11
|
+
type LocalCommandLineApplication = {
|
|
12
|
+
runLocalCommandLine(argv: string[]): CommandLineResult;
|
|
13
|
+
};
|
|
14
|
+
type ShutdownApplication = {
|
|
15
|
+
run(argv: string[]): number;
|
|
16
|
+
};
|
|
17
|
+
/** An application class together with the construct properties it accepts. */
|
|
18
|
+
type ApplicationClass<T extends CommandLineApplication, P> = AnyClass<T> & (new (props: P) => T);
|
|
19
|
+
declare const isDerivedApplication: (application: object) => application is LocalCommandLineApplication;
|
|
20
|
+
declare const shutDownThroughRun: (application: ShutdownApplication) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Constructs an application GTKX can shut down. GLib parses an application's command line at most
|
|
23
|
+
* once per instance and crashes on a second parse, so {@link runApplication} and
|
|
24
|
+
* {@link quitApplication} only accept an application built here.
|
|
25
|
+
*
|
|
26
|
+
* @param base The application class to construct, such as `Gtk.Application`.
|
|
27
|
+
* @param props Construct properties, passed through unchanged.
|
|
28
|
+
* @returns An instance of a class derived from `base`, registered once per base class as its own GType.
|
|
29
|
+
*/
|
|
30
|
+
declare const createApplication: <T extends CommandLineApplication, P>(base: ApplicationClass<T, P>, props: P) => T;
|
|
31
|
+
export { createApplication, isDerivedApplication, shutDownThroughRun, type ApplicationClass, type CommandLineApplication, type LocalCommandLineApplication, };
|
|
32
|
+
//# sourceMappingURL=application-class.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-class.d.ts","sourceRoot":"","sources":["../src/application-class.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAe,MAAM,aAAa,CAAC;AAMzD,KAAK,iBAAiB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;AAErD;;;GAGG;AACH,KAAK,sBAAsB,GAAG;IAC1B,kGAAkG;IAClG,IAAI,IAAI,IAAI,CAAC;CAChB,CAAC;AAEF,KAAK,2BAA2B,GAAG;IAC/B,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAAC;CAC1D,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACvB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;CAC/B,CAAC;AAEF,8EAA8E;AAC9E,KAAK,gBAAgB,CAAC,CAAC,SAAS,sBAAsB,EAAE,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;AA2CjG,QAAA,MAAM,oBAAoB,GAAI,aAAa,MAAM,KAAG,WAAW,IAAI,2BAQlE,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,aAAa,mBAAmB,KAAG,IAY9D,CAAC;AAKF;;;;;;;;GAQG;AACH,QAAA,MAAM,iBAAiB,GAAI,CAAC,SAAS,sBAAsB,EAAE,CAAC,EAAE,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,KAAG,CACrC,CAAC;AAErE,OAAO,EACH,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,GACnC,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { getOrInsert } from "@gtkx/utils";
|
|
2
|
+
import { registerClass } from "./register-class.js";
|
|
3
|
+
import { getClassType } from "./registry.js";
|
|
4
|
+
import { typeName } from "./type.js";
|
|
5
|
+
import { callParent } from "./vfunc-call.js";
|
|
6
|
+
const derivedClasses = new WeakMap();
|
|
7
|
+
const derivedApplicationClasses = new Set();
|
|
8
|
+
const quitApplications = new WeakSet();
|
|
9
|
+
const shuttingDownApplications = new WeakSet();
|
|
10
|
+
const derivedTypeName = (base) => `Gtkx${typeName(getClassType(base)) ?? base.name}`;
|
|
11
|
+
const buildApplicationClass = (base) => {
|
|
12
|
+
class DerivedApplication extends base {
|
|
13
|
+
runLocalCommandLine(argv) {
|
|
14
|
+
return this.vfuncLocalCommandLine(argv);
|
|
15
|
+
}
|
|
16
|
+
vfuncLocalCommandLine(argv) {
|
|
17
|
+
if (shuttingDownApplications.has(this)) {
|
|
18
|
+
this.quit();
|
|
19
|
+
return [true, argv, 0];
|
|
20
|
+
}
|
|
21
|
+
return callParent(DerivedApplication, "vfuncLocalCommandLine", this, argv);
|
|
22
|
+
}
|
|
23
|
+
vfuncNameLost() {
|
|
24
|
+
quitApplications.add(this);
|
|
25
|
+
return callParent(DerivedApplication, "vfuncNameLost", this);
|
|
26
|
+
}
|
|
27
|
+
quit() {
|
|
28
|
+
quitApplications.add(this);
|
|
29
|
+
super.quit();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const derived = registerClass(DerivedApplication, { typeName: derivedTypeName(base) });
|
|
33
|
+
derivedApplicationClasses.add(derived);
|
|
34
|
+
return derived;
|
|
35
|
+
};
|
|
36
|
+
const isDerivedApplication = (application) => {
|
|
37
|
+
for (const derived of derivedApplicationClasses) {
|
|
38
|
+
if (application instanceof derived) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
};
|
|
44
|
+
const shutDownThroughRun = (application) => {
|
|
45
|
+
if (!isDerivedApplication(application) || quitApplications.has(application)) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
shuttingDownApplications.add(application);
|
|
49
|
+
try {
|
|
50
|
+
application.run([]);
|
|
51
|
+
}
|
|
52
|
+
finally {
|
|
53
|
+
shuttingDownApplications.delete(application);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const deriveApplicationClass = (base) => getOrInsert(derivedClasses, base, () => buildApplicationClass(base));
|
|
57
|
+
/**
|
|
58
|
+
* Constructs an application GTKX can shut down. GLib parses an application's command line at most
|
|
59
|
+
* once per instance and crashes on a second parse, so {@link runApplication} and
|
|
60
|
+
* {@link quitApplication} only accept an application built here.
|
|
61
|
+
*
|
|
62
|
+
* @param base The application class to construct, such as `Gtk.Application`.
|
|
63
|
+
* @param props Construct properties, passed through unchanged.
|
|
64
|
+
* @returns An instance of a class derived from `base`, registered once per base class as its own GType.
|
|
65
|
+
*/
|
|
66
|
+
const createApplication = (base, props) => new (deriveApplicationClass(base))(props);
|
|
67
|
+
export { createApplication, isDerivedApplication, shutDownThroughRun, };
|
|
68
|
+
//# sourceMappingURL=application-class.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-class.js","sourceRoot":"","sources":["../src/application-class.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AnyClass, getOrInsert } from \"@gtkx/utils\";\nimport { registerClass } from \"./register-class.js\";\nimport { getClassType } from \"./registry.js\";\nimport { typeName } from \"./type.js\";\nimport { callParent } from \"./vfunc-call.js\";\n\ntype CommandLineResult = [boolean, string[], number];\n\n/**\n * The GIO application surface {@link createApplication} builds on, which `Gio.Application` and\n * every subclass of it satisfies structurally.\n */\ntype CommandLineApplication = {\n /** Marks the application as quitting, so GLib's own `run` returns without driving a main loop. */\n quit(): void;\n};\n\ntype LocalCommandLineApplication = {\n runLocalCommandLine(argv: string[]): CommandLineResult;\n};\n\ntype ShutdownApplication = {\n run(argv: string[]): number;\n};\n\n/** An application class together with the construct properties it accepts. */\ntype ApplicationClass<T extends CommandLineApplication, P> = AnyClass<T> & (new (props: P) => T);\n\nconst derivedClasses: WeakMap<AnyClass, AnyClass> = new WeakMap();\nconst derivedApplicationClasses: Set<AnyClass> = new Set();\nconst quitApplications: WeakSet<object> = new WeakSet();\nconst shuttingDownApplications: WeakSet<object> = new WeakSet();\n\nconst derivedTypeName = (base: AnyClass): string => `Gtkx${typeName(getClassType(base)) ?? base.name}`;\n\nconst buildApplicationClass = (base: AnyClass<CommandLineApplication>): AnyClass<CommandLineApplication> => {\n class DerivedApplication extends base {\n runLocalCommandLine(argv: string[]): CommandLineResult {\n return this.vfuncLocalCommandLine(argv);\n }\n\n protected vfuncLocalCommandLine(argv: string[]): CommandLineResult {\n if (shuttingDownApplications.has(this)) {\n this.quit();\n\n return [true, argv, 0];\n }\n\n return callParent(DerivedApplication, \"vfuncLocalCommandLine\", this, argv) as CommandLineResult;\n }\n\n protected vfuncNameLost(): boolean {\n quitApplications.add(this);\n\n return callParent(DerivedApplication, \"vfuncNameLost\", this) as boolean;\n }\n\n override quit(): void {\n quitApplications.add(this);\n super.quit();\n }\n }\n\n const derived = registerClass(DerivedApplication, { typeName: derivedTypeName(base) });\n derivedApplicationClasses.add(derived);\n\n return derived;\n};\n\nconst isDerivedApplication = (application: object): application is LocalCommandLineApplication => {\n for (const derived of derivedApplicationClasses) {\n if (application instanceof derived) {\n return true;\n }\n }\n\n return false;\n};\n\nconst shutDownThroughRun = (application: ShutdownApplication): void => {\n if (!isDerivedApplication(application) || quitApplications.has(application)) {\n return;\n }\n\n shuttingDownApplications.add(application);\n\n try {\n application.run([]);\n } finally {\n shuttingDownApplications.delete(application);\n }\n};\n\nconst deriveApplicationClass = <T extends CommandLineApplication>(base: AnyClass<T>): AnyClass<T> =>\n getOrInsert(derivedClasses, base, () => buildApplicationClass(base)) as AnyClass<T>;\n\n/**\n * Constructs an application GTKX can shut down. GLib parses an application's command line at most\n * once per instance and crashes on a second parse, so {@link runApplication} and\n * {@link quitApplication} only accept an application built here.\n *\n * @param base The application class to construct, such as `Gtk.Application`.\n * @param props Construct properties, passed through unchanged.\n * @returns An instance of a class derived from `base`, registered once per base class as its own GType.\n */\nconst createApplication = <T extends CommandLineApplication, P>(base: ApplicationClass<T, P>, props: P): T =>\n new (deriveApplicationClass(base) as new (props: P) => T)(props);\n\nexport {\n createApplication,\n isDerivedApplication,\n shutDownThroughRun,\n type ApplicationClass,\n type CommandLineApplication,\n type LocalCommandLineApplication,\n};\n"]}
|
package/dist/arg.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { Descriptor } from "@gtkx/native";
|
|
2
|
+
/** How one argument of a native call or signal emission is marshalled and which way it flows. */
|
|
2
3
|
type Arg = {
|
|
4
|
+
/** Descriptor the value is marshalled with, wrapped in a pointer to it for an output argument. */
|
|
3
5
|
type: Descriptor;
|
|
6
|
+
/** Direction of an output argument, omitted for a plain input argument. */
|
|
4
7
|
direction?: "out" | "inout";
|
|
5
|
-
|
|
6
|
-
|
|
8
|
+
/** When true, the caller supplies the storage the callee writes into, rather than a pointer to fill. */
|
|
9
|
+
isCallerAllocated?: boolean;
|
|
10
|
+
/** When true, the argument is consumed internally and left out of the packed result. */
|
|
11
|
+
isConsumed?: boolean;
|
|
7
12
|
};
|
|
8
13
|
declare const isOutputArg: (arg: Arg) => boolean;
|
|
9
14
|
declare const isInoutArg: (arg: Arg) => boolean;
|
|
10
15
|
declare const isCallerAllocatedArg: (arg: Arg) => boolean;
|
|
11
16
|
declare const isRefArg: (arg: Arg) => boolean;
|
|
12
|
-
|
|
17
|
+
declare const requiresInputArg: (arg: Arg) => boolean;
|
|
18
|
+
export { isOutputArg, isInoutArg, isCallerAllocatedArg, isRefArg, requiresInputArg, type Arg };
|
|
13
19
|
//# sourceMappingURL=arg.d.ts.map
|
package/dist/arg.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arg.d.ts","sourceRoot":"","sources":["../src/arg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,KAAK,GAAG,GAAG;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC5B,
|
|
1
|
+
{"version":3,"file":"arg.d.ts","sourceRoot":"","sources":["../src/arg.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,iGAAiG;AACjG,KAAK,GAAG,GAAG;IACP,kGAAkG;IAClG,IAAI,EAAE,UAAU,CAAC;IACjB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IAC5B,wGAAwG;IACxG,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,wFAAwF;IACxF,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,QAAA,MAAM,WAAW,GAAI,KAAK,GAAG,KAAG,OAAsC,CAAC;AACvE,QAAA,MAAM,UAAU,GAAI,KAAK,GAAG,KAAG,OAAoC,CAAC;AACpE,QAAA,MAAM,oBAAoB,GAAI,KAAK,GAAG,KAAG,OAAyC,CAAC;AACnF,QAAA,MAAM,QAAQ,GAAI,KAAK,GAAG,KAAG,OAAwE,CAAC;AACtG,QAAA,MAAM,gBAAgB,GAAI,KAAK,GAAG,KAAG,OAA4C,CAAC;AAElF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,oBAAoB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,GAAG,EAAE,CAAC"}
|
package/dist/arg.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const isOutputArg = (arg) => arg.direction !== undefined;
|
|
2
2
|
const isInoutArg = (arg) => arg.direction === "inout";
|
|
3
|
-
const isCallerAllocatedArg = (arg) => arg.
|
|
4
|
-
const isRefArg = (arg) => arg.direction !== undefined && arg.
|
|
5
|
-
|
|
3
|
+
const isCallerAllocatedArg = (arg) => arg.isCallerAllocated === true;
|
|
4
|
+
const isRefArg = (arg) => arg.direction !== undefined && arg.isCallerAllocated !== true;
|
|
5
|
+
const requiresInputArg = (arg) => !isRefArg(arg) || isInoutArg(arg);
|
|
6
|
+
export { isOutputArg, isInoutArg, isCallerAllocatedArg, isRefArg, requiresInputArg };
|
|
6
7
|
//# sourceMappingURL=arg.js.map
|
package/dist/arg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arg.js","sourceRoot":"","sources":["../src/arg.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"arg.js","sourceRoot":"","sources":["../src/arg.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC;AACvE,MAAM,UAAU,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC;AACpE,MAAM,oBAAoB,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,GAAG,CAAC,iBAAiB,KAAK,IAAI,CAAC;AACnF,MAAM,QAAQ,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,GAAG,CAAC,SAAS,KAAK,SAAS,IAAI,GAAG,CAAC,iBAAiB,KAAK,IAAI,CAAC;AACtG,MAAM,gBAAgB,GAAG,CAAC,GAAQ,EAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAElF,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,oBAAoB,EAAE,QAAQ,EAAE,gBAAgB,EAAY,CAAC","sourcesContent":["import type { Descriptor } from \"@gtkx/native\";\n\n/** How one argument of a native call or signal emission is marshalled and which way it flows. */\ntype Arg = {\n /** Descriptor the value is marshalled with, wrapped in a pointer to it for an output argument. */\n type: Descriptor;\n /** Direction of an output argument, omitted for a plain input argument. */\n direction?: \"out\" | \"inout\";\n /** When true, the caller supplies the storage the callee writes into, rather than a pointer to fill. */\n isCallerAllocated?: boolean;\n /** When true, the argument is consumed internally and left out of the packed result. */\n isConsumed?: boolean;\n};\n\nconst isOutputArg = (arg: Arg): boolean => arg.direction !== undefined;\nconst isInoutArg = (arg: Arg): boolean => arg.direction === \"inout\";\nconst isCallerAllocatedArg = (arg: Arg): boolean => arg.isCallerAllocated === true;\nconst isRefArg = (arg: Arg): boolean => arg.direction !== undefined && arg.isCallerAllocated !== true;\nconst requiresInputArg = (arg: Arg): boolean => !isRefArg(arg) || isInoutArg(arg);\n\nexport { isOutputArg, isInoutArg, isCallerAllocatedArg, isRefArg, requiresInputArg, type Arg };\n"]}
|
package/dist/bind.d.ts
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { type Descriptor } from "@gtkx/native";
|
|
2
|
+
/**
|
|
3
|
+
* Precompiles a call to a C function, marshalling the values it is given through the argument
|
|
4
|
+
* descriptors and the result through the return one. The symbol is resolved in the shared library
|
|
5
|
+
* on the first call.
|
|
6
|
+
*
|
|
7
|
+
* @param sharedLibrary The shared library to resolve the symbol in.
|
|
8
|
+
* @param symbol The name of the C function to bind.
|
|
9
|
+
* @param argDescriptors Describe the C arguments, in declaration order.
|
|
10
|
+
* @param returnDescriptor Describes the C return value.
|
|
11
|
+
* @returns A function calling the bound symbol.
|
|
12
|
+
*/
|
|
2
13
|
declare function bind(sharedLibrary: string, symbol: string, argDescriptors: Descriptor[], returnDescriptor: Descriptor): (...values: unknown[]) => unknown;
|
|
3
14
|
declare function createBindCache(): (key: string, ...args: Parameters<typeof bind>) => ReturnType<typeof bind>;
|
|
4
15
|
export { bind, createBindCache };
|
package/dist/bind.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAsB,MAAM,cAAc,CAAC;AAEzE,iBAAS,IAAI,CACT,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,UAAU,EAAE,EAC5B,gBAAgB,EAAE,UAAU,GAC7B,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAInC;AAED,iBAAS,eAAe,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,UAAU,CAAC,OAAO,IAAI,CAAC,CAerG;AAED,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"bind.d.ts","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAsB,MAAM,cAAc,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,iBAAS,IAAI,CACT,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,UAAU,EAAE,EAC5B,gBAAgB,EAAE,UAAU,GAC7B,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAInC;AAED,iBAAS,eAAe,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,UAAU,CAAC,OAAO,IAAI,CAAC,CAerG;AAED,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/bind.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { call, bind as nativeBind } from "@gtkx/native";
|
|
2
|
+
/**
|
|
3
|
+
* Precompiles a call to a C function, marshalling the values it is given through the argument
|
|
4
|
+
* descriptors and the result through the return one. The symbol is resolved in the shared library
|
|
5
|
+
* on the first call.
|
|
6
|
+
*
|
|
7
|
+
* @param sharedLibrary The shared library to resolve the symbol in.
|
|
8
|
+
* @param symbol The name of the C function to bind.
|
|
9
|
+
* @param argDescriptors Describe the C arguments, in declaration order.
|
|
10
|
+
* @param returnDescriptor Describes the C return value.
|
|
11
|
+
* @returns A function calling the bound symbol.
|
|
12
|
+
*/
|
|
2
13
|
function bind(sharedLibrary, symbol, argDescriptors, returnDescriptor) {
|
|
3
14
|
const descriptor = nativeBind(sharedLibrary, symbol, argDescriptors, returnDescriptor);
|
|
4
15
|
return (...values) => call(descriptor, values);
|
package/dist/bind.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,IAAI,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzE,SAAS,IAAI,CACT,aAAqB,EACrB,MAAc,EACd,cAA4B,EAC5B,gBAA4B;IAE5B,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAEvF,OAAO,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,eAAe;IACpB,MAAM,KAAK,GAAyC,IAAI,GAAG,EAAE,CAAC;IAE9D,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5B,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAEtB,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;AACN,CAAC;AAED,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import { call, type Descriptor, bind as nativeBind } from \"@gtkx/native\";\n\nfunction bind(\n sharedLibrary: string,\n symbol: string,\n argDescriptors: Descriptor[],\n returnDescriptor: Descriptor,\n): (...values: unknown[]) => unknown {\n const descriptor = nativeBind(sharedLibrary, symbol, argDescriptors, returnDescriptor);\n\n return (...values) => call(descriptor, values);\n}\n\nfunction createBindCache(): (key: string, ...args: Parameters<typeof bind>) => ReturnType<typeof bind> {\n const cache: Map<string, ReturnType<typeof bind>> = new Map();\n\n return (key, ...args) => {\n const existing = cache.get(key);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const bound = bind(...args);\n cache.set(key, bound);\n\n return bound;\n };\n}\n\nexport { bind, createBindCache };\n"]}
|
|
1
|
+
{"version":3,"file":"bind.js","sourceRoot":"","sources":["../src/bind.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,IAAI,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzE;;;;;;;;;;GAUG;AACH,SAAS,IAAI,CACT,aAAqB,EACrB,MAAc,EACd,cAA4B,EAC5B,gBAA4B;IAE5B,MAAM,UAAU,GAAG,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAEvF,OAAO,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,eAAe;IACpB,MAAM,KAAK,GAAyC,IAAI,GAAG,EAAE,CAAC;IAE9D,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAC5B,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAEtB,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;AACN,CAAC;AAED,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import { call, type Descriptor, bind as nativeBind } from \"@gtkx/native\";\n\n/**\n * Precompiles a call to a C function, marshalling the values it is given through the argument\n * descriptors and the result through the return one. The symbol is resolved in the shared library\n * on the first call.\n *\n * @param sharedLibrary The shared library to resolve the symbol in.\n * @param symbol The name of the C function to bind.\n * @param argDescriptors Describe the C arguments, in declaration order.\n * @param returnDescriptor Describes the C return value.\n * @returns A function calling the bound symbol.\n */\nfunction bind(\n sharedLibrary: string,\n symbol: string,\n argDescriptors: Descriptor[],\n returnDescriptor: Descriptor,\n): (...values: unknown[]) => unknown {\n const descriptor = nativeBind(sharedLibrary, symbol, argDescriptors, returnDescriptor);\n\n return (...values) => call(descriptor, values);\n}\n\nfunction createBindCache(): (key: string, ...args: Parameters<typeof bind>) => ReturnType<typeof bind> {\n const cache: Map<string, ReturnType<typeof bind>> = new Map();\n\n return (key, ...args) => {\n const existing = cache.get(key);\n\n if (existing !== undefined) {\n return existing;\n }\n\n const bound = bind(...args);\n cache.set(key, bound);\n\n return bound;\n };\n}\n\nexport { bind, createBindCache };\n"]}
|
package/dist/callback.d.ts
CHANGED
|
@@ -7,7 +7,8 @@ type CallbackSpec = {
|
|
|
7
7
|
returnDescriptor: Descriptor;
|
|
8
8
|
userDataIndex?: number;
|
|
9
9
|
};
|
|
10
|
+
declare const isCallerAllocatedOut: (descriptor: Descriptor) => boolean;
|
|
10
11
|
declare const wrapCallbackValue: (spec: CallbackDescriptor, callback: unknown) => unknown;
|
|
11
12
|
declare function wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback;
|
|
12
|
-
export { wrapCallbackValue, wrapCallback };
|
|
13
|
+
export { isCallerAllocatedOut, wrapCallbackValue, wrapCallback };
|
|
13
14
|
//# sourceMappingURL=callback.d.ts.map
|
package/dist/callback.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../src/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../src/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,kBAAkB,CAAC;AAO1E,KAAK,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAChD,KAAK,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAKpD,KAAK,YAAY,GAAG;IAChB,cAAc,EAAE,UAAU,EAAE,CAAC;IAC7B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AA4BF,QAAA,MAAM,oBAAoB,GAAI,YAAY,UAAU,KAAG,OACmD,CAAC;AA6N3G,QAAA,MAAM,iBAAiB,GAAI,MAAM,kBAAkB,EAAE,UAAU,OAAO,KAAG,OACS,CAAC;AAEnF,iBAAS,YAAY,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,CAe5F;AAED,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC"}
|
package/dist/callback.js
CHANGED
|
@@ -3,6 +3,7 @@ import { fromNative, toNative } from "./native-value.js";
|
|
|
3
3
|
import { getHandle } from "./registry.js";
|
|
4
4
|
import { splitTupleResult } from "./tuple.js";
|
|
5
5
|
import { copyValue } from "./value.js";
|
|
6
|
+
import { popSeedFrame, pushSeedFrame } from "./vfunc-seeds.js";
|
|
6
7
|
const fillCallerAllocatedBuffer = (descriptor, target, source) => {
|
|
7
8
|
if (descriptor.kind === "boxed" && descriptor.typeName === "GValue") {
|
|
8
9
|
copyValue(getHandle(target), getHandle(source));
|
|
@@ -14,54 +15,147 @@ const fillCallerAllocatedBuffer = (descriptor, target, source) => {
|
|
|
14
15
|
}
|
|
15
16
|
throw new Error(`Cannot write caller-allocated ${descriptor.kind} out-parameter: no known byte size`);
|
|
16
17
|
};
|
|
17
|
-
const isCallerAllocatedOut = (descriptor) => (descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.
|
|
18
|
-
const collectRefArg = (descriptor, wrappedValue, inputs,
|
|
18
|
+
const isCallerAllocatedOut = (descriptor) => (descriptor.kind === "boxed" || descriptor.kind === "struct") && descriptor.isCallerAllocated === true;
|
|
19
|
+
const collectRefArg = (descriptor, wrappedValue, inputs, out) => {
|
|
19
20
|
if (descriptor.inout === true) {
|
|
20
21
|
inputs.push(wrappedValue.value);
|
|
21
22
|
}
|
|
22
|
-
|
|
23
|
+
out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });
|
|
23
24
|
};
|
|
24
|
-
const collectCallbackArg = (descriptor, wrappedValue, inputs,
|
|
25
|
+
const collectCallbackArg = (descriptor, wrappedValue, inputs, out) => {
|
|
25
26
|
if (descriptor?.kind === "ref") {
|
|
26
|
-
collectRefArg(descriptor, wrappedValue, inputs,
|
|
27
|
+
collectRefArg(descriptor, wrappedValue, inputs, out);
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
inputs.push(wrappedValue);
|
|
30
31
|
if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {
|
|
31
|
-
|
|
32
|
+
out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
35
|
const partitionCallbackArgs = (effectiveTypes, wrapped, start) => {
|
|
35
36
|
const inputs = [];
|
|
36
|
-
const
|
|
37
|
+
const params = [];
|
|
38
|
+
const collected = { params, argIndex: start };
|
|
37
39
|
for (let i = start; i < effectiveTypes.length; i++) {
|
|
38
|
-
|
|
40
|
+
collected.argIndex = i;
|
|
41
|
+
collectCallbackArg(effectiveTypes[i], wrapped[i], inputs, collected);
|
|
39
42
|
}
|
|
40
|
-
return { inputs, outParams };
|
|
43
|
+
return { inputs, outParams: params };
|
|
44
|
+
};
|
|
45
|
+
const hasOutParamArg = (descriptor) => descriptor !== undefined && (descriptor.kind === "ref" || isCallerAllocatedOut(descriptor));
|
|
46
|
+
const hasRefOutParamArg = (descriptor) => descriptor?.kind === "ref" && descriptor.inout !== true;
|
|
47
|
+
const haveOutParamArgs = (effectiveTypes, start) => effectiveTypes.slice(start).some((descriptor) => hasOutParamArg(descriptor));
|
|
48
|
+
const haveRefOutParamArgs = (effectiveTypes, start) => effectiveTypes.slice(start).some((descriptor) => hasRefOutParamArg(descriptor));
|
|
49
|
+
const sizeParamIndexFor = (descriptor) => {
|
|
50
|
+
if (descriptor.kind !== "ref") {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
const { innerDescriptor } = descriptor;
|
|
54
|
+
return innerDescriptor.kind === "array" ? innerDescriptor.sizeParamIndex : undefined;
|
|
55
|
+
};
|
|
56
|
+
const lengthOutParamIndices = (outParams) => {
|
|
57
|
+
const indices = new Map();
|
|
58
|
+
for (const outParam of outParams) {
|
|
59
|
+
const sizeParamIndex = sizeParamIndexFor(outParam.descriptor);
|
|
60
|
+
if (sizeParamIndex !== undefined) {
|
|
61
|
+
indices.set(sizeParamIndex, outParam.argIndex);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return indices;
|
|
41
65
|
};
|
|
42
66
|
const writeOutParams = (outParams, outValues) => {
|
|
67
|
+
const written = new Map();
|
|
43
68
|
for (const [position, outParam] of outParams.entries()) {
|
|
44
69
|
const outValue = outValues[position];
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
const { descriptor } = outParam;
|
|
71
|
+
written.set(outParam.argIndex, outValue);
|
|
72
|
+
if (descriptor.kind === "ref") {
|
|
73
|
+
outParam.value.value = toNative(descriptor.innerDescriptor, outValue);
|
|
47
74
|
}
|
|
48
75
|
else if (outValue != null && outParam.value != null) {
|
|
49
|
-
fillCallerAllocatedBuffer(
|
|
76
|
+
fillCallerAllocatedBuffer(descriptor, outParam.value, outValue);
|
|
50
77
|
}
|
|
51
78
|
}
|
|
79
|
+
return written;
|
|
80
|
+
};
|
|
81
|
+
const groupOutParams = (outParams) => {
|
|
82
|
+
const lengths = lengthOutParamIndices(outParams);
|
|
83
|
+
const groups = { lengthLinks: [], valueParams: [] };
|
|
84
|
+
for (const outParam of outParams) {
|
|
85
|
+
const sourceIndex = lengths.get(outParam.argIndex);
|
|
86
|
+
if (sourceIndex === undefined) {
|
|
87
|
+
groups.valueParams.push(outParam);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
groups.lengthLinks.push({ target: outParam, sourceIndex });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return groups;
|
|
94
|
+
};
|
|
95
|
+
const getFoldedLength = (source) => {
|
|
96
|
+
const length = source?.length;
|
|
97
|
+
return typeof length === "number" ? length : 0;
|
|
98
|
+
};
|
|
99
|
+
const writeFoldedLengths = (lengthLinks, written) => {
|
|
100
|
+
for (const link of lengthLinks) {
|
|
101
|
+
link.target.value.value = getFoldedLength(written.get(link.sourceIndex));
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const collectRefSeeds = (outParams) => {
|
|
105
|
+
const seeds = new Map();
|
|
106
|
+
for (const outParam of outParams) {
|
|
107
|
+
const seed = outParam.value?.value;
|
|
108
|
+
if (seed != null && hasRefOutParamArg(outParam.descriptor)) {
|
|
109
|
+
seeds.set(outParam.argIndex, seed);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return seeds;
|
|
113
|
+
};
|
|
114
|
+
const applyCallback = (plan, thisArg, inputs, outParams) => {
|
|
115
|
+
if (!plan.hasRefOutParams) {
|
|
116
|
+
return plan.fn.apply(thisArg, inputs);
|
|
117
|
+
}
|
|
118
|
+
pushSeedFrame({ argDescriptors: plan.effectiveTypes, instance: thisArg, seeds: collectRefSeeds(outParams) });
|
|
119
|
+
try {
|
|
120
|
+
return plan.fn.apply(thisArg, inputs);
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
popSeedFrame();
|
|
124
|
+
}
|
|
52
125
|
};
|
|
53
126
|
const getThisArg = (receiver, wrapped) => receiver === "this" ? (wrapped[0] ?? null) : null;
|
|
127
|
+
const wrapCallbackArgs = (effectiveTypes, rawArgs) => {
|
|
128
|
+
let index = 0;
|
|
129
|
+
for (const descriptor of effectiveTypes) {
|
|
130
|
+
rawArgs[index] = fromNative(descriptor, rawArgs[index]);
|
|
131
|
+
index += 1;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const trimCallbackInputs = (plan, wrapped) => {
|
|
135
|
+
const count = plan.effectiveTypes.length;
|
|
136
|
+
if (wrapped.length > count) {
|
|
137
|
+
wrapped.length = count;
|
|
138
|
+
}
|
|
139
|
+
for (let index = 0; index < plan.start; index++) {
|
|
140
|
+
wrapped.shift();
|
|
141
|
+
}
|
|
142
|
+
return wrapped;
|
|
143
|
+
};
|
|
54
144
|
const runCallback = (plan, rawArgs) => {
|
|
55
145
|
const { effectiveTypes, returnDescriptor } = plan;
|
|
56
|
-
|
|
57
|
-
const thisArg = getThisArg(plan.receiver,
|
|
58
|
-
|
|
59
|
-
|
|
146
|
+
wrapCallbackArgs(effectiveTypes, rawArgs);
|
|
147
|
+
const thisArg = getThisArg(plan.receiver, rawArgs);
|
|
148
|
+
if (!plan.hasOutParams) {
|
|
149
|
+
return toNative(returnDescriptor, plan.fn.apply(thisArg, trimCallbackInputs(plan, rawArgs)));
|
|
150
|
+
}
|
|
151
|
+
const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, rawArgs, plan.start);
|
|
152
|
+
const result = applyCallback(plan, thisArg, inputs, outParams);
|
|
60
153
|
if (outParams.length === 0) {
|
|
61
154
|
return toNative(returnDescriptor, result);
|
|
62
155
|
}
|
|
63
|
-
const {
|
|
64
|
-
|
|
156
|
+
const { lengthLinks, valueParams } = groupOutParams(outParams);
|
|
157
|
+
const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== "void", valueParams.length);
|
|
158
|
+
writeFoldedLengths(lengthLinks, writeOutParams(valueParams, outValues));
|
|
65
159
|
return toNative(returnDescriptor, primary);
|
|
66
160
|
};
|
|
67
161
|
const getEffectiveTypes = (spec) => {
|
|
@@ -73,14 +167,18 @@ const getEffectiveTypes = (spec) => {
|
|
|
73
167
|
};
|
|
74
168
|
const wrapCallbackValue = (spec, callback) => callback == null ? callback : wrapCallback(callback, spec, "none");
|
|
75
169
|
function wrapCallback(fn, spec, receiver) {
|
|
170
|
+
const effectiveTypes = getEffectiveTypes(spec);
|
|
171
|
+
const start = receiver === "none" ? 0 : 1;
|
|
76
172
|
const plan = {
|
|
77
173
|
fn,
|
|
78
|
-
effectiveTypes
|
|
174
|
+
effectiveTypes,
|
|
79
175
|
returnDescriptor: spec.returnDescriptor,
|
|
80
|
-
start
|
|
176
|
+
start,
|
|
81
177
|
receiver,
|
|
178
|
+
hasOutParams: haveOutParamArgs(effectiveTypes, start),
|
|
179
|
+
hasRefOutParams: haveRefOutParamArgs(effectiveTypes, start),
|
|
82
180
|
};
|
|
83
181
|
return (...rawArgs) => runCallback(plan, rawArgs);
|
|
84
182
|
}
|
|
85
|
-
export { wrapCallbackValue, wrapCallback };
|
|
183
|
+
export { isCallerAllocatedOut, wrapCallbackValue, wrapCallback };
|
|
86
184
|
//# sourceMappingURL=callback.js.map
|
package/dist/callback.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../src/callback.ts"],"names":[],"mappings":"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","sourcesContent":["import { copy, type Descriptor } from \"@gtkx/native\";\nimport type { CallbackDescriptor, RefDescriptor } from \"./descriptors.js\";\nimport { fromNative, toNative } from \"./native-value.js\";\nimport { getHandle } from \"./registry.js\";\nimport { splitTupleResult } from \"./tuple.js\";\nimport { copyValue } from \"./value.js\";\n\ntype Callback = (...args: unknown[]) => unknown;\ntype CallbackReceiver = \"this\" | \"emitter\" | \"none\";\ntype OutParam = { value: unknown; descriptor: Descriptor };\n\ntype CallbackSpec = {\n argDescriptors: Descriptor[];\n returnDescriptor: Descriptor;\n userDataIndex?: number;\n};\n\ntype CallbackPlan = {\n fn: Callback;\n effectiveTypes: Descriptor[];\n returnDescriptor: Descriptor;\n start: number;\n receiver: CallbackReceiver;\n};\n\nconst fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {\n if (descriptor.kind === \"boxed\" && descriptor.typeName === \"GValue\") {\n copyValue(getHandle(target), getHandle(source));\n\n return;\n }\n\n if ((descriptor.kind === \"boxed\" || descriptor.kind === \"struct\") && descriptor.size !== undefined) {\n copy(getHandle(target), getHandle(source), descriptor.size);\n\n return;\n }\n\n throw new Error(`Cannot write caller-allocated ${descriptor.kind} out-parameter: no known byte size`);\n};\n\nconst isCallerAllocatedOut = (descriptor: Descriptor): boolean =>\n (descriptor.kind === \"boxed\" || descriptor.kind === \"struct\") && descriptor.callerAllocated === true;\n\nconst collectRefArg = (\n descriptor: RefDescriptor,\n wrappedValue: unknown,\n inputs: unknown[],\n outParams: OutParam[],\n): void => {\n if (descriptor.inout === true) {\n inputs.push((wrappedValue as { value: unknown }).value);\n }\n\n outParams.push({ value: wrappedValue, descriptor });\n};\n\nconst collectCallbackArg = (\n descriptor: Descriptor | undefined,\n wrappedValue: unknown,\n inputs: unknown[],\n outParams: OutParam[],\n): void => {\n if (descriptor?.kind === \"ref\") {\n collectRefArg(descriptor, wrappedValue, inputs, outParams);\n\n return;\n }\n\n inputs.push(wrappedValue);\n\n if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {\n outParams.push({ value: wrappedValue, descriptor });\n }\n};\n\nconst partitionCallbackArgs = (\n effectiveTypes: Descriptor[],\n wrapped: unknown[],\n start: number,\n): { inputs: unknown[]; outParams: OutParam[] } => {\n const inputs: unknown[] = [];\n const outParams: OutParam[] = [];\n\n for (let i = start; i < effectiveTypes.length; i++) {\n collectCallbackArg(effectiveTypes[i], wrapped[i], inputs, outParams);\n }\n\n return { inputs, outParams };\n};\n\nconst writeOutParams = (outParams: OutParam[], outValues: unknown[]): void => {\n for (const [position, outParam] of outParams.entries()) {\n const outValue = outValues[position];\n\n if (outParam.descriptor.kind === \"ref\") {\n (outParam.value as { value: unknown }).value = outValue;\n } else if (outValue != null && outParam.value != null) {\n fillCallerAllocatedBuffer(outParam.descriptor, outParam.value, outValue);\n }\n }\n};\n\nconst getThisArg = (receiver: CallbackReceiver, wrapped: unknown[]): unknown =>\n receiver === \"this\" ? (wrapped[0] ?? null) : null;\n\nconst runCallback = (plan: CallbackPlan, rawArgs: unknown[]): unknown => {\n const { effectiveTypes, returnDescriptor } = plan;\n const wrapped = effectiveTypes.map((descriptor, i) => fromNative(descriptor, rawArgs[i]));\n const thisArg = getThisArg(plan.receiver, wrapped);\n const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, wrapped, plan.start);\n const result = plan.fn.apply(thisArg, inputs);\n\n if (outParams.length === 0) {\n return toNative(returnDescriptor, result);\n }\n\n const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== \"void\", outParams.length);\n writeOutParams(outParams, outValues);\n\n return toNative(returnDescriptor, primary);\n};\n\nconst getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {\n const { userDataIndex } = spec;\n\n if (userDataIndex === undefined) {\n return spec.argDescriptors;\n }\n\n return spec.argDescriptors.filter((_, i) => i !== userDataIndex);\n};\n\nconst wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>\n callback == null ? callback : wrapCallback(callback as Callback, spec, \"none\");\n\nfunction wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {\n const plan: CallbackPlan = {\n fn,\n effectiveTypes: getEffectiveTypes(spec),\n returnDescriptor: spec.returnDescriptor,\n start: receiver === \"none\" ? 0 : 1,\n receiver,\n };\n\n return (...rawArgs: unknown[]): unknown => runCallback(plan, rawArgs);\n}\n\nexport { wrapCallbackValue, wrapCallback };\n"]}
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../src/callback.ts"],"names":[],"mappings":"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","sourcesContent":["import { copy, type Descriptor } from \"@gtkx/native\";\nimport type { CallbackDescriptor, RefDescriptor } from \"./descriptors.js\";\nimport { fromNative, toNative } from \"./native-value.js\";\nimport { getHandle } from \"./registry.js\";\nimport { splitTupleResult } from \"./tuple.js\";\nimport { copyValue } from \"./value.js\";\nimport { popSeedFrame, pushSeedFrame, type RefSeeds } from \"./vfunc-seeds.js\";\n\ntype Callback = (...args: unknown[]) => unknown;\ntype CallbackReceiver = \"this\" | \"emitter\" | \"none\";\ntype OutParam = { value: unknown; descriptor: Descriptor; argIndex: number };\ntype LengthLink = { target: OutParam; sourceIndex: number };\ntype OutParamGroups = { lengthLinks: LengthLink[]; valueParams: OutParam[] };\n\ntype CallbackSpec = {\n argDescriptors: Descriptor[];\n returnDescriptor: Descriptor;\n userDataIndex?: number;\n};\n\ntype CallbackPlan = {\n fn: Callback;\n effectiveTypes: Descriptor[];\n returnDescriptor: Descriptor;\n start: number;\n receiver: CallbackReceiver;\n hasOutParams: boolean;\n hasRefOutParams: boolean;\n};\n\nconst fillCallerAllocatedBuffer = (descriptor: Descriptor, target: object, source: object): void => {\n if (descriptor.kind === \"boxed\" && descriptor.typeName === \"GValue\") {\n copyValue(getHandle(target), getHandle(source));\n\n return;\n }\n\n if ((descriptor.kind === \"boxed\" || descriptor.kind === \"struct\") && descriptor.size !== undefined) {\n copy(getHandle(target), getHandle(source), descriptor.size);\n\n return;\n }\n\n throw new Error(`Cannot write caller-allocated ${descriptor.kind} out-parameter: no known byte size`);\n};\n\nconst isCallerAllocatedOut = (descriptor: Descriptor): boolean =>\n (descriptor.kind === \"boxed\" || descriptor.kind === \"struct\") && descriptor.isCallerAllocated === true;\n\nconst collectRefArg = (\n descriptor: RefDescriptor,\n wrappedValue: unknown,\n inputs: unknown[],\n out: { params: OutParam[]; argIndex: number },\n): void => {\n if (descriptor.inout === true) {\n inputs.push((wrappedValue as { value: unknown }).value);\n }\n\n out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });\n};\n\nconst collectCallbackArg = (\n descriptor: Descriptor | undefined,\n wrappedValue: unknown,\n inputs: unknown[],\n out: { params: OutParam[]; argIndex: number },\n): void => {\n if (descriptor?.kind === \"ref\") {\n collectRefArg(descriptor, wrappedValue, inputs, out);\n\n return;\n }\n\n inputs.push(wrappedValue);\n\n if (descriptor !== undefined && isCallerAllocatedOut(descriptor)) {\n out.params.push({ value: wrappedValue, descriptor, argIndex: out.argIndex });\n }\n};\n\nconst partitionCallbackArgs = (\n effectiveTypes: Descriptor[],\n wrapped: unknown[],\n start: number,\n): { inputs: unknown[]; outParams: OutParam[] } => {\n const inputs: unknown[] = [];\n const params: OutParam[] = [];\n const collected = { params, argIndex: start };\n\n for (let i = start; i < effectiveTypes.length; i++) {\n collected.argIndex = i;\n collectCallbackArg(effectiveTypes[i], wrapped[i], inputs, collected);\n }\n\n return { inputs, outParams: params };\n};\n\nconst hasOutParamArg = (descriptor: Descriptor | undefined): boolean =>\n descriptor !== undefined && (descriptor.kind === \"ref\" || isCallerAllocatedOut(descriptor));\n\nconst hasRefOutParamArg = (descriptor: Descriptor | undefined): boolean =>\n descriptor?.kind === \"ref\" && descriptor.inout !== true;\n\nconst haveOutParamArgs = (effectiveTypes: Descriptor[], start: number): boolean =>\n effectiveTypes.slice(start).some((descriptor) => hasOutParamArg(descriptor));\n\nconst haveRefOutParamArgs = (effectiveTypes: Descriptor[], start: number): boolean =>\n effectiveTypes.slice(start).some((descriptor) => hasRefOutParamArg(descriptor));\n\nconst sizeParamIndexFor = (descriptor: Descriptor): number | undefined => {\n if (descriptor.kind !== \"ref\") {\n return undefined;\n }\n\n const { innerDescriptor } = descriptor;\n\n return innerDescriptor.kind === \"array\" ? innerDescriptor.sizeParamIndex : undefined;\n};\n\nconst lengthOutParamIndices = (outParams: OutParam[]): Map<number, number> => {\n const indices: Map<number, number> = new Map();\n\n for (const outParam of outParams) {\n const sizeParamIndex = sizeParamIndexFor(outParam.descriptor);\n\n if (sizeParamIndex !== undefined) {\n indices.set(sizeParamIndex, outParam.argIndex);\n }\n }\n\n return indices;\n};\n\nconst writeOutParams = (outParams: OutParam[], outValues: unknown[]): Map<number, unknown> => {\n const written: Map<number, unknown> = new Map();\n\n for (const [position, outParam] of outParams.entries()) {\n const outValue = outValues[position];\n const { descriptor } = outParam;\n written.set(outParam.argIndex, outValue);\n\n if (descriptor.kind === \"ref\") {\n (outParam.value as { value: unknown }).value = toNative(descriptor.innerDescriptor, outValue);\n } else if (outValue != null && outParam.value != null) {\n fillCallerAllocatedBuffer(descriptor, outParam.value, outValue);\n }\n }\n\n return written;\n};\n\nconst groupOutParams = (outParams: OutParam[]): OutParamGroups => {\n const lengths = lengthOutParamIndices(outParams);\n const groups: OutParamGroups = { lengthLinks: [], valueParams: [] };\n\n for (const outParam of outParams) {\n const sourceIndex = lengths.get(outParam.argIndex);\n\n if (sourceIndex === undefined) {\n groups.valueParams.push(outParam);\n } else {\n groups.lengthLinks.push({ target: outParam, sourceIndex });\n }\n }\n\n return groups;\n};\n\nconst getFoldedLength = (source: unknown): number => {\n const length = (source as { length?: unknown } | null | undefined)?.length;\n\n return typeof length === \"number\" ? length : 0;\n};\n\nconst writeFoldedLengths = (lengthLinks: LengthLink[], written: Map<number, unknown>): void => {\n for (const link of lengthLinks) {\n (link.target.value as { value: unknown }).value = getFoldedLength(written.get(link.sourceIndex));\n }\n};\n\nconst collectRefSeeds = (outParams: OutParam[]): RefSeeds => {\n const seeds: RefSeeds = new Map();\n\n for (const outParam of outParams) {\n const seed = (outParam.value as { value?: unknown } | null)?.value;\n\n if (seed != null && hasRefOutParamArg(outParam.descriptor)) {\n seeds.set(outParam.argIndex, seed);\n }\n }\n\n return seeds;\n};\n\nconst applyCallback = (plan: CallbackPlan, thisArg: unknown, inputs: unknown[], outParams: OutParam[]): unknown => {\n if (!plan.hasRefOutParams) {\n return plan.fn.apply(thisArg, inputs);\n }\n\n pushSeedFrame({ argDescriptors: plan.effectiveTypes, instance: thisArg, seeds: collectRefSeeds(outParams) });\n\n try {\n return plan.fn.apply(thisArg, inputs);\n } finally {\n popSeedFrame();\n }\n};\n\nconst getThisArg = (receiver: CallbackReceiver, wrapped: unknown[]): unknown =>\n receiver === \"this\" ? (wrapped[0] ?? null) : null;\n\nconst wrapCallbackArgs = (effectiveTypes: Descriptor[], rawArgs: unknown[]): void => {\n let index = 0;\n\n for (const descriptor of effectiveTypes) {\n rawArgs[index] = fromNative(descriptor, rawArgs[index]);\n index += 1;\n }\n};\n\nconst trimCallbackInputs = (plan: CallbackPlan, wrapped: unknown[]): unknown[] => {\n const count = plan.effectiveTypes.length;\n\n if (wrapped.length > count) {\n wrapped.length = count;\n }\n\n for (let index = 0; index < plan.start; index++) {\n wrapped.shift();\n }\n\n return wrapped;\n};\n\nconst runCallback = (plan: CallbackPlan, rawArgs: unknown[]): unknown => {\n const { effectiveTypes, returnDescriptor } = plan;\n wrapCallbackArgs(effectiveTypes, rawArgs);\n const thisArg = getThisArg(plan.receiver, rawArgs);\n\n if (!plan.hasOutParams) {\n return toNative(returnDescriptor, plan.fn.apply(thisArg, trimCallbackInputs(plan, rawArgs)));\n }\n\n const { inputs, outParams } = partitionCallbackArgs(effectiveTypes, rawArgs, plan.start);\n const result = applyCallback(plan, thisArg, inputs, outParams);\n\n if (outParams.length === 0) {\n return toNative(returnDescriptor, result);\n }\n\n const { lengthLinks, valueParams } = groupOutParams(outParams);\n const { primary, outValues } = splitTupleResult(result, returnDescriptor.kind !== \"void\", valueParams.length);\n writeFoldedLengths(lengthLinks, writeOutParams(valueParams, outValues));\n\n return toNative(returnDescriptor, primary);\n};\n\nconst getEffectiveTypes = (spec: CallbackSpec): Descriptor[] => {\n const { userDataIndex } = spec;\n\n if (userDataIndex === undefined) {\n return spec.argDescriptors;\n }\n\n return spec.argDescriptors.filter((_, i) => i !== userDataIndex);\n};\n\nconst wrapCallbackValue = (spec: CallbackDescriptor, callback: unknown): unknown =>\n callback == null ? callback : wrapCallback(callback as Callback, spec, \"none\");\n\nfunction wrapCallback(fn: Callback, spec: CallbackSpec, receiver: CallbackReceiver): Callback {\n const effectiveTypes = getEffectiveTypes(spec);\n const start = receiver === \"none\" ? 0 : 1;\n\n const plan: CallbackPlan = {\n fn,\n effectiveTypes,\n returnDescriptor: spec.returnDescriptor,\n start,\n receiver,\n hasOutParams: haveOutParamArgs(effectiveTypes, start),\n hasRefOutParams: haveRefOutParamArgs(effectiveTypes, start),\n };\n\n return (...rawArgs: unknown[]): unknown => runCallback(plan, rawArgs);\n}\n\nexport { isCallerAllocatedOut, wrapCallbackValue, wrapCallback };\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ExternalObject, type Handle } from "@gtkx/native";
|
|
2
|
+
/**
|
|
3
|
+
* Handler backing a `GClosure`. It receives the closure's parameters already converted from their
|
|
4
|
+
* `GValue`s, and its result is written back into the closure's return `GValue` when it has one.
|
|
5
|
+
*
|
|
6
|
+
* A parameter that is itself a `GValue`, such as the target a property binding transform fills in,
|
|
7
|
+
* arrives as the caller's own `GObject.Value` rather than a copy, so writing to it is how the
|
|
8
|
+
* handler produces that parameter's value. It stops being valid once the handler returns.
|
|
9
|
+
*/
|
|
10
|
+
type ClosureCallback = (...args: never[]) => unknown;
|
|
11
|
+
/**
|
|
12
|
+
* Marshals a value passed where a `GObject.Closure` is expected into a closure handle: a function
|
|
13
|
+
* becomes a new `GClosure` dispatching into it, and an existing closure yields its own handle.
|
|
14
|
+
* @param value Function to wrap, or an already-built closure.
|
|
15
|
+
* @throws {ClosureMarshalError} When the value is neither.
|
|
16
|
+
*/
|
|
17
|
+
declare function toClosure(value: unknown): ExternalObject<Handle>;
|
|
18
|
+
/** Same as {@link toClosure}, but passes a null or undefined value through as no closure at all. */
|
|
19
|
+
declare function tryToClosure(value: unknown): ExternalObject<Handle> | undefined;
|
|
20
|
+
/** Thrown when a value passed where a `GObject.Closure` is expected cannot be marshalled into one. */
|
|
21
|
+
declare class ClosureMarshalError extends TypeError {
|
|
22
|
+
/** Name callers match on when the error is caught as a plain `TypeError`. */
|
|
23
|
+
name: string;
|
|
24
|
+
}
|
|
25
|
+
export { type ClosureCallback, ClosureMarshalError, toClosure, tryToClosure };
|
|
26
|
+
//# sourceMappingURL=closure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"closure.d.ts","sourceRoot":"","sources":["../src/closure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,MAAM,EAAQ,MAAM,cAAc,CAAC;AAStE;;;;;;;GAOG;AACH,KAAK,eAAe,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC;AAyFrD;;;;;GAKG;AACH,iBAAS,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,CAUzD;AAED,oGAAoG;AACpG,iBAAS,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,SAAS,CAExE;AAED,sGAAsG;AACtG,cAAM,mBAAoB,SAAQ,SAAS;IACvC,6EAA6E;IAC7D,IAAI,SAAyB;CAChD;AAED,OAAO,EAAE,KAAK,eAAe,EAAE,mBAAmB,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC"}
|