(
only_onExecute: boolean,
set_level?: boolean,
)
| 531 | |
| 532 | // This is more internal, it computes the executable nodes in order and returns it |
| 533 | computeExecutionOrder( |
| 534 | only_onExecute: boolean, |
| 535 | set_level?: boolean, |
| 536 | ): LGraphNode[] { |
| 537 | const L: LGraphNode[] = [] |
| 538 | const S: LGraphNode[] = [] |
| 539 | const M: Dictionary<LGraphNode> = {} |
| 540 | // to avoid repeating links |
| 541 | const visited_links: Record<NodeId, boolean> = {} |
| 542 | const remaining_links: Record<NodeId, number> = {} |
| 543 | |
| 544 | // search for the nodes without inputs (starting nodes) |
| 545 | for (const node of this._nodes) { |
| 546 | if (only_onExecute && !node.onExecute) { |
| 547 | continue |
| 548 | } |
| 549 | |
| 550 | // add to pending nodes |
| 551 | M[node.id] = node |
| 552 | |
| 553 | // num of input connections |
| 554 | let num = 0 |
| 555 | if (node.inputs) { |
| 556 | for (const input of node.inputs) { |
| 557 | if (input?.link != null) { |
| 558 | num += 1 |
| 559 | } |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | if (num == 0) { |
| 564 | // is a starting node |
| 565 | S.push(node) |
| 566 | if (set_level) node._level = 1 |
| 567 | } else { |
| 568 | // num of input links |
| 569 | if (set_level) node._level = 0 |
| 570 | remaining_links[node.id] = num |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | while (true) { |
| 575 | // get an starting node |
| 576 | const node = S.shift() |
| 577 | if (node === undefined) break |
| 578 | |
| 579 | // add to ordered list |
| 580 | L.push(node) |
| 581 | // remove from the pending nodes |
| 582 | delete M[node.id] |
| 583 | |
| 584 | if (!node.outputs) continue |
| 585 | |
| 586 | // for every output |
| 587 | for (const output of node.outputs) { |
| 588 | // not connected |
| 589 | // TODO: Confirm functionality, clean condition |
| 590 | if (output?.links == null || output.links.length == 0) |
no test coverage detected