From d96949c6059a5dfaacb9fa856085845a4db61713 Mon Sep 17 00:00:00 2001 From: Misode Date: Sun, 24 May 2020 02:40:14 +0200 Subject: [PATCH] Add nodes with render and transform --- public/index.html | 4 +++- src/app/app.ts | 44 ++++++++++++++++++++++++++++++++++++++- src/nodes/AbstractNode.ts | 33 +++++++++++++++++++++++++++++ src/nodes/EnumNode.ts | 17 +++++++++++++++ src/nodes/ObjectNode.ts | 22 ++++++++++++++++++++ src/nodes/StringNode.ts | 11 ++++++++++ 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/nodes/AbstractNode.ts create mode 100644 src/nodes/EnumNode.ts create mode 100644 src/nodes/ObjectNode.ts create mode 100644 src/nodes/StringNode.ts diff --git a/public/index.html b/public/index.html index 8a1b943c..73a8680c 100644 --- a/public/index.html +++ b/public/index.html @@ -6,7 +6,9 @@ Document -
+
+
+
diff --git a/src/app/app.ts b/src/app/app.ts index 8a640224..79f0703c 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -1 +1,43 @@ -document!.getElementById('root')!.textContent = 'Hello world!'; +import { EnumNode } from '../nodes/EnumNode' +import { ObjectNode } from '../nodes/ObjectNode' +import { StringNode } from '../nodes/StringNode' + +const EntityCollection = ['sheep', 'pig'] + +const predicateTree = { + id: 'predicate', + fields: { + condition: new EnumNode(['foo', 'bar'], { + transform: (s: string) => (s === 'foo') ? {predicate: 'baz'} : s + }), + predicate: new ObjectNode({ + type: new EnumNode(EntityCollection, {}), + nbt: new StringNode() + }) + } +}; + +function renderTree(tree: any, data: any) { + return Object.keys(tree.fields).map(f => + tree.fields[f].render(f, data[f]) + ).join('
'); +} + +function serializeTree(tree: any, data: any) { + let res: any = {} + Object.keys(tree.fields).forEach(f => + res[f] = tree.fields[f].transform(data[f]) + ) + return JSON.stringify(res); +} + +let dummyData = { + condition: 'foo', + chance: 0.4, + predicate: { + nbt: 'hi' + } +} + +document!.getElementById('view')!.innerHTML = renderTree(predicateTree, dummyData) +document!.getElementById('source')!.textContent = serializeTree(predicateTree, dummyData) diff --git a/src/nodes/AbstractNode.ts b/src/nodes/AbstractNode.ts new file mode 100644 index 00000000..e297410c --- /dev/null +++ b/src/nodes/AbstractNode.ts @@ -0,0 +1,33 @@ + +export interface INode { + setParent: (parent: INode) => void + transform: (value: T) => any + render: (field: string, value: T) => string +} + +export interface NodeChildren { + [name: string]: INode +} + +export interface NodeMods { + transform?: (value: T) => any +} + +export abstract class AbstractNode implements INode { + private transformMod = (v: T) => v + protected parent?: INode + + constructor(mods?: NodeMods) { + if (mods?.transform) this.transformMod = mods.transform + } + + setParent(parent: INode) { + this.parent = parent + } + + transform(value: T) { + return this.transformMod(value) + } + + abstract render(field: string, value: T): string +} diff --git a/src/nodes/EnumNode.ts b/src/nodes/EnumNode.ts new file mode 100644 index 00000000..4d233f6e --- /dev/null +++ b/src/nodes/EnumNode.ts @@ -0,0 +1,17 @@ +import { AbstractNode, NodeMods } from './AbstractNode' + +export class EnumNode extends AbstractNode { + private options: string[] + + constructor(options: string[], mods?: NodeMods) { + super(mods) + this.options = options + } + + render (field: string, value: string) { + return `${field} + ` + } +} diff --git a/src/nodes/ObjectNode.ts b/src/nodes/ObjectNode.ts new file mode 100644 index 00000000..b57ef76a --- /dev/null +++ b/src/nodes/ObjectNode.ts @@ -0,0 +1,22 @@ +import { AbstractNode, NodeChildren, NodeMods } from './AbstractNode' + +export class ObjectNode extends AbstractNode { + private fields: NodeChildren + + constructor(fields: NodeChildren, mods?: NodeMods) { + super(mods) + this.fields = fields + Object.values(fields).forEach(child => { + child.setParent(this) + }) + } + + render(field: string, value: any) { + value = value || {} + return `${field}:
+ ${Object.keys(this.fields).map(f => { + return '> ' + this.fields[f].render(f, value[f]) + }).join('
')} +
` + } +} diff --git a/src/nodes/StringNode.ts b/src/nodes/StringNode.ts new file mode 100644 index 00000000..9c033166 --- /dev/null +++ b/src/nodes/StringNode.ts @@ -0,0 +1,11 @@ +import { AbstractNode, NodeMods } from './AbstractNode' + +export class StringNode extends AbstractNode { + constructor(mods?: NodeMods) { + super(mods) + } + + render(field: string, value: string) { + return `${field} ${value || ''}` + } +}