Inhalte

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