TFactorisableContainer.h
Go to the documentation of this file.
1 #ifndef ibase_TFactorisableContainer_included
2 #define ibase_TFactorisableContainer_included
3 
4 
5 // Qt includes
6 #include <QtCore/QPair>
7 
8 // ACF includes
9 #include <istd/TSmartPtr.h>
10 #include <istd/TIFactory.h>
12 
13 
14 namespace ibase
15 {
16 
17 
25 template <class InterfaceClass>
28  QPair<istd::TSmartPtr<InterfaceClass>, QByteArray> >
29 {
30 public:
31  typedef QPair<istd::TSmartPtr<InterfaceClass>, QByteArray> ItemClass;
33 
35  virtual ~TFactorisableContainer();
36 
40  InterfaceClass* InsertElement(int index, const QByteArray& elementFactoryKey);
41 
45  InterfaceClass* AddElement(const QByteArray& elementFactoryKey);
46 
52  InterfaceClass* GetElement(int elementIndex) const;
53 
57  int GetElementIndex(const InterfaceClass& elementRef) const;
58 
62  QByteArray GetElementKey(int elementIndex) const;
63 
65 
66  // reimplemented (iser::ISerializable)
67  bool Serialize(iser::IArchive& archive);
68 
69 protected:
70  virtual InterfaceClass* CreateElement(const QByteArray& itemKey);
71  virtual void OnElementCreated(InterfaceClass* elementPtr);
72 
73  // reimplemented (ibase::TContainer)
74  virtual bool SerializeItem(ItemClass& item, iser::IArchive& archive);
75 
76 protected:
78 };
79 
80 
81 template <class InterfaceClass>
83 {
84  m_itemFactoryPtr = NULL;
85 }
86 
87 
88 template <class InterfaceClass>
90 {
91  BaseClass::Reset();
92 }
93 
94 
95 template <class InterfaceClass>
96 InterfaceClass* TFactorisableContainer<InterfaceClass>::AddElement(const QByteArray& elementFactoryKey)
97 {
98  istd::TSmartPtr<InterfaceClass> elementPtr(CreateElement(elementFactoryKey));
99  if (elementPtr.IsValid()){
100  BaseClass::PushBack(ItemClass(elementPtr, elementFactoryKey));
101  }
102 
103  return elementPtr.GetPtr();
104 }
105 
106 
107 template <class InterfaceClass>
108 InterfaceClass* TFactorisableContainer<InterfaceClass>::InsertElement(int index, const QByteArray& elementFactoryKey)
109 {
110  istd::TSmartPtr<InterfaceClass> elementPtr(CreateElement(elementFactoryKey));
111  if (elementPtr.IsValid()){
112  BaseClass::InsertAt(ItemClass(elementPtr, elementFactoryKey), index);
113  }
114 
115  return elementPtr.GetPtr();
116 }
117 
118 
119 template <class InterfaceClass>
120 InterfaceClass* TFactorisableContainer<InterfaceClass>::GetElement(int elementIndex) const
121 {
122  if (elementIndex < BaseClass::GetItemsCount() && elementIndex >= 0){
123  return const_cast<InterfaceClass*>(BaseClass::GetAt(elementIndex).first.GetPtr());
124  }
125 
126  return NULL;
127 }
128 
129 
130 template <class InterfaceClass>
131 int TFactorisableContainer<InterfaceClass>::GetElementIndex(const InterfaceClass& elementRef) const
132 {
133  for (int itemIndex = 0; itemIndex < BaseClass::GetItemsCount(); itemIndex++){
134  InterfaceClass* elementPtr = GetElement(itemIndex);
135  if (elementPtr == &elementRef){
136  return itemIndex;
137  }
138  }
139 
140  return -1;
141 }
142 
143 
144 template <class InterfaceClass>
146 {
147  if (elementIndex < BaseClass::GetItemsCount() && elementIndex >= 0){
148  return BaseClass::GetAt(elementIndex).second;
149  }
150 
151  return QByteArray();
152 }
153 
154 
155 template <class InterfaceClass>
157 {
158  m_itemFactoryPtr = itemFactoryPtr;
159 }
160 
161 
162 // reimplemented (iser::ISerializable)
163 
164 template <class InterfaceClass>
166 {
167  static iser::CArchiveTag itemsTag("Items", "List of items", iser::CArchiveTag::TT_MULTIPLE);
168  static iser::CArchiveTag itemTag("Item", "Item", iser::CArchiveTag::TT_GROUP, &itemsTag);
169  static iser::CArchiveTag keyTag("ItemKey", "Factory key of the item", iser::CArchiveTag::TT_LEAF, &itemTag);
170 
172  Q_UNUSED(notifier);
173 
174  if (!archive.IsStoring()){
175  this->Reset();
176  }
177 
178  int itemCount = BaseClass::GetItemsCount();
179 
180  bool retVal = archive.BeginMultiTag(itemsTag, itemTag, itemCount);
181  if (!retVal){
182  return false;
183  }
184 
185  for (int index = 0; index < itemCount; index++){
186  retVal = retVal && archive.BeginTag(itemTag);
187 
188  ItemClass item;
189  QByteArray itemKey;
190 
191  if (archive.IsStoring()){
192  itemKey = BaseClass::GetAt(index).second;
193  }
194 
195  retVal = retVal && archive.BeginTag(keyTag);
196  retVal = retVal && archive.Process(itemKey);
197  retVal = retVal && archive.EndTag(keyTag);
198 
199  if (!archive.IsStoring()){
200  item.second = itemKey;
201  InterfaceClass* interfacePtr = CreateElement(itemKey);
202  if (interfacePtr != NULL){
203  item.first.SetPtr(interfacePtr);
204 
205  BaseClass::PushBack(item);
206  }
207  else{
208  return false;
209  }
210  }
211 
212  ItemClass& containerItem = BaseClass::GetAt(index);
213 
214  retVal = retVal && SerializeItem(containerItem, archive);
215 
216  retVal = retVal && archive.EndTag(itemTag);
217  }
218 
219  retVal = retVal && archive.EndTag(itemsTag);
220 
221  return retVal;
222 }
223 
224 
225 // protected methods
226 
227 template <class InterfaceClass>
228 InterfaceClass* TFactorisableContainer<InterfaceClass>::CreateElement(const QByteArray& itemKey)
229 {
230  if (m_itemFactoryPtr != NULL){
231  istd::IPolymorphic* polymorphicPtr = m_itemFactoryPtr->CreateInstance(itemKey);
232  if (polymorphicPtr != NULL){
233  InterfaceClass* interfacePtr = dynamic_cast<InterfaceClass*>(polymorphicPtr);
234  if (interfacePtr != NULL){
235  OnElementCreated(interfacePtr);
236 
237  return interfacePtr;
238  }
239  else{
240  delete polymorphicPtr;
241 
242  return NULL;
243  }
244  }
245  }
246 
247  return NULL;
248 }
249 
250 
251 template <class InterfaceClass>
253 {
254 }
255 
256 
257 // reimplemented (ibase::TContainer)
258 
259 template <class InterfaceClass>
261 {
262  iser::ISerializable* serializablePtr = dynamic_cast<iser::ISerializable*>(item.first.GetPtr());
263  if (serializablePtr != NULL){
264  return serializablePtr->Serialize(archive);
265  }
266 
267  return false;
268 }
269 
270 
271 } // namespace ibase
272 
273 
274 #endif // !ibase_TFactorisableContainer_included
275 
ibase::TSerializableContainer< ItemClass > BaseClass
InterfaceClass * GetElement(int elementIndex) const
Gets an element with given index elementIndex from the container.
Specific container implementation for factorisable items.
virtual bool IsStoring() const =0
Check if this archive is loading or storing.
InterfaceClass * AddElement(const QByteArray &elementFactoryKey)
Add an element to the container.
Common class for all classes which objects can be archived or restored from archive.
Definition: ISerializable.h:23
virtual bool Process(bool &value)=0
Process primitive type.
virtual bool Serialize(IArchive &archive)=0
Load or store state of this object as a archive stream.
virtual bool BeginTag(const CArchiveTag &tag)=0
Begin of archive tag.
Multiple tag containing variable number of child tags.
Definition: CArchiveTag.h:42
Normal tag used for grouping of tags or processed elements.
Definition: CArchiveTag.h:37
virtual bool BeginMultiTag(const CArchiveTag &tag, const CArchiveTag &subTag, int &count)=0
Begin of archive tag containing set of subelements of the same type.
Represent input/output persistence archive.
Definition: IArchive.h:30
Base interface for all used interfaces and implementations.
Definition: IPolymorphic.h:17
Implementation of a smart pointer.
Definition: TSmartPtr.h:24
bool IsValid() const
Check, whether the object is in valid state.
Definition: TTransPtr.h:131
virtual InterfaceClass * CreateElement(const QByteArray &itemKey)
Help class which provides the automatic update mechanism of the model.
Leaf tag, it can contain only one primitive element.
Definition: CArchiveTag.h:48
void RegisterItemFactory(istd::TIFactory< InterfaceClass > *itemFactoryPtr)
#define NULL
Definition: istd.h:64
Common implementation for an abstract serializable container.
static const ChangeSet & GetAllChanges()
Get anonymous change set.
Definition: IChangeable.h:387
virtual bool SerializeItem(ItemClass &item, iser::IArchive &archive)
Serialize a single item in the container.
istd::TIFactory< InterfaceClass > * m_itemFactoryPtr
QPair< istd::TSmartPtr< InterfaceClass >, QByteArray > ItemClass
int GetElementIndex(const InterfaceClass &elementRef) const
Gets the index of given element from the container.
Process tag used to group data in archive stream.
Definition: CArchiveTag.h:21
QByteArray GetElementKey(int elementIndex) const
Gets the element key associated with the element with given elementIndex from the container...
virtual bool EndTag(const CArchiveTag &tag)=0
End of archive tag.
const Type * GetPtr() const
Get access to pointed object.
Definition: TTransPtr.h:138
virtual void OnElementCreated(InterfaceClass *elementPtr)
InterfaceClass * InsertElement(int index, const QByteArray &elementFactoryKey)
Insert an element into the container at given index.
bool Serialize(iser::IArchive &archive)
Load or store state of this object as a archive stream.

© 2007-2017 Witold Gantzke and Kirill Lepskiy