From 8da6a2174296bc1b78c6dde13f6bca46e67e156a Mon Sep 17 00:00:00 2001 From: Aylur Date: Sun, 1 Sep 2024 20:19:39 +0000 Subject: docs: variable --- core/gjs/src/variable.ts | 19 +++-- docs/src/content/docs/ags/faq.md | 79 +++++++++++++++++++ docs/src/content/docs/ags/utilities.md | 2 +- docs/src/content/docs/ags/variable.md | 138 ++++++++++++++++++++++++++++++++- 4 files changed, 228 insertions(+), 10 deletions(-) diff --git a/core/gjs/src/variable.ts b/core/gjs/src/variable.ts index d583ab1..9528ffe 100644 --- a/core/gjs/src/variable.ts +++ b/core/gjs/src/variable.ts @@ -166,12 +166,14 @@ class VariableWrapper extends Function { observe( objs: Array<[obj: Connectable, signal: string]>, - callback: (...args: any[]) => T): Variable + callback: (...args: any[]) => T, + ): Variable observe( obj: Connectable, signal: string, - callback: (...args: any[]) => T): Variable + callback: (...args: any[]) => T, + ): Variable observe( objs: Connectable | Array<[obj: Connectable, signal: string]>, @@ -184,12 +186,15 @@ class VariableWrapper extends Function { if (Array.isArray(objs)) { for (const obj of objs) { const [o, s] = obj - o.connect(s, set) + const id = o.connect(s, set) + this.onDropped(() => o.disconnect(id)) } } else { - if (typeof sigOrFn === "string") - objs.connect(sigOrFn, set) + if (typeof sigOrFn === "string") { + const id = objs.connect(sigOrFn, set) + this.onDropped(() => objs.disconnect(id)) + } } return this as unknown as Variable @@ -199,7 +204,7 @@ class VariableWrapper extends Function { const Deps extends Array | Binding>, Args extends { [K in keyof Deps]: Deps[K] extends Variable - ? T : Deps[K] extends Binding ? T : never + ? T : Deps[K] extends Binding ? T : never }, V = Args, >(deps: Deps, fn: (...args: Args) => V = (...args) => args as unknown as V) { @@ -221,7 +226,7 @@ export const Variable = new Proxy(VariableWrapper as any, { }) as { derive: typeof VariableWrapper["derive"] (init: T): Variable - new(init: T): Variable + new (init: T): Variable } export default Variable diff --git a/docs/src/content/docs/ags/faq.md b/docs/src/content/docs/ags/faq.md index eca31c7..5599fe3 100644 --- a/docs/src/content/docs/ags/faq.md +++ b/docs/src/content/docs/ags/faq.md @@ -78,3 +78,82 @@ App.start({ If there is a name clash with an icon from your current icon pack the icon pack will take precedence ::: + +## Logging + +The `console` API in gjs uses glib logging functions. +If you just want to print some text as is to stdout +use the globally available `print` function or `printerr` for stderr. + +```js +print("print this line to stdout") +printerr("print this line to stderr") +``` + +## Binding custom structures + +The `bind` function can take two types of objects. + +```typescript +interface Subscribable { + subscribe(callback: (value: T) => void): () => void + get(): T +} + +interface Connectable { + connect(signal: string, callback: (...args: any[]) => unknown): number + disconnect(id: number): void +} +``` + +`Connectable` is for mostly gobjects, while `Subscribable` is for `Variables` +and custom objects. + +For example you can compose `Variables` in using a class. + +```typescript +type MyVariableValue = { + number: number + string: string +} + +class MyVariable { + number = Variable(0) + string = Variable("") + + get(): MyVariableValue { + return { + number: this.number.get(), + string: this.string.get(), + } + } + + subscribe(callback: (v: MyVariableValue) => void) { + const unsub1 = this.number.subscribe((value) => { + callback({ string: value, number: this.number.get() }) + }) + + const unsub2 = this.string.subscribe((value) => { + callback({ number: value, string: this.string.get() }) + }) + + return () => { + unsub1() + unsub2() + } + } +} +``` + +Then it can be used with `bind`. + +```tsx +function MyWidget() { + const myvar = new MyVariableValue() + const label = bind(myvar).as(({ string, number }) => { + return `${string} ${number}` + }) + + return