From bafd48d3df9b43a1d49ec015eff30619d595468b Mon Sep 17 00:00:00 2001 From: Aylur Date: Tue, 15 Oct 2024 13:25:45 +0000 Subject: update lua and gjs layout installing the gjs package through meson or npm now results in the same exposed structure lua: fix rockspec docs: aur package --- lang/gjs/src/gobject.ts | 180 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 lang/gjs/src/gobject.ts (limited to 'lang/gjs/src/gobject.ts') diff --git a/lang/gjs/src/gobject.ts b/lang/gjs/src/gobject.ts new file mode 100644 index 0000000..4740764 --- /dev/null +++ b/lang/gjs/src/gobject.ts @@ -0,0 +1,180 @@ +export { default as GObject, default as default } from "gi://GObject" +export { default as Gio } from "gi://Gio" +export { default as GLib } from "gi://GLib" + +import GObject from "gi://GObject" +const meta = Symbol("meta") + +const { ParamSpec, ParamFlags } = GObject + +const kebabify = (str: string) => str + .replace(/([a-z])([A-Z])/g, "$1-$2") + .replaceAll("_", "-") + .toLowerCase() + +type SignalDeclaration = { + flags?: GObject.SignalFlags + accumulator?: GObject.AccumulatorType + return_type?: GObject.GType + param_types?: Array +} + +type PropertyDeclaration = + | InstanceType + | { $gtype: GObject.GType } + | typeof String + | typeof Number + | typeof Boolean + | typeof Object + +type GObjectConstructor = { + [meta]?: { + Properties?: { [key: string]: GObject.ParamSpec } + Signals?: { [key: string]: GObject.SignalDefinition } + } + new(...args: any[]): any +} + +type MetaInfo = GObject.MetaInfo, never> + +export function register(options: MetaInfo = {}) { + return function (cls: GObjectConstructor) { + GObject.registerClass({ + Signals: { ...cls[meta]?.Signals }, + Properties: { ...cls[meta]?.Properties }, + ...options, + }, cls) + } +} + +export function property(declaration: PropertyDeclaration = Object) { + return function (target: any, prop: any, desc?: PropertyDescriptor) { + target.constructor[meta] ??= {} + target.constructor[meta].Properties ??= {} + + const name = kebabify(prop) + + if (!desc) { + let value = defaultValue(declaration) + + Object.defineProperty(target, prop, { + get() { + return value + }, + set(v) { + if (v !== value) { + value = v + this.notify(name) + } + }, + }) + + Object.defineProperty(target, `set_${name.replace("-", "_")}`, { + value: function (v: any) { + this[prop] = v + }, + }) + + Object.defineProperty(target, `get_${name.replace("-", "_")}`, { + value: function () { + return this[prop] + }, + }) + + target.constructor[meta].Properties[kebabify(prop)] = pspec(name, ParamFlags.READWRITE, declaration) + } + + else { + let flags = 0 + if (desc.get) flags |= ParamFlags.READABLE + if (desc.set) flags |= ParamFlags.WRITABLE + + target.constructor[meta].Properties[kebabify(prop)] = pspec(name, flags, declaration) + } + } +} + +export function signal(...params: Array<{ $gtype: GObject.GType } | typeof Object>): +(target: any, signal: any, desc?: PropertyDescriptor) => void + +export function signal(declaration?: SignalDeclaration): +(target: any, signal: any, desc?: PropertyDescriptor) => void + +export function signal( + declaration?: SignalDeclaration | { $gtype: GObject.GType } | typeof Object, + ...params: Array<{ $gtype: GObject.GType } | typeof Object> +) { + return function (target: any, signal: any, desc?: PropertyDescriptor) { + target.constructor[meta] ??= {} + target.constructor[meta].Signals ??= {} + + const name = kebabify(signal) + + if (declaration || params.length > 0) { + // @ts-expect-error TODO: type assert + const arr = [declaration, ...params].map(v => v.$gtype) + target.constructor[meta].Signals[name] = { + param_types: arr, + } + } + else { + target.constructor[meta].Signals[name] = declaration + } + + if (!desc) { + Object.defineProperty(target, signal, { + value: function (...args: any[]) { + this.emit(name, ...args) + }, + }) + } + else { + const og: ((...args: any[]) => void) = desc.value + desc.value = function (...args: any[]) { + // @ts-expect-error not typed + this.emit(name, ...args) + } + Object.defineProperty(target, `on_${name.replace("-", "_")}`, { + value: function (...args: any[]) { + return og(...args) + }, + }) + } + } +} + +function pspec(name: string, flags: number, declaration: PropertyDeclaration) { + if (declaration instanceof ParamSpec) + return declaration + + switch (declaration) { + case String: + return ParamSpec.string(name, "", "", flags, "") + case Number: + return ParamSpec.double(name, "", "", flags, -Number.MAX_VALUE, Number.MAX_VALUE, 0) + case Boolean: + return ParamSpec.boolean(name, "", "", flags, false) + case Object: + return ParamSpec.jsobject(name, "", "", flags) + default: + // @ts-expect-error misstyped + return ParamSpec.object(name, "", "", flags, declaration.$gtype) + } +} + +function defaultValue(declaration: PropertyDeclaration) { + if (declaration instanceof ParamSpec) + return declaration.get_default_value() + + switch (declaration) { + case String: + return "default-string" + case Number: + return 0 + case Boolean: + return false + case Object: + default: + return null + } +} -- cgit v1.2.3 From e7762eb33a8d5d8c216a42fb6634b8cd87fa9f14 Mon Sep 17 00:00:00 2001 From: Aylur Date: Fri, 18 Oct 2024 12:07:13 +0000 Subject: reexport modules - Gio from file - GLib from gobject - AstalIO.Process from process - AstalIO.Time from time --- lang/gjs/src/gobject.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lang/gjs/src/gobject.ts') diff --git a/lang/gjs/src/gobject.ts b/lang/gjs/src/gobject.ts index 4740764..d37ac69 100644 --- a/lang/gjs/src/gobject.ts +++ b/lang/gjs/src/gobject.ts @@ -1,8 +1,8 @@ -export { default as GObject, default as default } from "gi://GObject" -export { default as Gio } from "gi://Gio" -export { default as GLib } from "gi://GLib" - import GObject from "gi://GObject" + +export { default as GLib } from "gi://GLib?version=2.0" +export { GObject, GObject as default } + const meta = Symbol("meta") const { ParamSpec, ParamFlags } = GObject -- cgit v1.2.3 From 004b12381b3891836ecbf3bb22aa3054145e3f38 Mon Sep 17 00:00:00 2001 From: Aylur Date: Tue, 22 Oct 2024 16:02:06 +0000 Subject: fix(gjs): property decorator make it not static --- lang/gjs/src/gobject.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'lang/gjs/src/gobject.ts') diff --git a/lang/gjs/src/gobject.ts b/lang/gjs/src/gobject.ts index d37ac69..aeb3d9e 100644 --- a/lang/gjs/src/gobject.ts +++ b/lang/gjs/src/gobject.ts @@ -4,6 +4,7 @@ export { default as GLib } from "gi://GLib?version=2.0" export { GObject, GObject as default } const meta = Symbol("meta") +const priv = Symbol("priv") const { ParamSpec, ParamFlags } = GObject @@ -55,28 +56,27 @@ export function property(declaration: PropertyDeclaration = Object) { const name = kebabify(prop) if (!desc) { - let value = defaultValue(declaration) - Object.defineProperty(target, prop, { get() { - return value + return this[priv]?.[prop] ?? defaultValue(declaration) }, - set(v) { - if (v !== value) { - value = v + set(v: any) { + if (v !== this[prop]) { + this[priv] ??= {} + this[priv][prop] = v this.notify(name) } }, }) Object.defineProperty(target, `set_${name.replace("-", "_")}`, { - value: function (v: any) { + value(v: any) { this[prop] = v }, }) Object.defineProperty(target, `get_${name.replace("-", "_")}`, { - value: function () { + value() { return this[prop] }, }) @@ -95,10 +95,10 @@ export function property(declaration: PropertyDeclaration = Object) { } export function signal(...params: Array<{ $gtype: GObject.GType } | typeof Object>): -(target: any, signal: any, desc?: PropertyDescriptor) => void + (target: any, signal: any, desc?: PropertyDescriptor) => void export function signal(declaration?: SignalDeclaration): -(target: any, signal: any, desc?: PropertyDescriptor) => void + (target: any, signal: any, desc?: PropertyDescriptor) => void export function signal( declaration?: SignalDeclaration | { $gtype: GObject.GType } | typeof Object, -- cgit v1.2.3