diff options
Diffstat (limited to 'core/gjs/src/gobject.ts')
-rw-r--r-- | core/gjs/src/gobject.ts | 178 |
1 files changed, 0 insertions, 178 deletions
diff --git a/core/gjs/src/gobject.ts b/core/gjs/src/gobject.ts deleted file mode 100644 index 2658555..0000000 --- a/core/gjs/src/gobject.ts +++ /dev/null @@ -1,178 +0,0 @@ -import GObject from "gi://GObject" -export default 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<GObject.GType> -} - -type PropertyDeclaration = - | InstanceType<typeof GObject.ParamSpec> - | { $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, Array<{ $gtype: GObject.GType }>, 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 - } -} |