Mornella/Mornella_Mobile/Observer.h
#pragma once
#include "Common.h"
#include "Conf.h"
#define EVENT_NOT_INTERESTING (INT)-1
typedef struct _Listeners {
UINT uTid;
BOOL bProcessed;
BOOL bDispatched;
} Listeners, *pListeners;
// Classe observer per il dispatch dei messaggi dalla coda IPC, e' singleton.
class Observer {
private:
static Observer *Instance;
static volatile LONG lLock;
HANDLE hQueueRead, hQueueWrite, hObserverMutex;
INT m_iQueueCommand;
BOOL bRefresh;
list<Listeners> *pRegistered;
MSGQUEUEOPTIONS qRead, qWrite;
BYTE *pQueue;
DWORD dwQueueBuf;
DWORD dwMsgLen;
IpcMsg *m_pIpcMsg;
private:
/**
* Legge dalla coda in attesa in attesa di un messaggio, il timeout e' di un secondo. Se il messaggio
* viene letto dwMsgLen contiene la sua lunghezza completa, altrimenti e' 0. In caso di errore o di
* messaggio non trovato, la funzione ritorna FALSE. Questa funzione effettua la lettura solo se
* bRefresh e' impostato a TRUE. Questo flag viene impostato dalla Dispatch() quando tutti i listener
* hanno markato il messaggio.
*/
BOOL ReadQueue();
/**
* Invia un messaggio sulla coda grande 4 byte + sizeof(IpcMsg), il messaggio e' rappresentato da
* m_iQueueCommand che viene impostato dalla MarkMessage(). Sender e Receiver sono impostati ai valori
* contenuti nel messaggio letto. La funzione torna TRUE in caso di scrittura avvenuta con successo,
* FALSE altrimenti.
*/
BOOL WriteQueue();
/**
* Imposta i flag bProcessed e bDispatched a FALSE per tutti i listener registrati. Viene chiamata
* prima di effettuare un nuovo ciclo di read della coda. Torna TRUE in caso di successo, FALSE
* altrimenti.
*/
BOOL ResetList();
/**
* Se tutti i listener hanno markato il messaggio questa funzione scrive il comando nella coda,
* resetta la lista ed imposta bRefresh a TRUE. Altrimenti ritorna TRUE se la funzione va a buon
* fine, FALSE altrimenti.
*/
BOOL Dispatch();
~Observer();
/**
* Apre la coda creata da Task(), crea il mutex e alloca il buffer pQueue utilizzato
* per il processing dei messaggi. La dimensione di pQueue e' fissata ed e' definita dalla
* dimensione massima stabilita da Task() all'atto della creazione della coda.
*/
Observer();
public:
/**
* Observer e' una classe singleton
*/
static Observer* self();
/**
* Istanzia la lista pRegistered se non esiste ed aggiunge il thread il cui TID e' definito da
* uTid alla lista dei listeners. Torna TRUE in caso di successo, FALSE altrimenti.
*/
BOOL Register(UINT uTid);
/**
* Rimuove un Listener dalla coda e la ridimensiona, torna FALSE solo se la lista non esiste.
*/
BOOL UnRegister(UINT uTid);
/**
* Torna un puntatore al messaggio ricevuto se c'e', NULL altrimenti.
*/
const BYTE* GetMessage();
/**
* Ogni listener DEVE chiamare questa funzione dopo la GetMessage(), uTid rappresenta il TID del
* listener chiamante, uCommand il comando da inviare alla coda e bProcessed lo stato del messaggio.
* Se bProcessed e' TRUE significa che il listener ha processato ed utilizzato il messaggio, quindi
* la classe valorizza m_iQueueCommand prendendolo da uCommand e invia il messaggio alla coda. Altrimenti
* uCommand viene ignorato. La WriteQueue() viene chiamata solo dopo che TUTTI i listener hanno
* markato il messaggio come processato/non-processato.
*/
BOOL MarkMessage(UINT uTid, UINT uCommand, BOOL bProcessed);
};