Skip to content

Commit

Permalink
Merge pull request #176 from bhouston/start-stop-events
Browse files Browse the repository at this point in the history
Instead of a single event for NodeExecution, add NodeExecutionStart and NodeExecutionEnd
  • Loading branch information
bhouston authored Dec 1, 2022
2 parents 5f5ea12 + 7818f0d commit 5bafbca
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 17 deletions.
8 changes: 6 additions & 2 deletions examples/exec-graph/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
registerCoreProfile,
registerSceneProfile,
Registry,
traceToLogger,
validateGraph,
validateRegistry,
writeGraphToJSON
Expand Down Expand Up @@ -69,7 +68,12 @@ async function execGraph({
const engine = new Engine(graph);

if (programOptions.trace) {
engine.onNodeExecution.addListener(traceToLogger);
engine.onNodeExecutionStart.addListener((node) =>
Logger.verbose(`<< ${node.description.typeName}:${node.id} >> START`)
);
engine.onNodeExecutionEnd.addListener((node) =>
Logger.verbose(`<< ${node.description.typeName}:${node.id} >> END`)
);
}

if (programOptions.dryRun) {
Expand Down
10 changes: 8 additions & 2 deletions packages/core/src/Execution/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export class Engine {
private readonly fiberQueue: Fiber[] = [];
public readonly asyncNodes: AsyncNode[] = [];
public readonly eventNodes: EventNode[] = [];
public readonly onNodeExecution = new EventEmitter<Node>();
public readonly onNodeExecutionStart = new EventEmitter<Node>();
public readonly onNodeExecutionEnd = new EventEmitter<Node>();
public executionSteps = 0;

constructor(public readonly graph: Graph) {
Expand All @@ -27,10 +28,15 @@ export class Engine {
});
// init all event nodes at startup
this.eventNodes.forEach((eventNode) => {
// evaluate input parameters
eventNode.inputSockets.forEach((inputSocket) => {
resolveSocketValue(this.graph, inputSocket);
Assert.mustBeTrue(inputSocket.valueTypeName !== 'flow');
resolveSocketValue(this, inputSocket);
});

this.onNodeExecutionStart.emit(eventNode);
eventNode.init(this);
this.onNodeExecutionEnd.emit(eventNode);
});
}

Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/Execution/Fiber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,25 +82,27 @@ export class Fiber {

node.inputSockets.forEach((inputSocket) => {
if (inputSocket.valueTypeName !== 'flow') {
resolveSocketValue(this.graph, inputSocket);
resolveSocketValue(this.engine, inputSocket);
}
});

// first resolve all input values
// flow socket is set to true for the one flowing in, while all others are set to false.
this.engine.onNodeExecution.emit(node);
this.engine.onNodeExecutionStart.emit(node);
if (node instanceof AsyncNode) {
this.engine.asyncNodes.push(node);
node.triggered(this.engine, link.socketName, () => {
// remove from the list of pending async nodes
const index = this.engine.asyncNodes.indexOf(node);
this.engine.asyncNodes.splice(index, 1);
this.engine.onNodeExecutionEnd.emit(node);
this.executionSteps++;
});
return;
}
if (node instanceof FlowNode) {
node.triggered(this, link.socketName);
this.engine.onNodeExecutionEnd.emit(node);
this.executionSteps++;
return;
}
Expand Down
10 changes: 7 additions & 3 deletions packages/core/src/Execution/resolveSocketValue.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { Assert } from '../Diagnostics/Assert';
import { Graph } from '../Graphs/Graph';
import { ImmediateNode } from '../Nodes/ImmediateNode';
//import { ImmediateNode } from '../Nodes/ImmediateNode';
import { Socket } from '../Sockets/Socket';
import { Engine } from './Engine';

export function resolveSocketValue(graph: Graph, inputSocket: Socket) {
export function resolveSocketValue(engine: Engine, inputSocket: Socket) {
// if it has no links, leave value on input socket alone.
if (inputSocket.links.length === 0) {
return;
}

const graph = engine.graph;

const upstreamLink = inputSocket.links[0];
// caching the target node + socket here increases engine performance by 8% on average. This is a hotspot.
if (
Expand Down Expand Up @@ -44,10 +46,12 @@ export function resolveSocketValue(graph: Graph, inputSocket: Socket) {
// resolve all inputs for the upstream node (this is where the recursion happens)
// TODO: This is a bit dangerous as if there are loops in the graph, this will blow up the stack
for (const upstreamInputSocket of upstreamNode.inputSockets) {
resolveSocketValue(graph, upstreamInputSocket);
resolveSocketValue(engine, upstreamInputSocket);
}

engine.onNodeExecutionStart.emit(upstreamNode);
upstreamNode.exec();
this.engine.onNodeExecutionEnd.emit(upstreamNode);

// get the output value we wanted.
inputSocket.value = upstreamOutputSocket.value;
Expand Down
6 changes: 0 additions & 6 deletions packages/core/src/Execution/traceToLogger.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/src/Nodes/Registry/NodeTypeRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export class NodeTypeRegistry {
description.otherTypeNames
.concat([description.typeName])
.forEach((typeName) => {
console.log('typeName', typeName);
if (typeName in this.typeNameToNodeDescriptions) {
throw new Error(
`already registered node type ${typeName} (string)`
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export * from './Nodes/Templates/In0Out1FuncNode';

// loading & execution
export * from './Execution/Engine';
export * from './Execution/traceToLogger';
export * from './Graphs/IO/readGraphFromJSON';
export * from './Graphs/IO/writeGraphToJSON';
export * from './Graphs/IO/writeNodeSpecsToJSON';
Expand Down

0 comments on commit 5bafbca

Please sign in to comment.