Alarm Message Service: Collection Implementations
Table of Contents
Introduction
Now, the concrete classes for the default factory methods can be programmed.
Doubly Linked Element
The doubly linked element class is just a simple container class to carry the object, and it can point to other doubly linked elements.
Class DoublyLinkedElement {attribute 'enable_dynamic_creation'}
{attribute 'reflection'}
FUNCTION_BLOCK DoublyLinkedElement EXTENDS Object IMPLEMENTS IDoublyLinkedElement
VAR
content :IObject;
nextElement :IDoublyLinkedElement;
previousElement :IDoublyLinkedElement;
END_VAR
|
GET PROPERTY className :ClassName |
|
className := 'DoublyLinkedElement';
|
METHOD compareTo :ComparationResult
VAR_INPUT
object :IObject;
END_VAR
VAR
element :IDoublyLinkedElement;
END_VAR
|
IF ((THIS^.isObjectNull(object)) AND (THIS^.isObjectNull(THIS^.object))) THEN
compareTo := ComparationResult.EQUAL;
ELSIF (THIS^.isObjectNull(object)) THEN
compareTo := ComparationResult.SMALLER;
ELSIF (THIS^.isObjectNull(THIS^.object)) THEN
compareTo := ComparationResult.GREATER;
ELSIF (__QUERYINTERFACE(object, element)) THEN
compareTo := THIS^.object.compareTo(element.object);
ELSE
compareTo := ComparationResult.SMALLER;
END_IF
|
METHOD FB_init :BOOL
VAR_INPUT
(* if TRUE, the retain variables are initialized (warm start / cold start) *)
bInitRetains :BOOL;
(* if TRUE, the instance afterwards gets moved into the copy code (online change) *)
bInCopyCode :BOOL;
content :IObject;
next :IDoublyLinkedElement;
previous :IDoublyLinkedElement;;
END_VAR
VAR
{attribute 'hide'}
newHashstate3 :Hashcode;
END_VAR
VAR CONSTANT
{attribute 'hide'}
NUMBER_OF_LEFT_SHIFTS :UINT := 17;
{attribute 'hide'}
NUMBER_OF_LEFT_ROTATIONS :UINT := 45;
END_VAR
|
THIS^.content := content;
THIS^.nextElement := next;
THIS^.previousElement := previous;
|
GET PROPERTY next :IDoublyLinkedElement |
|
next := THIS^.nextElement;
|
SET PROPERTY next :IDoublyLinkedElement |
|
THIS^.nextElement := next;
|
GET PROPERTY object :IObject |
|
object := THIS^.content;
|
GET PROPERTY previous :IDoublyLinkedElement |
|
previous := THIS^.previousElement;
|
GET PROPERTY previous :IDoublyLinkedElement |
|
previous := THIS^.previousElement;
|
SET PROPERTY previous :IDoublyLinkedElement |
|
THIS^.previousElement := previous;
|
Single Thread Object List
Class SingleThreadObjectList {attribute 'enable_dynamic_creation'}
{attribute 'reflection'}
FUNCTION_BLOCK SingleThreadObjectList EXTENDS Object IMPLEMENTS IList
VAR
head :IDoublyLinkedElement;
last :IDoublyLinkedElement;
comparator :IComparator;
sorter :IListSorter;
mySize :__XWORD;
END_VAR
|
METHOD append
VAR_INPUT
object : IObject;
END_VAR
VAR
new: IDoublyLinkedElement;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
RETURN(THIS^.isObjectNull(object));
new := THIS^.elementFactory.getNewDoublyLinkedElement(
object := object,
previousElement := THIS^.last,
nextElement := IS_NOT_REFERENCED,
linkElements := TRUE
);
RETURN(THIS^.isObjectNull(new));
THIS^.last := new;
IF (THIS^.isObjectNull(THIS^.head)) THEN
THIS^.head := new;
END_IF
THIS^.incrementSize();
|
GET PROPERTY className :ClassName |
|
className := 'SingleThreadObjectList';
|
METHOD clear
|
{warning disable C0139}
WHILE (THIS^.hasElement) DO
THIS^.pop;
IF (THIS^.hasElement) THEN
THIS^.dequeue;
END_IF
END_WHILE
{warning restore C0139}
|
METHOD PROTECTED compare :ComparationResult
VAR_INPUT
element1 :IDoublyLinkedElement;
element2 :IDoublyLinkedElement;
END_VAR
|
IF (THIS^.isObjectValid(THIS^.comparator)) THEN
compare := THIS^.comparator.compare(element1, element2);
ELSIF (THIS^.isObjectValid(element1)) THEN
compare := element1.compareTo(element2);
ELSIF (THIS^.isObjectValid(element2)) THEN
compare := ComparationResult.GREATER;
ELSE
compare := ComparationResult.EQUAL;
END_IF
|
METHOD compareTo :ComparationResult
VAR_INPUT
object : IObject;
END_VAR
VAR
list :IList;
END_VAR
|
compareTo := ComparationResult.EQUAL;
IF (THIS^.isObjectNull(object)) THEN
compareTo := ComparationResult.GREATER;
ELSIF (__QUERYINTERFACE(object, list)) THEN
IF (THIS^.size < list.size) THEN
compareTo := ComparationResult.SMALLER;
ELSIF (THIS^.size > list.size) THEN
compareTo := ComparationResult.GREATER;
END_IF
END_IF
|
METHOD PROTECTED decrementSize
VAR CONSTANT
SIZE_INCREMENT :__XWORD := 1;
END_VAR
|
THIS^.mySize := (THIS^.mySize - SIZE_INCREMENT);
|
GET PROPERTY dequeue :IObject |
VAR
head :IDoublyLinkedElement;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
dequeue := IS_NOT_REFERENCED;
IF (THIS^.isObjectValid(THIS^.head)) THEN
dequeue := THIS^.head.object;
head := THIS^.head;
THIS^.head := head.next;
THIS^.elementFactory.destructDoublyLinkedElement(
element := head,
unlinkElement := TRUE
);
IF (THIS^.isObjectNull(THIS^.head)) THEN
THIS^.last := IS_NOT_REFERENCED;
END_IF;
THIS^.decrementSize();
END_IF
|
GET PROPERTY PRIVATE elementFactory :IDoublyLinkedElementFactory |
VAR_INST
factoryProvider :FactoryProvider(0,0,0,0,0);
factory :IDoublyLinkedElementFactory;
END_VAR
|
IF (THIS^.isObjectNull(factory)) THEN
factory := factoryProvider.getDoublyLinkedElementFactory();
END_IF
elementFactory := factory;
|
METHOD FB_exit :BOOL
VAR_INPUT
(* if TRUE, the exit method is called for exiting an instance that is copied afterwards (online change). *)
bInCopyCode :BOOL;
END_VAR
|
THIS^.clear();
|
METHOD PROTECTED findObject :IDoublyLinkedElement
VAR_INPUT
object :IObject;
END_VAR
VAR
head :IDoublyLinkedElement;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
findObject := IS_NOT_REFERENCED;
IF (THIS^.isObjectNull(object) OR THIS^.isObjectNull(THIS^.head)) THEN
RETURN;
END_IF;
head := THIS^.head;
WHILE (THIS^.isObjectValid(head)) DO
IF (THIS^.isObjectValid(head.object)) THEN
IF (head.object.hashcode = object.hashcode) THEN
findObject := head;
EXIT;
ELSE
head := head.next;
END_IF
END_IF
END_WHILE
|
GET PROPERTY hasElement :BOOL |
|
hasElement := THIS^.isObjectValid(THIS^.head);
|
METHOD PROTECTED incrementSize
VAR CONSTANT
SIZE_INCREMENT :__XWORD := 1;
END_VAR
|
THIS^.mySize := (THIS^.mySize + SIZE_INCREMENT);
|
METHOD PROTECTED insertBefore
VAR_INPUT
element :IDoublyLinkedElement;
newNext :IDoublyLinkedElement;
END_VAR
VAR_OUTPUT
next :IDoublyLinkedElement := IS_NOT_REFERENCED;
END_VAR
VAR
oldNext :IDoublyLinkedElement := IS_NOT_REFERENCED;
newPrevious :IDoublyLinkedElement := IS_NOT_REFERENCED;
oldPrevious :IDoublyLinkedElement := IS_NOT_REFERENCED;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
THIS^.unlinkElement(element, oldNext => oldNext, oldPrevious => oldPrevious);
IF (THIS^.isObjectValid(newNext)) THEN
newPrevious := newNext.previous;
END_IF
THIS^.linkElement(newPrevious, element, newNext);
next := oldPrevious;
|
METHOD PROTECTED insertBehind
VAR_INPUT
element :IDoublyLinkedElement;
newPrevious :IDoublyLinkedElement;
END_VAR
VAR_OUTPUT
next :IDoublyLinkedElement := IS_NOT_REFERENCED;
END_VAR
VAR
oldNext :IDoublyLinkedElement := IS_NOT_REFERENCED;
newNext :IDoublyLinkedElement := IS_NOT_REFERENCED;
oldPrevious :IDoublyLinkedElement := IS_NOT_REFERENCED;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
THIS^.unlinkElement(element, oldNext => oldNext, oldPrevious => oldPrevious);
IF (THIS^.isObjectValid(newPrevious)) THEN
newNext := newPrevious.next;
END_IF
THIS^.linkElement(newPrevious, element, newNext);
next := oldPrevious;
|
GET PROPERTY isEmpty :BOOL |
|
isEmpty := THIS^.isObjectNull(THIS^.head);
|
METHOD isListContainsObject :BOOL
VAR_INPUT
object :IObject;
END_VAR
|
isListContainsObject := THIS^.isObjectValid(THIS^.findObject(object));
|
METHOD PROTECTED isSortFinished :BOOL
VAR_INPUT
element :IDoublyLinkedElement;
END_VAR
VAR_OUTPUT
retVal :ExecutionState;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
isSortFinished := FALSE;
IF (THIS^.isObjectNull(element)) THEN
isSortFinished := TRUE;
ELSIF (THIS^.isObjectNull(element.next)) THEN
THIS^.last := element;
isSortFinished := TRUE;
END_IF
retVal := SEL(isSortFinished, ExecutionState.BUSY, ExecutionState.SUCCESS);
|
METHOD iterate :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
VAR_OUTPUT
object :IObject;
END_VAR
VAR_INST
currentElement :IDoublyLinkedElement;
actualHead :IDoublyLinkedElement;
actualLast :IDoublyLinkedElement;
startSize :__XWORD;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
IF (NOT execute) THEN
currentElement := THIS^.head;
THIS^.wasListChanged(FALSE, actualHead, actualLast, startSize);
object := IS_NOT_REFERENCED;
iterate := ExecutionState.IDLE;
ELSIF (THIS^.wasListChanged(TRUE, actualHead, actualLast, startSize)) THEN
iterate := ExecutionState.ABORTED;
object := IS_NOT_REFERENCED;
ELSIF (THIS^.isObjectValid(currentElement)) THEN
object := currentElement.object;
iterate := ExecutionState.BUSY;
currentElement := currentElement.next;
ELSE
iterate := ExecutionState.SUCCESS;
object := IS_NOT_REFERENCED;
END_IF
|
METHOD PROTECTED linkElement
VAR_INPUT
previous :IDoublyLinkedElement := IS_NOT_REFERENCED;
element :IDoublyLinkedElement := IS_NOT_REFERENCED;
next :IDoublyLinkedElement := IS_NOT_REFERENCED;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
RETURN(THIS^.isObjectNull(element));
element.previous := previous;
element.next := next;
IF (THIS^.isObjectValid(previous)) THEN
previous.next := element;
END_IF
IF (THIS^.isObjectValid(next)) THEN
next.previous := element;
END_IF
|
METHOD PROTECTED mySort :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
VAR_INST
element :IDoublyLinkedElement;
actualHead :IDoublyLinkedElement;
actualLast :IDoublyLinkedElement;
startSize :__XWORD;
END_VAR
VAR
cycle :UINT := 0;
next :IDoublyLinkedElement;
previous :IDoublyLinkedElement;
END_VAR
VAR CONSTANT
MAX_CYCLES :UINT := 10;
CYCLE_INCREMENT :UINT := 1;
END_VAR
|
IF (NOT execute) THEN
mySort := ExecutionState.IDLE;
element := THIS^.head;
THIS^.wasListChanged(FALSE, actualHead, actualLast, startSize);
RETURN;
ELSIF (THIS^.wasListChanged(TRUE, actualHead, actualLast, startSize)) THEN
mySort := ExecutionState.ABORTED;
END_IF
WHILE ((NOT THIS^.isSortFinished(element, retVal => mySort)) AND (cycle < MAX_CYCLES)) DO
next := element.next;
previous := next.previous;
WHILE (THIS^.isObjectValid(previous)) DO
IF (THIS^.compare(next, previous) >= ComparationResult.SMALLER) THEN
IF (NOT next.previous.isEqual(previous)) THEN
THIS^.insertBehind(element := next, newPrevious := previous, next => next);
EXIT;
END_IF
ELSIF (THIS^.isObjectNull(previous.previous)) THEN
THIS^.head := next;
THIS^.insertBefore(element := next, newNext := previous, next => next);
EXIT;
END_IF
previous := previous.previous;
END_WHILE
element := next;
cycle := cycle+CYCLE_INCREMENT;
END_WHILE
THIS^.wasListChanged(FALSE, actualHead, actualLast, startSize);
|
GET PROPERTY pop :IObject |
VAR
last :IDoublyLinkedElement;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
pop := IS_NOT_REFERENCED;
IF (THIS^.isObjectValid(THIS^.last)) THEN
pop := THIS^.last.object;
last := THIS^.last;
THIS^.last := last.previous;
THIS^.elementFactory.destructDoublyLinkedElement(
element := last,
unlinkElement := TRUE
);
IF (THIS^.isObjectNull(THIS^.last)) THEN
THIS^.head := IS_NOT_REFERENCED;
END_IF;
THIS^.decrementSize();
END_IF
|
METHOD prepend
VAR_INPUT
object :IObject;
END_VAR
VAR
new :IDoublyLinkedElement;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
IF (THIS^.isObjectValid(object)) THEN
new := THIS^.elementFactory.getNewDoublyLinkedElement(
object := object,
previousElement := IS_NOT_REFERENCED,
nextElement := THIS^.head,
linkElements := TRUE
);
IF (THIS^.isObjectValid(new)) THEN
THIS^.head := new;
IF (THIS^.isObjectNull(THIS^.last)) THEN
THIS^.last := new;
END_IF
END_IF
THIS^.incrementSize();
END_IF
|
METHOD remove
VAR_INPUT
object :IObject;
END_VAR
VAR
element :IDoublyLinkedElement;
END_VAR
|
element := THIS^.findObject(object);
IF (THIS^.isObjectValid(element)) THEN
THIS^.elementFactory.destructDoublyLinkedElement(
element := element,
unlinkElement := TRUE
);
END_IF
|
METHOD setComperator :IList
VAR_INPUT
comparator :IComparator;
END_VAR
|
setComperator := THIS^;
THIS^.comparator := comparator;
|
METHOD setSorter :IList
VAR_INPUT
sorter :IListSorter;
END_VAR
|
setSorter := THIS^;
THIS^.sorter := sorter;
|
GET PROPERTY size :__XWORD |
|
size := THIS^.mySize;
|
METHOD sort :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
|
IF (THIS^.isObjectValid(THIS^.sorter)) THEN
sort := THIS^.xenoSort(execute);
ELSE
sort := THIS^.mySort(execute);
END_IF
|
METHOD PROTECTED unlinkElement
VAR_INPUT
element :IDoublyLinkedElement;
END_VAR
VAR_OUTPUT
oldNext :IDoublyLinkedElement := IS_NOT_REFERENCED;
oldPrevious :IDoublyLinkedElement := IS_NOT_REFERENCED;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
RETURN (THIS^.isObjectNull(element));
oldNext := element.next;
oldPrevious := element.previous;
IF (THIS^.isObjectValid(oldPrevious)) THEN
oldPrevious.next := oldNext;
END_IF
IF (THIS^.isObjectValid(oldNext)) THEN
oldNext.previous := oldPrevious;
END_IF
|
METHOD PROTECTED wasListChanged :BOOL
VAR_INPUT
execute :BOOL;
END_VAR
VAR_IN_OUT
actualHead :IDoublyLinkedElement;
actualLast :IDoublyLinkedElement;
startSize :__XWORD;
END_VAR
|
wasListChanged := TRUE;
IF (NOT execute) THEN
actualHead := THIS^.head;
actualLast := THIS^.last;
startSize := THIS^.size;
wasListChanged := FALSE;
ELSIF (THIS^.isObjectNull(actualHead) <> THIS^.isObjectNull(THIS^.head)) THEN;
ELSIF (THIS^.isObjectNull(actualLast) <> THIS^.isObjectNull(THIS^.last)) THEN;
ELSIF (startSize <> THIS^.size) THEN;
ELSE
wasListChanged := FALSE;
IF (THIS^.isObjectValid(THIS^.head)) THEN
wasListChanged := (NOT THIS^.head.isEqual(actualHead));
END_IF
IF (THIS^.isObjectValid(THIS^.head) AND (NOT wasListChanged)) THEN
wasListChanged := (NOT THIS^.last.isEqual(actualLast));
END_IF
END_IF
|
METHOD PROTECTED xenoSort :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
|
IF (NOT execute) THEN
THIS^.sorter.head := THIS^.head;
THIS^.sorter.last := THIS^.last;
xenoSort := THIS^.sorter.sort(execute);
ELSE
xenoSort := THIS^.sorter.sort(execute);
THIS^.head := THIS^.sorter.head;
THIS^.last := THIS^.sorter.last;
END_IF
|
Synchronized Object List
Class SynchronizedObjectList {attribute 'enable_dynamic_creation'}
{attribute 'reflection'}
FUNCTION_BLOCK SynchronizedObjectList EXTENDS Object IMPLEMENTS IList
VAR
{attribute 'hide'}
lockObject :TC2_System.FB_IecCriticalSection;
END_VAR
|
GET PROPERTY PRIVATE listFactory :IObjectListFactory |
VAR_INST
factoryProvider :FactoryProvider(0,0,0,0,0);
factory :IObjectListFactory;
factoryLockObject :TC2_System.FB_IecCriticalSection;
END_VAR
|
factoryLockObject.Enter();
IF (THIS^.isObjectNull(factory)) THEN
factory := factoryProvider.getObjectListFactory();
END_IF
listFactory := factory;
factoryLockObject.Leave();
|
GET PROPERTY PRIVATE singleThreadList :IList |
VAR_INST
listLockObject :TC2_System.FB_IecCriticalSection;
listInstance :IList;
END_VAR
|
listLockObject.Enter();
IF (THIS^.isObjectNull(listInstance)) THEN
listInstance := THIS^.listFactory.getNewObjectList();
END_IF
singleThreadList := listInstance;
listLockObject.Leave();
|
GET PROPERTY className :ClassName |
|
className := 'SynchronizedObjectList';
|
METHOD append
VAR_INPUT
object :IObject;
END_VAR
|
THIS^.lockObject.Enter();
THIS^.singleThreadList.append(object);
THIS^.lockObject.Leave();
|
METHOD sort :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
|
THIS^.lockObject.Enter();
sort := THIS^.singleThreadList.sort(execute);
THIS^.lockObject.Leave();
|
METHOD setSorter :IList
VAR_INPUT
sorter :IListSorter;
END_VAR
|
setSorter := THIS^;
THIS^.lockObject.Enter();
THIS^.singleThreadList.setSorter(sorter);
THIS^.lockObject.Leave();
|
METHOD FB_exit :BOOL
VAR_INPUT
(* if TRUE, the exit method is called for exiting an instance that is copied afterwards (online change). *)
bInCopyCode :BOOL;
END_VAR
|
IF (THIS^.isObjectNull(THIS^.singleThreadList)) THEN;
ELSIF (THIS^.isObjectValid(THIS^.listFactory)) THEN
THIS^.listFactory.destructObjectList(THIS^.singleThreadList);
END_IF
|
Alarm Message Queue
Class AlarmMessageQueue {attribute 'enable_dynamic_creation'}
{attribute 'reflection'}
FUNCTION_BLOCK AlarmMessageQueue EXTENDS Object IMPLEMENTS IAlarmMessageQueue
|
GET PROPERTY PRIVATE listFactory :ISynchronizedObjectListFactory |
VAR_INST
factoryProvider :FactoryProvider(0,0,0,0,0);
factory :ISynchronizedObjectListFactory;
factoryLockObject :TC2_System.FB_IecCriticalSection;
END_VAR
|
factoryLockObject.Enter();
IF (THIS^.isObjectNull(factory)) THEN
factory := factoryProvider.getSynchronizedObjectListFactory();
END_IF
listFactory := factory;
factoryLockObject.Leave();
|
GET PROPERTY PRIVATE alarmList :IList |
VAR_INST
listLockObject :TC2_System.FB_IecCriticalSection;
listInstance :IList;
END_VAR
|
listLockObject.Enter();
IF (THIS^.isObjectNull(listInstance)) THEN
listInstance := THIS^.listFactory.getNewSynchronizedObjectList();
END_IF
alarmList := listInstance;
listLockObject.Leave();
|
GET PROPERTY PROTECTED isAlarmListValid :BOOL |
|
isAlarmListValid := (THIS^.isObjectValid(THIS^.alarmList));
|
METHOD PROTECTED toAlarmMessageDto :IAlarmMessageDto
VAR_INPUT
object :IObject;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
|
IF (NOT __QUERYINTERFACE(object, toAlarmMessageDto)) THEN
toAlarmMessageDto := IS_NOT_REFERENCED;
END_IF
|
GET PROPERTY dequeue :IAlarmMessageDto |
VAR CONSTANT
IS_NOT_REFERENCED :__XWORD := 0;
END_VAR
|
IF (THIS^.isAlarmListValid) THEN
dequeue := (THIS^.toAlarmMessageDto(THIS^.alarmList.dequeue));
ELSE
dequeue := IS_NOT_REFERENCED;
END_IF
|
METHOD append
VAR_INPUT
alarmMessage :IAlarmMessageDto;
END_VAR
|
IF (THIS^.isAlarmListValid) THEN
IF (NOT THIS^.alarmList.isListContainsObject(alarmMessage)) THEN
THIS^.alarmList.append(alarmMessage);
END_IF
END_IF
|
Alarm Message Service Subscriber List
Class AlarmMessageServiceSubscriberList {attribute 'enable_dynamic_creation'}
{attribute 'reflection'}
FUNCTION_BLOCK AlarmMessageServiceSubscriberList EXTENDS Object IMPLEMENTS IAlarmMessageServiceSubscriberList
|
GET PROPERTY PRIVATE listFactory :ISynchronizedObjectListFactory |
VAR_INST
factoryProvider :FactoryProvider(0,0,0,0,0);
factory :ISynchronizedObjectListFactory;
factoryLockObject :TC2_System.FB_IecCriticalSection;
END_VAR
|
factoryLockObject.Enter();
IF (THIS^.isObjectNull(factory)) THEN
factory := factoryProvider.getSynchronizedObjectListFactory();
END_IF
listFactory := factory;
factoryLockObject.Leave();
|
GET PROPERTY PRIVATE subscriberList :IList |
VAR_INST
listLockObject :TC2_System.FB_IecCriticalSection;
listInstance :IList;
END_VAR
|
listLockObject.Enter();
IF (THIS^.isObjectNull(listInstance)) THEN
listInstance := THIS^.listFactory.getNewSynchronizedObjectList();
END_IF
subscriberList := listInstance;
listLockObject.Leave();
|
GET PROPERTY PROTECTED isSubscriberListValid :BOOL |
|
isSubscriberListValid := (THIS^.isObjectValid(THIS^.subscriberList));
|
METHOD setComperator :IAlarmMessageServiceSubscriberList
VAR_INPUT
comparator :IComparator;
END_VAR
|
setComperator := THIS^;
IF (THIS^.isSubscriberListValid) THEN
THIS^.subscriberList.setComperator(comparator);
END_IF
|
METHOD iterateSubscriber :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
VAR_OUTPUT
subscriber :IAlarmMessageService;
END_VAR
VAR CONSTANT
IS_NOT_REFERENCED :__UXINT := 0;
END_VAR
VAR
object : IObject;
END_VAR
|
IF (THIS^.isSubscriberListValid) THEN
iterateSubscriber := (THIS^.subscriberList.iterate(execute, object => object));
IF (NOT __QUERYINTERFACE(object, subscriber)) THEN
subscriber := IS_NOT_REFERENCED;
iterateSubscriber := ExecutionState.ERROR;
END_IF
ELSE
subscriber := IS_NOT_REFERENCED;
iterateSubscriber := ExecutionState.ABORTED;
END_IF
|
METHOD iterate :ExecutionState
VAR_INPUT
execute :BOOL;
END_VAR
VAR_OUTPUT
object :IObject;
END_VAR
VAR
subscriber :IAlarmMessageService;
END_VAR
|
iterate := THIS^.iterateSubscriber(execute, subscriber => subscriber);
object := subscriber;
|