add factory and addchilds method

This commit is contained in:
Asaki Yuki 2026-02-24 20:30:30 +07:00
parent 2c1242a9ad
commit 7d2b1b023b
3 changed files with 83 additions and 0 deletions

53
src/components/Factory.ts Normal file
View file

@ -0,0 +1,53 @@
import { Type } from "../types/enums/Type.js"
import { Variable } from "../types/properties/value.js"
import { Class } from "./Class.js"
import { UI } from "./UI.js"
export class FactoryManager extends Class {
private maxChildrenSize?: number
private factoryVariables?: Array<Variable>
private controlIds: Map<string, UI<Type>>
private control?: UI<Type>
constructor(protected name: string) {
super()
this.controlIds = new Map()
}
setControlId(name: string, element: UI<Type>) {
if (this.control) throw new Error("Cannot set control id after setting control")
this.controlIds.set(name, element)
return this
}
setControlIds(...elements: { name: string; element: UI<Type> }[]) {
elements.forEach(({ name, element }) => this.controlIds.set(name, element))
return this
}
setControl(element: UI<Type>) {
if (this.controlIds.size) throw new Error("Cannot set control after setting control ids")
this.control = element
return this
}
setMaxChildrenSize(size: number) {
this.maxChildrenSize = size
return this
}
protected toJSON() {
const obj: any = { name: this.name }
if (this.maxChildrenSize) obj.max_children_size = this.maxChildrenSize
if (this.factoryVariables) obj.variables = this.factoryVariables
if (this.control) obj.control_name = this.control.toString().slice(1)
if (this.controlIds.size) {
const controlIds: Record<string, string> = {}
this.controlIds.forEach((value, key) => (controlIds[key] = key + value.toString()))
obj.control_ids = controlIds
}
return obj
}
}

View file

@ -22,6 +22,7 @@ import nodepath from "path"
import util from "node:util"
import { config, isNotObfuscate, uiBuildFolder } from "../compilers/Configuration.js"
import { FactoryManager } from "./Factory.js"
interface ExtendUI {
name: string
@ -35,6 +36,13 @@ const fileExt = config.compiler?.fileExtension
: `.${config.compiler.fileExtension}`
: ".json"
type ChildInput<C extends UI<Type, Renderer | null>> = {
child: C
properties?: C extends UI<infer T, infer K> ? Partial<Properties<T, K>> : never
name?: string
callback?: (name: string, parent: UI<Type, Renderer | null>) => void
}
export class UI<T extends Type, K extends Renderer | null = null> extends Class {
readonly path: string
readonly name: string
@ -49,6 +57,7 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
protected readonly buttonMappings: ButtonMapping[] = []
protected readonly anims: (Animation<AnimType> | AnimationKeyframe<AnimType>)[] = []
protected readonly extendType?: Type
protected factory?: FactoryManager
protected properties: Properties<T, K> = <any>{}
protected bindCache = new Map<string, unknown>()
@ -93,6 +102,11 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
return this
}
setFactory(factory: FactoryManager) {
this.factory = factory
return this
}
/**
* Bind data (coming from the code) to this UI element to use.
* @param bindings
@ -149,6 +163,16 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
return this
}
addChilds<UIs extends readonly UI<Type, Renderer | null>[]>(...childs: { [K in keyof UIs]: ChildInput<UIs[K]> }) {
const childrenList = childs as unknown as ChildInput<UI<Type, Renderer | null>>[]
childrenList.forEach(({ child, properties, name, callback }) => {
this.addChild(child, properties, name, callback)
})
return this
}
addAnimations(...anims: (Animation<AnimType> | AnimationKeyframe<AnimType>)[]) {
this.anims.push(...anims)
return this
@ -186,6 +210,7 @@ export class UI<T extends Type, K extends Renderer | null = null> extends Class
if (this.bindings.length) obj.bindings = this.bindings
if (this.variables.length) obj.variables = this.variables
if (this.buttonMappings.length) obj.button_mappings = this.buttonMappings
if (this.factory) obj.factory = this.factory
if (this.anims.length) obj.anims = this.anims.map(a => String(a))

View file

@ -46,6 +46,7 @@ import {
isNotObfuscate,
namespaceCount,
} from "../compilers/Configuration.js"
import { FactoryManager } from "./Factory.js"
type CompileBinding = `[${string}]`
@ -307,6 +308,10 @@ export function Modify<T extends Namespace, K extends Element<T>>(namespace: T,
return modifyUI
}
export function Factory(name: string) {
return new FactoryManager(name)
}
export function Panel(properties?: Panel, namespace?: string, name?: string, allowObfuscate?: boolean) {
return new UI(Type.PANEL, name, namespace, undefined, allowObfuscate).setProperties(properties || {})
}