From fd098d8bfc94583db2821da64e6d1f6f12513990 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Fri, 22 Oct 2021 13:24:40 -0700 Subject: [PATCH 1/5] Add comments to task plugin --- core/src/plugins/taskPlugin/task.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/core/src/plugins/taskPlugin/task.ts b/core/src/plugins/taskPlugin/task.ts index 886c03b5b..3d8761294 100644 --- a/core/src/plugins/taskPlugin/task.ts +++ b/core/src/plugins/taskPlugin/task.ts @@ -95,10 +95,19 @@ export class Task { if (!this.outputData) { const inputs = {} as Record - // here we run through all INPUTS connected to other OUTPUTS for the node. - // We run eachinput back to whatever node it is connected to. - // We run that nodes task run, and then return its output data and - // associate it with This nodes input key + + /* + This is where we are populating all the input values to be passed into the worker. + We are getting all the input connections that are connected as outputs (ie have values) + We filter out all connections which did not come from the previou node. This is to hgelp support multiple + inputs properly, otherwise we actually back propagate along every input and run it, whichI think is unwanted behaviour. + After we have filtered these out, we need to run the task, which triggers that nodes worker. After the worker runs, + the task has populated output data, which we take and we associate with the tasks input values, which are subsequently + passed to the nodes worker for processing. + + We assume here that his nodes worker does not need to access ALL values simultaneously, but is only interested in one. + There is a task option which enables this functionality just in case we have use cases that don't want this behaviour. + */ await Promise.all( this.getInputs('output').map(async key => { const thothWorkerinputs = await Promise.all( From c720291acf4a42b57249e0058431a8a768796eb6 Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Fri, 22 Oct 2021 13:25:47 -0700 Subject: [PATCH 2/5] Support new task option to only get one input value from immedate past node --- core/src/plugins/taskPlugin/task.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/core/src/plugins/taskPlugin/task.ts b/core/src/plugins/taskPlugin/task.ts index 3d8761294..21d5e97d6 100644 --- a/core/src/plugins/taskPlugin/task.ts +++ b/core/src/plugins/taskPlugin/task.ts @@ -14,6 +14,7 @@ export type TaskOptions = { outputs: Record init?: Function onRun?: Function + runOneInput?: boolean } type RunOptions = { @@ -21,6 +22,7 @@ type RunOptions = { needReset?: boolean garbage?: Task[] fromSocket?: string + fromNode?: NodeData } export type TaskOutputTypes = 'option' | 'output' @@ -85,6 +87,7 @@ export class Task { garbage = [] as Task[], propagate = true, fromSocket, + fromNode, } = options if (needReset) garbage.push(this) @@ -110,17 +113,25 @@ export class Task { */ await Promise.all( this.getInputs('output').map(async key => { - const thothWorkerinputs = await Promise.all( - this.inputs[key].map(async (con: ThothReteInput) => { + const inputPromises = this.inputs[key] + .filter((con: ThothReteInput) => { + // only filter inputs to remove ones that are not the origin if a task option is true + if (!this.component.task.runOneInput || !fromNode) return true + return con.task.node.id === fromNode.id + }) + .map(async (con: ThothReteInput) => { await con.task.run(data, { needReset: false, garbage, propagate: false, + fromNode: this.node, }) const outputData = con.task.outputData as Record + return outputData[con.key] }) - ) + + const thothWorkerinputs = await Promise.all(inputPromises) inputs[key] = thothWorkerinputs }) @@ -145,6 +156,7 @@ export class Task { needReset: false, garbage, fromSocket: con.key, + fromNode: this.node, }) }) ) From bc697c2b4fbadad9259fc12c7200b761eb136edd Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Fri, 22 Oct 2021 13:25:59 -0700 Subject: [PATCH 3/5] Use new option in playtest print --- core/src/components/PlaytestPrint.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/components/PlaytestPrint.ts b/core/src/components/PlaytestPrint.ts index 4659c2b59..d948b9bfd 100644 --- a/core/src/components/PlaytestPrint.ts +++ b/core/src/components/PlaytestPrint.ts @@ -16,6 +16,7 @@ export class PlaytestPrint extends ThothComponent { super('Playtest Print') this.task = { + runOneInput: true, outputs: { trigger: 'option', }, From 708b3238188bc6db52c9e8572ad58a81f41ba8fd Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Fri, 22 Oct 2021 13:26:22 -0700 Subject: [PATCH 4/5] Add new task option to module output --- core/src/components/ModuleOutput.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/components/ModuleOutput.ts b/core/src/components/ModuleOutput.ts index f0d04692e..edad48127 100644 --- a/core/src/components/ModuleOutput.ts +++ b/core/src/components/ModuleOutput.ts @@ -3,7 +3,7 @@ import { v4 as uuidv4 } from 'uuid' import { NodeData, ThothNode, ThothWorkerInputs } from '../../types' import { InputControl } from '../dataControls/InputControl' -import { Task } from '../plugins/taskPlugin/task' +import { TaskOptions } from '../plugins/taskPlugin/task' // @seang todo: convert data controls to typescript to remove this // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore @@ -12,18 +12,19 @@ import { ThothComponent } from '../thoth-component' const info = `The module output component adds an output socket to the parent module. It can be given a name, which is displayed on the parent.` export class ModuleOutput extends ThothComponent { - task: Partial & { outputs: { text: string } } + task: TaskOptions module: object category: string info: string contextMenuName: string constructor() { - // Name of the componentw + // Name of the component super('Module Output') this.contextMenuName = 'Output' this.task = { + runOneInput: true, outputs: { text: 'output', }, From 2bad9c1a7a2eac49173dfd6594a6c7f0a5ce30da Mon Sep 17 00:00:00 2001 From: Michael Sharpe Date: Fri, 22 Oct 2021 14:32:38 -0700 Subject: [PATCH 5/5] Add a few comments --- core/src/plugins/taskPlugin/task.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/plugins/taskPlugin/task.ts b/core/src/plugins/taskPlugin/task.ts index 21d5e97d6..6e2bfcd15 100644 --- a/core/src/plugins/taskPlugin/task.ts +++ b/core/src/plugins/taskPlugin/task.ts @@ -90,12 +90,14 @@ export class Task { fromNode, } = options + // garbage means that the nodes output value will be reset after it is all done. if (needReset) garbage.push(this) // This would be a great place to run an animation showing the signal flow. // Just needto figure out how to change the folow of the connection attached to a socket on the fly. // And animations should follow the flow of the data, not the main IO paths + // Only run the worker if the outputData isnt already populated. if (!this.outputData) { const inputs = {} as Record @@ -137,15 +139,22 @@ export class Task { }) ) + // socket info is used internally in the worker if we need to know about where signals come from. + // this is mainly used currently by the module plugin to know where the run signal should go to. const socketInfo = { target: fromSocket ? this.getInputFromConnection(fromSocket) : null, } + // the main output data of the task, which is gathered up when the next node gets this nodes value this.outputData = await this.worker(this, inputs, data, socketInfo) + // an onRun option in case a task whats to do something when the task is run. if (this.component.task.onRun) this.component.task.onRun(this.node, this, data, socketInfo) + // this is what propagates the the run command to the next nodes in the chain + // this makes use of the 'next' nodes. It also will filter out any connectios which the task has closed. + // it is this functionality that lets us control which direction the run signal flows. if (propagate) await Promise.all( this.next