From 2646c22e688cb10340bd5607f458d881901c1545 Mon Sep 17 00:00:00 2001 From: Misode Date: Wed, 27 May 2020 03:27:10 +0200 Subject: [PATCH] Combine filtered node and object node --- src/nodes/FilteredNode.ts | 53 --------------------------------------- src/nodes/ObjectNode.ts | 45 +++++++++++++++++++++++---------- src/schemas/Condition.ts | 7 +++--- 3 files changed, 36 insertions(+), 69 deletions(-) delete mode 100644 src/nodes/FilteredNode.ts diff --git a/src/nodes/FilteredNode.ts b/src/nodes/FilteredNode.ts deleted file mode 100644 index 4f9f63f8..00000000 --- a/src/nodes/FilteredNode.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { NodeMods, INode, NodeChildren, AbstractNode, RenderOptions } from './AbstractNode' -import { IObject } from './ObjectNode' -import { Path } from '../model/Path' -import { TreeView } from '../view/TreeView' - -export const Switch = Symbol('switch') - -type NestedNodeChildren = { - [name: string]: NodeChildren -} - -export type FilteredChildren = { - [name: string]: INode - [Switch]: NestedNodeChildren -} - -export class FilteredNode extends AbstractNode { - filter: string - fields: NodeChildren - cases: NestedNodeChildren - - constructor(filter: string, fields: FilteredChildren, mods?: NodeMods) { - super(mods) - this.filter = filter; - const {[Switch]: _switch, ..._fields} = fields - this.fields = _fields - this.cases = _switch - } - - transform(path: Path, value: IObject) { - if (value === undefined) return undefined - value = value ?? {} - const activeCase = this.cases[value[this.filter]] ?? [] - const activeFields = {...this.fields, ...activeCase} - let res: any = {} - Object.keys(activeFields).forEach(f => - res[f] = activeFields[f].transform(path.push(f), value[f]) - ) - return res; - } - - renderRaw(path: Path, value: IObject, view: TreeView, options?: RenderOptions) { - if (value === undefined) return `` - const activeCase = this.cases[value[this.filter]] ?? [] - const activeFields = {...this.fields, ...activeCase} - return `${options?.hideLabel ? `` : ` -
`} - ${Object.keys(activeFields).map(f => { - return activeFields[f].render(path.push(f), value[f], view) - }).join('')} - ${options?.hideLabel ? `` : `
`}` - } -} diff --git a/src/nodes/ObjectNode.ts b/src/nodes/ObjectNode.ts index 6c7f047a..c5e5e9bd 100644 --- a/src/nodes/ObjectNode.ts +++ b/src/nodes/ObjectNode.ts @@ -1,40 +1,59 @@ -import { AbstractNode, NodeChildren, NodeMods, RenderOptions } from './AbstractNode' -import { TreeView } from '../view/TreeView' +import { NodeMods, INode, NodeChildren, AbstractNode, RenderOptions } from './AbstractNode' import { Path } from '../model/Path' +import { TreeView } from '../view/TreeView' + +export const Switch = Symbol('switch') +export const Case = Symbol('case') + +export type NestedNodeChildren = { + [name: string]: NodeChildren +} export type IObject = { [name: string]: any } -export class ObjectNode extends AbstractNode { - protected fields: NodeChildren +export type FilteredChildren = { + [name: string]: INode + [Switch]?: string + [Case]?: NestedNodeChildren +} - constructor(fields: NodeChildren, mods?: NodeMods) { +export class ObjectNode extends AbstractNode { + fields: NodeChildren + cases: NestedNodeChildren + filter?: string + + constructor(fields: FilteredChildren, mods?: NodeMods) { super({ default: () => ({}), ...mods}) - this.fields = fields - Object.values(fields).forEach(child => { - child.setParent(this) - }) + const {[Switch]: _switch, [Case]: _case, ..._fields} = fields + this.fields = _fields + this.cases = _case ?? {} + this.filter = _switch } transform(path: Path, value: IObject) { if (value === undefined) return undefined value = value ?? {} + const activeCase = this.filter ? this.cases[value[this.filter]] : {}; + const activeFields = {...this.fields, ...activeCase} let res: any = {} - Object.keys(this.fields).forEach(f => - res[f] = this.fields[f].transform(path.push(f), value[f]) + Object.keys(activeFields).forEach(f => + res[f] = activeFields[f].transform(path.push(f), value[f]) ) return res; } renderRaw(path: Path, value: IObject, view: TreeView, options?: RenderOptions) { value = value ?? {} + const activeCase = this.filter ? this.cases[value[this.filter]] : {}; + const activeFields = {...this.fields, ...activeCase} return `${options?.hideLabel ? `` : `
`} - ${Object.keys(this.fields).map(f => { - return this.fields[f].render(path.push(f), value[f], view) + ${Object.keys(activeFields).map(f => { + return activeFields[f].render(path.push(f), value[f], view) }).join('')} ${options?.hideLabel ? `` : `
`}` } diff --git a/src/schemas/Condition.ts b/src/schemas/Condition.ts index 5f374a0f..71aa46a2 100644 --- a/src/schemas/Condition.ts +++ b/src/schemas/Condition.ts @@ -2,7 +2,7 @@ import { EnumNode } from '../nodes/EnumNode'; import { ResourceNode } from '../nodes/custom/ResourceNode'; import { NumberNode } from '../nodes/NumberNode'; import { BooleanNode } from '../nodes/BooleanNode'; -import { FilteredNode, Switch } from '../nodes/FilteredNode'; +import { ObjectNode, Switch, Case } from '../nodes/ObjectNode'; import { ListNode } from '../nodes/ListNode'; import { RangeNode } from '../nodes/custom/RangeNode'; import { MapNode } from '../nodes/MapNode'; @@ -15,9 +15,10 @@ import './Predicates' const entitySources = ['this', 'killer', 'killer_player'] -export const ConditionSchema = SchemaRegistry.register('condition', new FilteredNode('condition', { +export const ConditionSchema = SchemaRegistry.register('condition', new ObjectNode({ condition: new EnumNode(conditions, 'random_chance'), - [Switch]: { + [Switch]: 'condition', + [Case]: { 'alternative': { terms: new ListNode( new ReferenceNode('condition')