How to build an "event collector/broadcaster"?


2007-12-20 06:01:56 PM
cppbuilder47
This is a part of code of a class that "broadcast" an event to all component
that "registers" for it:
(the "Interface" part of the class name is not referred to a real class
Interface).
.H File
#ifndef TQuoteInterfaceH
#define TQuoteInterfaceH
#include <SysUtils.hpp>
#include <Classes.hpp>
#include "TQuoteList.h"
//---------------------------------------------------------------------------
typedef struct {
TObject* ptrUserObj;
pQuote ptrQuoteUsed;
TNotifyEvent evQuoteUpdated;
eEvNotifyStatus evStatus;
} QuoteUserType;
//---------------------------------------------------------------------------
//##############################################################################
typedef QuoteUserType tItem; // Tipo di Elemento dell'array
typedef QuoteUserType* pItem; // Puntatore all'Elemento dell'array.
//##############################################################################
class TDynamicArray : public TObject
{
private:
//##############################################################################
bool ItemIsEmpty (pItem sItem) {return sItem->evQuoteUpdated==NULL;};
bool ItemIsEqualTo (pItem sItem1, pItem sItem2) {
return (
sItem1->ptrUserObj == sItem2->ptrUserObj &&
sItem1->evQuoteUpdated == sItem2->evQuoteUpdated
);
};
//##############################################################################
pItem fBasePointer;
int fCapacity, fCount, fDefAlloc, fUserSize;
pItem __fastcall GetItem(int Index);
void __fastcall SetItem(int Index, pItem srcItem);
void __fastcall SetSize(int sNewSize);
public:
__fastcall TDynamicArray ();
__fastcall TDynamicArray (int initAlloc, int sDefAlloc = 4);
__fastcall ~TDynamicArray ();
void __fastcall Clear (bool sReAlloc=true);
void __fastcall Pack ();
void __fastcall Delete (int Index);
void __fastcall Add (pItem NewItem, bool ForcePack=true);
int __fastcall IndexOf (pItem SearchItem);
__property pItem Items[int index] = {read=GetItem, write=SetItem };
__property int Count = {read=fCount };
__property int Capacity = {read=fCapacity, write=SetSize };
};
//---------------------------------------------------------------------------
class PACKAGE TQuoteInterface : public TComponent
{
private:
TNotifyEvent evQuoteUpdated;
void __fastcall BroadcastUpdate(TObject *Sender);
TQuoteList* ListaQuote; // Elenco dei formati
TDynamicArray* ListaUsers; // List of classes that needs an evQuoteUpdated
event.
...
protected:
...
public:
...
void __fastcall RegisterEvent (TNotifyEvent event, TObject* Subscriber);
void __fastcall UnregisterEvent (TNotifyEvent event, TObject* Subscriber);
__published:
...
};
typedef TQuoteInterface* pQI;
//---------------------------------------------------------------------------
#endif
//##############################################################################
.CPP file:
//------------------------------------------------------------------------------
__fastcall TQuoteInterface::TQuoteInterface(TComponent*
Owner):TComponent(Owner)
{
ListaUsers = new TDynamicArray();
}
//------------------------------------------------------------------------------
void __fastcall TQuoteInterface::RegisterEvent(TNotifyEvent event, TObject*
Subscriber)
{
QuoteUserType tmpq;
tmpq.ptrUserObj = Subscriber;
tmpq.evQuoteUpdated = event;
ListaUsers->Add(&tmpq);
}
//------------------------------------------------------------------------------
void __fastcall TQuoteInterface::UnregisterEvent(TNotifyEvent event,
TObject* Subscriber)
{
int ind;
QuoteUserType tmpq;
tmpq.ptrUserObj = Subscriber;
tmpq.evQuoteUpdated = event;
ind = ListaUsers->IndexOf(&tmpq);
if(ind>=0) ListaUsers->Delete(ind);
}
//------------------------------------------------------------------------------
void __fastcall TQuoteInterface::BroadcastUpdate(TObject *Sender)
{
for (int i=0; i<ListaUsers->Count; i++) {
if (ListaUsers->Items[i]->evQuoteUpdated != NULL)
ListaUsers->Items[i]->evQuoteUpdated(Sender);
}
}
//------------------------------------------------------------------------------
This is the "best" way i've found to keep things clean and easy readable (as
there's other "programmers" in this project) in a form.
In the main Form i only need to "attach" various Components to my
"TQuoteInterface" in the FormCreate event, and then all the code
related to a QuoteUpdate event resides only in that components.
Without this "broadcasting method", i will have a function in the form that
manages the QuoteUpdate event, and then have to pass the data to all the
Components that need them.
Now, the Question:
is this the best method to do that?
If not, what are the other ways to do?
I hope you can understand me.