Dapfor home  

CDelegate Class Reference

This class organizes aggregation relations between data objects. More...

#include <Dapfor/Common/Delegate.h>

Inheritance diagram for CDelegate:

CDataObject

List of all members.

Public Member Functions

 CDelegate (CDataObject *aggregate, bool owner)
 Constructor.
virtual ~CDelegate ()
 Destructor.
virtual const Field GetField (FID fid) const
 Gets a field by its identifier.
virtual void GetAllFields (Fields &fields) const
 Gets all the fields available in CDelegate and the aggregated object.
virtual void GetAllFids (Fids &fids) const
 Gets all the identifiers available in CDelegate and the aggregated object.
virtual CDataObjectSetAggregate (CDataObject *aggregate)
 Sets a new aggregated object.
virtual CDataObjectGetAggregate ()
 Gets an aggregated object.
virtual const CDataObjectGetAggregate () const
 Gets an aggregated object.


Detailed Description

This class organizes aggregation relations between data objects.

CDelegate makes it possible to organize aggregation relations between data objects. In this case, all events will be forwarded from the aggregated object in behalf of the delegate. It is convenient, if there are several various classes, representing the functionality, which is entirely different. If the delegate is inserted into the grid, this delegate will stand as proxy between the grid and the aggregated object. In case of inheritance from the delegate, identification of their own tables of functions in descendant the class is possible. When the delegate object is demanded for the data, search of functions is realized firstly in the inheritance path and then in the aggregate object. When a new aggregated object is set, subscription for sending of the events from the object takes place. In case of event receiving, the event is transferred to the subscribers on behalf of the delegate object. Therefore the delegate object and the aggregated object appear from outward viewpoint as a single whole.

Example
//The C++ objects may have some relations. They can have pointers to other objects etc.
//For example, some share can be quoted on many markets or an autor can write some books.
//Moreover, they may implement Dapfor::Common::CDataObject interface and it will be nice
//to reuse them. The classes that derive from the Dapfor::Common::CDelegate 
//have the same behaviour that the classic data objects. But in addition they
//have the fields, provided by their aggregate. 
//In other words, this kind of objects externally is visible as it implements 
//a mapping of many classes.
//If we have an instrument which is related to some market and this instrument
//is inserted into the grid, than the grid can show the state of the instrument 
//and the market at the same time in neighbouring columns.



//File Market.h

// This class represents a market with its own state, which can be either connected or disconnected. 
// The state is expressed by enumeration CMarket::MarketState. The class has two functions 
// that return the market name and its state. In a real application the market state may be changed.
class CMarket : public Dapfor::Common::CDataObject
{
public:
    //It is useful to use enumerations instead of long-type numeric values...
    //The grid can use the same identifiers to show the values returned by the functions of this class.
    enum
    {
        FidMarketName = 100,
        FidMarketState,
    };

    enum MarketState
    {
        Connected,
        Disconnected,
    };


public:
    CMarket(const std::string& name, MarketState state);
    virtual ~CMarket();

    //Get- methods
    std::string GetMarketName() const;
    long        GetMarketState() const;

private:
    MarketState  m_MarketState;
    std::string  m_Name;

    //Declaration of the map, that contains a list of the functions, that can be called by their identifiers.
    DF_DECLARE_FIELD_MAP();
};




//File Market.cpp

// This declaration is useful to present numeric value (enum) as text string in the grid
Dapfor::Common::CLongEnumFormat::Item states[] =
{
    {CMarket::Connected,    "Connected"},
    {CMarket::Disconnected, "Disconnected"},
};

//FieldMap declaration
DF_BEGIN_FIELD_MAP(CMarket)
    DF_STL_STRING_ID(FidMarketName,  "Market",  &CMarket::GetMarketName,  0, 0)
    DF_LONG_ID      (FidMarketState, "State",   &CMarket::GetMarketState, 0, DF_ENUM_FORMAT(states))
DF_END_FIELD_MAP()

CMarket::CMarket(const std::string& name, MarketState state) : m_Name(name),
                                                               m_MarketState(state)
{
}

CMarket::~CMarket()
{
    // Don't forget to send a notification. 
    // The destructor of the base class does the same, but when it is called a table of virtual functions 
    // is no more valid for this class. And if there is an access from another thread to this object 
    // while its destruction we can catch an exception: pure virtual function call. 

    // So, to safe programming we advise to call NotifyDelete() method in each destructor.
    NotifyDelete();
}


std::string CMarket::GetMarketName() const
{
    return m_Name;
}

long CMarket::GetMarketState() const
{
    return m_MarketState;
}



//File Instrument.h

// The instrument presented on the market. An object of this class can be inserted into the grid. 
// The market is used as an aggregated object. This means, that the grid can get the market name and state through 
// an instrument object using the field identifiers CMarket::FidMarketName and CMarket::FidMarketState. 
// If the market state is changed the grid receives a notification via an instrument object and it can update and highlight a text,
// automatically sort or filter corresponded lines. 
// Note, that CMarket and CInstrument classes use different numeric identifiers 
// (The first starts from 100 and the second has id = 200).
class CInstrument : public Dapfor::Common::CDelegate
{
public:
    //It is useful to use enumerations instead of long-type numeric values...
    //The grid can use the same identifiers to show the values returned by the functions of this class.
    enum
    {
        FidInstrumentName = 200,
    };

public:
    CInstrument(const std::string& name, CMarket* market);
    virtual ~CInstrument();

    //Get- methods
    std::string GetInstrumentName() const;

private:
    std::string  m_Name;

    //Declaration of the map, that contains a list of the functions, that can be called by their identifiers.
    DF_DECLARE_FIELD_MAP();
};



//File Instrument.cpp

DF_BEGIN_FIELD_MAP(CInstrument)
    DF_STL_STRING_ID(FidInstrumentName,  "Instrument",  &CInstrument::GetInstrumentName,  0, 0)
DF_END_FIELD_MAP()

CInstrument::CInstrument(const std::string& name, CMarket* market) 
    : Dapfor::Common::CDelegate(market, false)
    , m_Name(name)
{
}

CInstrument::~CInstrument()
{
    // To safe programming we advise to call NotifyDelete() method in each destructor.
    NotifyDelete();
}


std::string CInstrument::GetInstrumentName() const
{
    return m_Name;
}


//Using sample

    //Grid initialization
    ...

    Dapfor::GUI::CHeader* header = new Dapfor::GUI::CHeader();
    header->Add(new Dapfor::GUI::CColumn(CMarket::FidMarketName,         "Market",     100));
    header->Add(new Dapfor::GUI::CColumn(CMarket::FidMarketState,        "State",      100));
    header->Add(new Dapfor::GUI::CColumn(CInstrument::FidInstrumentName, "Instrument", 100));
    m_Grid.SetHeader(header);
        
    ...

    //Markets & instruments initialization
    ...

    CMarket* market = new CMarket("Bloomberg", CMarket::Connected);
    CInstrument* instrument = new CInstrument("Bond", market);

    //Add an instrument to the grid.
    
    m_Grid.Add(instrument);


    // The grid will show three columns with the market name, connection state 
    // and instrument name. 
    //
    // That is all. No more code to sorting, highlighting, updating, filtering 
    // and other routines for a modified object. The grid does it itself. 


Constructor & Destructor Documentation

CDelegate ( CDataObject aggregate,
bool  owner 
)

Constructor.

Parameters:
[in] aggregate Aggregated object, in which the field search takes place, in case the delegate does not contain the data fields itself.
[in] owner Value, indicating that the delegate is the owner of the aggregated object. In case this parameter is set in true, the destructor will delete the aggregated object.

~CDelegate (  )  [virtual]

Destructor.

Unsubscribes from the aggregated object, and in case of ownership, the aggredated object will be destroyed.

Thread safety:
The function is thread safe.


Member Function Documentation

const CDataObject::Field GetField ( FID  fid  )  const [virtual]

Gets a field by its identifier.

It searches a data object field by its integer identifier. Firstly the search is realized in the inheritance chain. If the field is not found, the search is performed in the aggregated object.

Parameters:
[in] fid Field identifier.
Returns:
Current aggregated object.
Thread safety
The function is safe for multi-threaded callings for data search both inside the object and in the aggregated object. Data search in the aggregated object is implemented without taking synchronization objects like critical section or mutex. However, there is a potential risk in case of deletion of the aggregated object at the same time when another thread retrieves data from the aggregated object.

Reimplemented from CDataObject.

void GetAllFields ( Fields fields  )  const [virtual]

Gets all the fields available in CDelegate and the aggregated object.

Gets all the fields, which are available in all the classes located in the hierarchy chain and in the aggregated object.

Parameters:
[in,out] fields Contained to be filled.
Thread safety:
The function is thread safe.

void GetAllFids ( Fids fids  )  const [virtual]

Gets all the identifiers available in CDelegate and the aggregated object.

Gets all the field identifiers, which are available in all the classes located in the hierarchy chain and in the aggregated object.

Parameters:
[in,out] fids Contained to be filled.
Thread safety:
The function is thread safe.

CDataObject * SetAggregate ( CDataObject aggregate  )  [virtual]

Sets a new aggregated object.

Parameters:
[in] aggregate A new aggregated object.
Returns:
Previous aggregated object.
Thread safety:
The function is thread safe.

CDataObject * GetAggregate (  )  [virtual]

Gets an aggregated object.

Returns:
Current aggregated object.
Thread safety:
The function is thread safe.

const CDataObject * GetAggregate (  )  const [virtual]

Gets an aggregated object.

Returns:
Current aggregated object.
Thread safety:
The function is thread safe.


Copyright Dapfor 2007-2009
Generated on Sat Jan 30 15:01:24 2010 for MFCGrid by doxygen 1.5.5