Skip to main content

serial

Short summary

Method to perform a given action on all objects inside the collection. Objects are invoked with the applier in order until the applier returns 'SUCCESS', only then the next object will be invoked. When an applier returns BUSY, foreach won't continue on the next object and returns BUSY. The order in which the appliers are invoked on the objects is defined by the iterator. If at any point the applier returns an error the serial foreach stops and returns an error.

Return: SUCCESS: if applier returned SUCCESS on every object, ABORTED: execute has a falling edge during iterate, BUSY: When serial had rising edge on execute and applier returned busy for last evaluated object, IDLE: serial wasn't started yet, ERROR: error occured during execution

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 serial : 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;
END_VAR
VAR_INST
object :CNM_AbstractObject.IObject;
applierIndex :UDINT;
returnState :CNM_ReturnTypes.SingleExecutionState := CNM_ReturnTypes.SingleExecutionState.IDLE;;
returnStateObjects :CNM_ReturnTypes.SingleExecutionState;
returnStateApply :CNM_ReturnTypes.SingleExecutionState;
currentApplier :CNM_CollectionInterfaces.IApplier;
cycleManager :CNM_CycleManager.SimpleCycleManager;
END_VAR
VAR CONSTANT
STEP_IDLE :DINT := CNM_ReturnTypes.DefaultSteps.STEP.IDLE;
STEP_INIT :DINT := CNM_ReturnTypes.DefaultSteps.STEP.INIT;
STEP_SELECT_APPLIER :DINT := 2;
STEP_GET_OBJECT :DINT := 3;
STEP_APPLY :DINT := 4;
STEP_SUCCESS :DINT := CNM_ReturnTypes.DefaultSteps.STEP.SUCCESS;
STEP_ERROR :DINT := CNM_ReturnTypes.DefaultSteps.STEP.ERROR;
STEP_ABORT :DINT := CNM_ReturnTypes.DefaultSteps.STEP.ABORT;

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.step.next := SEL(THIS^.isObjectNull(applier), STEP_SELECT_APPLIER, STEP_ERROR);
IF ((
THIS^.isObjectNull(THIS^.serialIterator)
) AND_THEN (
THIS^.usedCollection.createNewIterator(iterator => THIS^.serialIterator)
<> CNM_ReturnTypes.SingleExecutionResult.SUCCESS
)
) THEN
cycleManager.step.next := STEP_ERROR;
END_IF
cycleManager.proceed();

STEP_SELECT_APPLIER:
continueForeach := TRUE;
THIS^.serialIterator.iterate(execute := FALSE);
cycleManager.proceedWith(
step := THIS^.selectApplier(
nextStep := STEP_GET_OBJECT,
applier := applier,
applierIndex := applierIndex,
nextApplier := currentApplier
)
);

STEP_GET_OBJECT:
returnStateObjects := THIS^.serialIterator.iterate(execute := TRUE, object => object);
CASE (returnStateObjects) OF
CNM_ReturnTypes.SingleExecutionState.BUSY:
IF(currentApplier.accept(object) = CNM_ReturnTypes.SingleExecutionResult.SUCCESS)THEN
currentApplier.apply(FALSE);
cycleManager.step.next := STEP_APPLY;
ELSE
cycleManager.step.next := STEP_ERROR;
END_IF
CNM_ReturnTypes.SingleExecutionState.SUCCESS:
cycleManager.step.next := STEP_SELECT_APPLIER;
CNM_ReturnTypes.SingleExecutionState.ABORTED:
cycleManager.step.next := STEP_ABORT;
ELSE
cycleManager.step.next := STEP_ERROR;
END_CASE
continueForeach := TRUE;
cycleManager.proceed();

STEP_APPLY:
continueForeach := TRUE;
IF(currentApplier.accept(object) = CNM_ReturnTypes.SingleExecutionResult.SUCCESS)THEN
returnStateApply := currentApplier.apply(TRUE);
CASE (returnStateApply) OF
CNM_ReturnTypes.SingleExecutionState.BUSY:
continueForeach := FALSE;
CNM_ReturnTypes.SingleExecutionState.SUCCESS:
cycleManager.proceedWith(STEP_GET_OBJECT);
CNM_ReturnTypes.SingleExecutionState.ABORTED:
cycleManager.proceedWith(STEP_ABORT);
ELSE
cycleManager.proceedWith(STEP_ERROR);
END_CASE
ELSE
cycleManager.proceedWith(STEP_ERROR);
END_IF
END_CASE
UNTIL (NOT continueForeach)
END_REPEAT
serial := cycleManager.state;