Skip to main content

parallel

Short summary

Method to perform a given action on all objects inside the collection. All objects are invoked with the applier each cycle until all are done. Needs to reset the execution flag between calls. If at any point the applier returns an error the foreach stops and returns an error. Action to perform needs to implement IApplier. Example: You have a list of numbers: 1 2 3 and a ConcreteIncrementApplier that can take a number and increment it. Calling list.forEach(TRUE, ConcreteIncrementApplier) will increment all numbers in the list, becoming: 2 3 4.

Example 2:

myIntCollectionInstance.foreach.parallel(execute := false);
myIntCollectionInstance.foreach.parallel(execute := true, applier := double);

Return: CNM_ReturnTypes.ExecutionState

Parameters

NameTypeCommentKind
executeBOOLcontrol bit to start or abort the forEach loopinput
applierCNM_CollectionInterfaces.IApplierthe applier (action) to be used on all obejcts in the collectioninput

Code

Declaration

METHOD parallel : CNM_ReturnTypes.SingleExecutionState
VAR_INPUT
(*control bit to start or abort the forEach loop*)
execute : BOOL;
(*the applier (action) to be used on all obejcts in the collection*)
applier : CNM_CollectionInterfaces.IApplier;
END_VAR
VAR
continueForeach :BOOL;
chained :CNM_CollectionInterfaces.IChainedApplier;
END_VAR
VAR_INST
object :CNM_AbstractObject.IObject;
applierIndex :UDINT;
step :DINT;
currentApplier :CNM_CollectionInterfaces.IApplier;
cycleManager :CNM_CycleManager.SimpleCycleManager;
END_VAR
VAR CONSTANT
STEP_INIT :DINT := CNM_ReturnTypes.DefaultSteps.STEP.INIT;
STEP_SELECT_APPLIER :DINT := 2;
STEP_APPLY :DINT := 3;
STEP_SUCCESS :DINT := CNM_ReturnTypes.DefaultSteps.STEP.SUCCESS;
STEP_ERROR :DINT := CNM_ReturnTypes.DefaultSteps.STEP.ERROR;
NULL : __XWORD := 0;
END_VAR

Implementation

REPEAT
continueForeach := FALSE;
cycleManager(execute := execute);
CASE cycleManager.step.current OF
STEP_INIT:
cycleManager.configuration.sequence.requireSuccessStep := FALSE;
applierIndex := 0;
currentApplier := 0;
continueForeach := TRUE;
cycleManager.proceed();
cycleManager.step.next := SEL(THIS^.isObjectNull(applier), STEP_SELECT_APPLIER, STEP_ERROR);
IF ((
THIS^.isObjectNull(THIS^.parallelIterator)
) AND_THEN (
THIS^.usedCollection.createNewIterator(iterator => THIS^.parallelIterator)
<> CNM_ReturnTypes.SingleExecutionResult.SUCCESS
)
) THEN
cycleManager.step.next := STEP_ERROR;
END_IF

STEP_SELECT_APPLIER:
continueForeach := TRUE;
step := THIS^.selectApplier(
nextStep := STEP_APPLY,
applier := applier,
applierIndex := applierIndex,
nextApplier := currentApplier
);
IF step = STEP_SUCCESS THEN
cycleManager.proceedWith(STEP_SUCCESS);
ELSE
THIS^.parallelIterator.iterate(FALSE);
WHILE(
THIS^.parallelIterator.iterate(execute := TRUE, object => object)
= CNM_ReturnTypes.SingleExecutionState.BUSY
)DO
IF(currentApplier.accept(object) = CNM_ReturnTypes.SingleExecutionResult.SUCCESS)THEN
currentApplier.apply(FALSE);
CONTINUE;
END_IF
cycleManager.step.next := STEP_ERROR;
EXIT;
END_WHILE
cycleManager.proceed();
END_IF
STEP_APPLY:
cycleManager.step.next := STEP_SELECT_APPLIER;
THIS^.parallelIterator.iterate(FALSE);
WHILE(
THIS^.parallelIterator.iterate(execute := TRUE, object => object)
= CNM_ReturnTypes.SingleExecutionState.BUSY
)DO
currentApplier.accept(object);
CASE (currentApplier.apply(TRUE)) OF
CNM_ReturnTypes.SingleExecutionState.BUSY:
cycleManager.step.next := STEP_APPLY;
CNM_ReturnTypes.SingleExecutionState.SUCCESS:;
ELSE
continueForeach := TRUE;
cycleManager.step.next := STEP_ERROR;
EXIT;
END_CASE
END_WHILE
cycleManager.proceed();
END_CASE
UNTIL (NOT continueForeach OR_ELSE NOT execute)
END_REPEAT

parallel := cycleManager.state;