I want to implement a collection or list using TOwnedCollection / TCollectionItem. I need a persistent list (to load and create from a FileStream) of classes with polymorphism.
Here is (part of) my code so far, but I didn't succeed to create the derived class TGenerator instead of its parent TPowerComponent and add it to the Collection.
//-------------------------------------------------------------------------------------
class TPCCollection : public TOwnedCollection
{
typedef TOwnedCollection inherited;
private:
TPowerComponent* __fastcall GetPowerComponent(int Index);
void __fastcall SetPowerComponent(int Index, TPowerComponent *Value);
public:
__fastcall TPCCollection(TPersistent *Owner);
HIDESBASE TPowerComponent* __fastcall Add(void);
HIDESBASE TPowerComponent* __fastcall Insert(int Index);
__property TPowerComponent* PCCollection[int Index] = {read=GetPowerComponent, write=SetPowerComponent};
};
//-------------------------------------------------------------------------------------
class TPowerComponent : public TCollectionItem
{
typedef TCollectionItem inherited;
public :
int X, Y, Rotation;
PowSymbType HisType;
__fastcall TPowerComponent(TCollection *Collection, PowSymbType AType );
void __fastcall Assign(TPersistent *Source);
virtual void __fastcall Paint(TCanvas * Canvas);
};
//-------------------------------------------------------------------------------------
class TGenerator : public TPowerComponent
{
typedef TPowerComponent inherited;
public :
double PG, Qgmin, Qgmax, Vsch;
__fastcall TGenerator(TCollection *Collection, PowSymbType AType );
void __fastcall Assign(TPersistent *Source);
virtual void __fastcall Paint(TCanvas * Canvas);
};
//-------------------------------------------------------------------------------------
// implementation
//-------------------------------------------------------------------------------------
// TPCCOllection
//-------------------------------------------------------------------------------------
__fastcall TPCCollection::TPCCollection(TPersistent *Owner)
: TOwnedCollection(Owner, __classid(TPowerComponent))
{
}
//-------------------------------------------------------------------------------------
TPowerComponent* __fastcall TPCCollection::Add()
{
return static_cast<TPowerComponent>(inherited::Add());
}
//-------------------------------------------------------------------------------------
TPowerComponent* __fastcall TPCCollection::Insert(int Index)
{
return static_cast<TPowerComponent>(inherited::Insert(Index));
}
//-------------------------------------------------------------------------------------
TPowerComponent* __fastcall TPCCollection::GetPowerComponent(int Index)
{
return static_cast<TPowerComponent>(inherited::GetItem(Index));
}
//-------------------------------------------------------------------------------------
void __fastcall TPCCollection::SetPowerComponent(int Index, TPowerComponent *Value)
{
inherited::SetItem(Index, Value);
}
//-------------------------------------------------------------------------------------
// TPowerComponent
//-------------------------------------------------------------------------------------
__fastcall TPowerComponent::TPowerComponent(TCollection *Collection, PowSymbType AType )
: TCollectionItem(Collection)
{
HisType=AType;
Rotation=0;
}
//-------------------------------------------------------------------------------------
void __fastcall TPowerComponent::Assign(TPersistent *Source)
{
TPowerComponent *Src = dynamic_cast<TPowerComponent>(Source);
if( Src )
{
// copy members from Src...
}
else inherited::Assign(Source);
}
//-------------------------------------------------------------------------------------
// se dessine
void __fastcall TPowerComponent::Paint(TCanvas * Canvas)
{
...
}
//-------------------------------------------------------------------------------------
// TGenerator
//-------------------------------------------------------------------------------------
__fastcall TGenerator::TGenerator(TCollection *Collection, PowSymbType AType )
:TPowerComponent( Collection, AType )
{
PG=0; Qgmin=0; Qgmax=0; Vsch=1.0; Con=-1;
}
//-------------------------------------------------------------------------------------
void __fastcall TGenerator::Assign(TPersistent *Source)
{
TGenerator *Src = dynamic_cast<TGenerator>(Source);
if( Src )
{
// copy members from Src...
}
else inherited::Assign(Source);
}
//-------------------------------------------------------------------------------------
// Usage
TPCCollection * NetWork = new TPCCollection(this);
// Usage to Access all the collection
for( int i=0; i< NetWork->Count; i++)
{
((TPowerComponent*)(NetWork->Items[i]))->Paint(Canvas);
}
To add a TGenerator and not a TPowerComponent, I use:
TGenerator * Gen=new TGenerator( NetWork, Generator);
The creation of the TCollectionItem child automatically add itself to the TCollection
The problem here is that we can't separate the process of item creation from adding it to the collection.
When I need another list that can have some of the items of the first collection list, for example, SelectedComponents can have one or some of the Items of the NetWork Collection, without recreating them.
This can be done with
std::list<TPowerComponent*> SelectedComponents;
but I can't write/read them using FileStream / persistent list. I need to put them in a TCollection but without recreating them.
How?