diff --git a/src/components/Factory.ts b/src/components/Factory.ts new file mode 100644 index 0000000..ffb3ef8 --- /dev/null +++ b/src/components/Factory.ts @@ -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 + private controlIds: Map> + private control?: UI + + constructor(protected name: string) { + super() + this.controlIds = new Map() + } + + setControlId(name: string, element: UI) { + 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 }[]) { + elements.forEach(({ name, element }) => this.controlIds.set(name, element)) + return this + } + + setControl(element: UI) { + 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 = {} + this.controlIds.forEach((value, key) => (controlIds[key] = key + value.toString())) + obj.control_ids = controlIds + } + + return obj + } +} diff --git a/src/components/UI.ts b/src/components/UI.ts index 3699b02..74acfda 100644 --- a/src/components/UI.ts +++ b/src/components/UI.ts @@ -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> = { + child: C + properties?: C extends UI ? Partial> : never + name?: string + callback?: (name: string, parent: UI) => void +} + export class UI extends Class { readonly path: string readonly name: string @@ -49,6 +57,7 @@ export class UI extends Class protected readonly buttonMappings: ButtonMapping[] = [] protected readonly anims: (Animation | AnimationKeyframe)[] = [] protected readonly extendType?: Type + protected factory?: FactoryManager protected properties: Properties = {} protected bindCache = new Map() @@ -93,6 +102,11 @@ export class UI 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 extends Class return this } + addChilds[]>(...childs: { [K in keyof UIs]: ChildInput }) { + const childrenList = childs as unknown as ChildInput>[] + + childrenList.forEach(({ child, properties, name, callback }) => { + this.addChild(child, properties, name, callback) + }) + + return this + } + addAnimations(...anims: (Animation | AnimationKeyframe)[]) { this.anims.push(...anims) return this @@ -186,6 +210,7 @@ export class UI 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)) diff --git a/src/components/Utils.ts b/src/components/Utils.ts index 888e651..1d9715b 100644 --- a/src/components/Utils.ts +++ b/src/components/Utils.ts @@ -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>(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 || {}) }