Skip to main content

iterate

Short summary

This method returns the next object in the iteration and returns an execution state.

Return: SUCCESS: if last object from collection was returned, ABORTED: execute has a falling edge during iterate, BUSY: When iterate had rising edge on execute and not all objects had been returned yet IDLE: iterate not in progress, execute is false and iterate reseted

Parameters

NameTypeCommentKind
executeBOOL-input
objectCNM_AbstractObject.IObject-output

Code

Declaration

METHOD PROTECTED iterate :CNM_ReturnTypes.SingleExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
VAR_OUTPUT
object :CNM_AbstractObject.IObject;
END_VAR
VAR_INST
currentNode :CNM_CollectionInterfaces.IBinaryTreeNode;
stacktop :__XWORD := 0;
cycleManager :CNM_CycleManager.SimpleCycleManager;
lastTreeVersion :__XWORD;
END_VAR
VAR
stacksize :UDINT;
END_VAR
VAR CONSTANT
INIT :DINT := CNM_ReturnTypes.DefaultSteps.STEP.INIT;
ITERATING :DINT := INIT + 1;
SUCCESS :DINT := CNM_ReturnTypes.DefaultSteps.STEP.SUCCESS;
ERROR :DINT := CNM_ReturnTypes.DefaultSteps.STEP.ERROR;
OBJECT_NOT_REFERENCED :__XWORD := 0;
END_VAR

Implementation

cycleManager(execute := execute);
CASE cycleManager.step.current OF
INIT:
cycleManager.configuration.sequence.requireSuccessStep := FALSE;
stacksize := THIS^.treeHeight;
object := OBJECT_NOT_REFERENCED;
lastTreeVersion := THIS^.changesToCollection;
__DELETE(THIS^.nodestack);
stacktop := 0;
THIS^.nodestack := __NEW(__XWORD, stacksize);
currentNode := THIS^.getSmallestNode(startNode:=THIS^.rootNode,nodebuffer := THIS^.nodestack,bufferindex := stacktop);
IF THIS^.isObjectValid(currentNode) THEN
object := currentNode.object;
THIS^.getInorderSuccessor(
nodebuffer := THIS^.nodestack,
bufferindex := stacktop,
successor => currentNode
);
END_IF
cycleManager.proceedWith(
step := SEL((THIS^.size > 0), SUCCESS, ITERATING)
);

ITERATING:
IF THIS^.changesToCollection <> lastTreeVersion THEN
cycleManager.proceedWith(ERROR);
iterate := CNM_ReturnTypes.SingleExecutionState.ERROR;
RETURN;
END_IF
IF THIS^.isObjectValid(currentNode) THEN
object := currentNode.object;
THIS^.getInorderSuccessor(
nodebuffer := THIS^.nodestack,
bufferindex := stacktop,
successor => currentNode
);
ELSE
__DELETE(THIS^.nodestack);
cycleManager.proceedWith(SUCCESS);
END_IF
END_CASE

iterate := cycleManager.state;