From 52e7485434933d7133f93ecad015b142e1a9a3b8 Mon Sep 17 00:00:00 2001 From: Nico Rehwaldt Date: Thu, 14 Dec 2023 23:07:48 +0100 Subject: [PATCH] WIP --- lib/simulator/Simulator.js | 67 ++++++++++++++++++---- lib/simulator/behaviors/ProcessBehavior.js | 29 ++++++++-- lib/simulator/util/ModelUtil.js | 13 +++++ 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/lib/simulator/Simulator.js b/lib/simulator/Simulator.js index b268fe2f..398aa9dc 100644 --- a/lib/simulator/Simulator.js +++ b/lib/simulator/Simulator.js @@ -17,12 +17,27 @@ import { is, isAny, isBoundaryEvent, + isCatchEvent, isCompensationEvent, isEventSubProcess, isInterrupting, - isStartEvent + isStartEvent, + isStartNode } from './util/ModelUtil'; +/** + * @typedef { any } DiagramElement + * + * @typedef { { + * element: DiagramElement, + * interrupting: boolean, + * boundary: boolean, + * iref?: string, + * ref: DiagramElement, + * persistent?: boolean, + * type: string + * } } SimulatorEvent + */ export default function Simulator(injector, eventBus, elementRegistry) { @@ -148,7 +163,9 @@ export default function Simulator(injector, eventBus, elementRegistry) { scope }); - scopeChanged(parentScope); + if (scope.parent) { + scopeChanged(scope.parent); + } }); return scope; @@ -290,6 +307,11 @@ export default function Simulator(injector, eventBus, elementRegistry) { return null; } + /** + * @param { any } element + * + * @return {SimulatorEvent} + */ function getEvent(element) { // do not double-return element @@ -638,21 +660,44 @@ export default function Simulator(injector, eventBus, elementRegistry) { rootScopes.push(scope); - const startEvents = element.children.filter(isStartEvent); + const startNodes = element.children.filter(isStartNode); + + const noneStarts = []; - for (const startEvent of startEvents) { + for (const startNode of startNodes) { const event = { - ...getEvent(startEvent), + ...getEvent(startNode), interrupting: false }; - // start events can always be triggered - subscribe(scope, event, initiator => signal({ - element, - startEvent, - initiator - })); + console.log(event); + + if (isCatchEvent(startNode) || event.type === 'none') { + noneStarts.push([ event, startNode ]); + } else { + + // start events can always be triggered + subscribe(scope, event, initiator => signal({ + element, + startNodes: [ startNode ], + initiator + })); + } + } + + if (noneStarts.length) { + const startNodes = noneStarts.map(([ _, node ]) => node); + + for (const [ event ] of noneStarts) { + + // start events can always be triggered + subscribe(scope, event, initiator => signal({ + element, + startNodes, + initiator + })); + } } }); diff --git a/lib/simulator/behaviors/ProcessBehavior.js b/lib/simulator/behaviors/ProcessBehavior.js index debb2844..fedc3746 100644 --- a/lib/simulator/behaviors/ProcessBehavior.js +++ b/lib/simulator/behaviors/ProcessBehavior.js @@ -1,3 +1,8 @@ +import { + isStartEvent +} from '../util/ModelUtil'; + + export default function ProcessBehavior( simulator, scopeBehavior) { @@ -13,17 +18,29 @@ ProcessBehavior.prototype.signal = function(context) { const { startEvent, + startNodes = startEvent ? [ startEvent ] : [], scope } = context; - if (!startEvent) { - throw new Error('missing '); + if (!startNodes.length) { + throw new Error('missing '); + } + + for (const startNode of startNodes) { + + if (isStartEvent(startNode)) { + this._simulator.signal({ + element: startNode, + parentScope: scope + }); + } else { + this._simulator.enter({ + element: startNode, + scope + }); + } } - this._simulator.signal({ - element: startEvent, - parentScope: scope - }); }; ProcessBehavior.prototype.exit = function(context) { diff --git a/lib/simulator/util/ModelUtil.js b/lib/simulator/util/ModelUtil.js index 969d1d27..81b160a8 100644 --- a/lib/simulator/util/ModelUtil.js +++ b/lib/simulator/util/ModelUtil.js @@ -49,6 +49,19 @@ export function isBoundaryEvent(element) { return is(element, 'bpmn:BoundaryEvent') && !isLabel(element); } +export function isImplicitStart(element) { + return ( + !isBoundaryEvent(element) && + !isEventSubProcess(element) && + !isSequenceFlow(element) && + element.incoming.length === 0 + ); +} + +export function isStartNode(element) { + return isStartEvent(element) || isImplicitStart(element); +} + export function isStartEvent(element) { return is(element, 'bpmn:StartEvent') && !isLabel(element); }