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
- Return type: CNM_ReturnTypes.SingleExecutionState
Parameters
| Name | Type | Comment | Kind |
|---|---|---|---|
| execute | BOOL | control bit to start or abort the forEach loop | input |
| applier | CNM_CollectionInterfaces.IApplier | the applier (action) to be used on all obejcts in the collection | input |
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;