Alarm Message Service: Alarm Message Distributor
Table of Contents
Introduction
The alarm message distributor is the operational alarm message service. A lot of work for this small class. ¯\(ツ)/¯
Interface
Interface IAlarmMessageDistributor INTERFACE IAlarmMessageDistributor EXTENDS IAlarmMessageService, IObject, IRunable
|
METHOD subscribe
VAR_INPUT
subscriber :IAlarmMessageService;
END_VAR
|
METHOD unsubscribe
VAR_INPUT
subscriber :IAlarmMessageService;
END_VAR
|
Implementation
Class AlarmMessageDistributor {attribute 'reflection'}
FUNCTION_BLOCK AlarmMessageDistributor EXTENDS Object IMPLEMENTS IAlarmMessageDistributor
|
GET PROPERTY PRIVATE alarmQueueFactory :IAlarmMessageQueueFactory |
VAR_INST
factoryProvider :FactoryProvider(0,0,0,0,0);
factory :IAlarmMessageQueueFactory;
factoryLockObject :TC2_System.FB_IecCriticalSection;
END_VAR
|
factoryLockObject.Enter();
IF (THIS^.isObjectNull(factory)) THEN
factory := factoryProvider.getAlarmMessageQueueFactory();
END_IF
alarmQueueFactory := factory;
factoryLockObject.Leave();
|
GET PROPERTY PRIVATE subscriberFactory :IAlarmMessageServiceSubscriberListFactory |
VAR_INST
factoryProvider :FactoryProvider(0,0,0,0,0);
factory :IAlarmMessageServiceSubscriberListFactory;
factoryLockObject :TC2_System.FB_IecCriticalSection;
END_VAR
|
factoryLockObject.Enter();
IF (THIS^.isObjectNull(factory)) THEN
factory := factoryProvider.getAlarmMessageServiceSubscriberListFactory();
END_IF
subscriberFactory := factory;
factoryLockObject.Leave();
|
GET PROPERTY PRIVATE subscriber :IAlarmMessageServiceSubscriberList |
VAR_INST
listLockObject :TC2_System.FB_IecCriticalSection;
listInstance :IAlarmMessageServiceSubscriberList;
END_VAR
|
listLockObject.Enter();
IF (THIS^.isObjectNull(listInstance)) THEN
listInstance := THIS^.subscriberFactory.getNewAlarmMessageServiceSubscriberList();
END_IF
subscriber := listInstance;
listLockObject.Leave();
|
PROPERTY PRIVATE clearQueue :IAlarmMessageQueue |
VAR_INST
listLockObject :TC2_System.FB_IecCriticalSection;
listInstance :IAlarmMessageQueue;
END_VAR
|
listLockObject.Enter();
IF (THIS^.isObjectNull(listInstance)) THEN
listInstance := THIS^.alarmQueueFactory.getNewAlarmMessageQueue();
END_IF
clearQueue := listInstance;
listLockObject.Leave();
|
GET PROPERTY PRIVATE handleQueue :IAlarmMessageQueue |
VAR_INST
listLockObject :TC2_System.FB_IecCriticalSection;
listInstance :IAlarmMessageQueue;
END_VAR
|
listLockObject.Enter();
IF (THIS^.isObjectNull(listInstance)) THEN
listInstance := THIS^.alarmQueueFactory.getNewAlarmMessageQueue();
END_IF
handleQueue := listInstance;
listLockObject.Leave();
|
GET PROPERTY PRIVATE isClearQueueValid :BOOL |
|
isClearQueueValid := (THIS^.isObjectValid(THIS^.clearQueue));
|
GET PROPERTY PRIVATE isHandleQueueValid :BOOL |
|
isHandleQueueValid := (THIS^.isObjectValid(THIS^.handleQueue));
|
GET PROPERTY PRIVATE isSubscriberListValid :BOOL |
|
isSubscriberListValid := (THIS^.isObjectValid(THIS^.subscriber));
|
METHOD subscribe
VAR_INPUT
subscriber :IAlarmMessageService;
END_VAR
|
IF (THIS^.isSubscriberListValid) THEN
THIS^.subscriber.append(subscriber);
END_IF
|
METHOD unsubscribe
VAR_INPUT
subscriber :IAlarmMessageService;
END_VAR
|
IF (THIS^.isSubscriberListValid) THEN
THIS^.subscriber.remove(subscriber);
END_IF
|
METHOD PROTECTED distributeHandle
VAR
alarmMessage :IAlarmMessageDto;
subscriber :IAlarmMessageService;
END_VAR
|
WHILE (THIS^.handleQueue.hasElement) DO
alarmMessage := THIS^.handleQueue.dequeue;
IF (THIS^.isObjectValid(alarmMessage) AND THIS^.isSubscriberListValid) THEN
THIS^.subscriber.iterateSubscriber(execute := FALSE, subscriber => subscriber);
WHILE (THIS^.subscriber.iterateSubscriber(execute := TRUE, subscriber => subscriber) = ExecutionState.BUSY) DO
subscriber.handle(alarmMessage);
END_WHILE
END_IF
END_WHILE
|
METHOD PROTECTED distributeClear
VAR
alarmMessage :IAlarmMessageDto;
subscriber :IAlarmMessageService;
END_VAR
|
WHILE (THIS^.clearQueue.hasElement) DO
alarmMessage := THIS^.clearQueue.dequeue;
IF (THIS^.isObjectValid(alarmMessage) AND THIS^.isSubscriberListValid) THEN
THIS^.subscriber.iterateSubscriber(execute := FALSE, subscriber => subscriber);
WHILE (THIS^.subscriber.iterateSubscriber(execute := TRUE, subscriber => subscriber) = ExecutionState.BUSY) DO
subscriber.clear(alarmMessage);
END_WHILE
END_IF
END_WHILE
|
METHOD handle
VAR_INPUT
alarmMessage :IAlarmMessageDto;
END_VAR
|
RETURN(THIS^.isObjectNull(alarmMessage));
RETURN(NOT THIS^.isHandleQueueValid);
IF (alarmMessage.state > HmiAlarmState.INACTIVE) THEN
IF (THIS^.isClearQueueValid) THEN
THIS^.clearQueue.remove(alarmMessage);
END_IF
RETURN;
ELSIF (alarmMessage.stopCategory >= AlarmStopCategory.STOP_IMMEDIATLY) THEN
THIS^.handleQueue.prepend(alarmMessage);
ELSE
THIS^.handleQueue.append(alarmMessage);
END_IF
IF (alarmMessage.state < HmiAlarmState.REGISTRED) THEN
alarmMessage.state := HmiAlarmState.REGISTRED;
END_IF
|
METHOD clear
VAR_INPUT
alarmMessage :IAlarmMessageDto;
END_VAR
|
RETURN(THIS^.isObjectNull(alarmMessage));
RETURN(NOT THIS^.isClearQueueValid);
RETURN(alarmMessage.state = HmiAlarmState.INACTIVE);
IF (alarmMessage.state = HmiAlarmState.REGISTRED) THEN
IF (THIS^.isHandleQueueValid) THEN
THIS^.handleQueue.remove(alarmMessage);
END_IF
ELSE
THIS^.clearQueue.append(alarmMessage);
END_IF
|
METHOD PROTECTED runClear
|
RETURN(NOT THIS^.isClearQueueValid);
RETURN(THIS^.clearQueue.isEmpty);
THIS^.distributeClear();
|
METHOD PROTECTED runHandle
|
RETURN(NOT THIS^.ishandleQueueValid);
RETURN(THIS^.handleQueue.isEmpty);
THIS^.distributeHandle();
|
METHOD run
|
THIS^.runHandle();
THIS^.runClear();
|
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
|
(*run call is just to distribute all pending alarms, before destruct lists*)
THIS^.run();
IF (THIS^.isObjectValid(THIS^.alarmQueueFactory)) THEN
THIS^.alarmQueueFactory.destructAlarmMessageQueue(THIS^.clearQueue);
THIS^.alarmQueueFactory.destructAlarmMessageQueue(THIS^.handleQueue);
END_IF
IF (THIS^.isObjectValid(THIS^.subscriberFactory)) THEN
THIS^.subscriberFactory.destructAlramMessageServiceSubscriberList(THIS^.subscriber);
END_IF
|