MFC Grid manual

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 are forwarded from the aggregated object on the behalf of the delegate. It is convenient, if there are several various classes representing entirely different functionalities. If the delegate is inserted into the grid, this delegate stands as a 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 required for data, search of functions is performed 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. When an event is received, it is transferred to the subscribers on the behalf of the delegate object. Therefore, the delegate object and the aggregated object appear as a single entity.

Example
//C++ objects can have various relations, they can have pointers to other objects etc.
//It is similar to stocks quoted on various markets or an author writing several books.
//Moreover, they can implement Dapfor::Common::CDataObject interface and
//be reused. Classes derived from the Dapfor::Common::CDelegate 
//have the same behavior as classic data objects. However, they also
//have fields provided by their aggregate. 
//In other words, this kind of objects is visible externally as it implements 
//mapping of many classes.
//If we have a market instrument and this instrument
//is inserted into the grid, the grid can show the state of the instrument 
//and the market at the same time in adjacent columns.



//File Market.h

// This class represents a market with its own state that can be either connected or disconnected. 
// State is expressed by enumeration CMarket::MarketState. The class has two functions 
// that return the market name and its state. In actual application market state can be changed.
class CMarket : public Dapfor::Common::CDataObject
{
public:
    //It is better to use enumerations instead of long numeric values...
    //The grid can use the same identifiers to display values returned by 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 map that contains the list of functions that can be called by their identifiers.
    DF_DECLARE_FIELD_MAP();
};




//File Market.cpp

// This declaration is useful to display 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. 
    // Base class destructor does the same, but when it is called a table of virtual functions 
    // for this class is no longer valid. If another thread accesses this object    // during its destruction, we can catch an exception: pure virtual function call. 
    // For programming safety we recommend calling NotifyDelete() method in each destructor.
    NotifyDelete();
}


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

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



//File Instrument.h

// An instrument presented on the market. An object of this class can be inserted into the grid. 
// The market is used as an aggregated object. It means that the grid can get name and state of the market 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 can update and highlight a text,
// automatically sort or filter corresponded lines. 
// Note, that CMarket and CInstrument classes use different numeric identifiers 
// (The former starts from 100 and the latter has id = 200).
class CInstrument : public Dapfor::Common::CDelegate
{
public:
    //It is better to use enumerations instead of long numeric values...
    //The grid can use the same identifiers to display values returned by 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 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()
{
    // For programming safety 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 displays three columns with market name, connection state 
    // and instrument name. 
    //
    // That is all. No more code is required for sorting, highlighting, updating, filtering 
    // and other routines for a modified object. The grid does everything automatically. 


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.