00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef _DynamicType_
00026 #define _DynamicType_
00027
00028 #include "XMLAdapter.hxx"
00029 #include "XMLIterableAdapter.hxx"
00030 #include "XMLComponentAdapter.hxx"
00031
00032 #include "DynamicTypeMacros.hxx"
00033
00034 #include "Component.hxx"
00035 #include "DataTypes.hxx"
00036
00037 #include <new>
00038
00039 namespace CLAM {
00040
00042
00043
00045
00046
00070 class DynamicType : public Component
00071 {
00072 public:
00080 DynamicType(const int nAttr);
00081
00091 DynamicType(const DynamicType& prototype, const bool shareData, const bool deepCopy);
00092 DynamicType(const DynamicType& prototype);
00093 virtual ~DynamicType();
00094
00095 virtual const char* GetClassName() const =0;
00096 protected:
00105 void DefaultInit() {
00106
00107 };
00108
00113 virtual void InformAll() {
00114
00115 CLAM_DEBUG_ASSERT(typeDescTable,"static table don't exist. in DT::InformAll()");
00116 int adder=0;
00117 for (unsigned int i=0; i<numAttr; i++) {
00118 typeDescTable[i].offset = adder;
00119 adder += typeDescTable[i].size;
00120 }
00121 maxAttrSize = adder;
00122
00123 };
00124
00125 public:
00133 void CopyInit(const DynamicType & dt) {
00134 };
00135
00145 bool UpdateData();
00146
00147 private:
00148
00149
00150
00151 typedef void* (*t_new)(void* pos);
00152 typedef void* (*t_new_copy)(void* pos,void* orig);
00153 typedef void (*t_destructor)(void* pos);
00154
00155 virtual void InformAttr_ (unsigned id, const char* name, unsigned size, const char* type, const bool isPtr,
00156 const t_new, const t_new_copy, const t_destructor);
00157
00158 protected:
00159 inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
00160 const t_new, const t_new_copy, const t_destructor, const Component* ptr);
00161
00162 inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
00163 const t_new, const t_new_copy, const t_destructor, const DynamicType* ptr);
00164
00165 inline void InformTypedAttr_(unsigned id, const char* name, unsigned size, const char *type, const bool isPtr,
00166 const t_new, const t_new_copy, const t_destructor, const void* ptr);
00167
00168 void AddAttr_ (const unsigned i, const unsigned size);
00169 void RemoveAttr_ (const unsigned id);
00170
00171 public:
00172 unsigned GetNDynamicAttributes() const { return numAttr; }
00173 const char * GetDynamicAttributeName(unsigned i) { return typeDescTable[i].id; }
00174 virtual const std::type_info & GetTypeId(unsigned i) const=0;
00175 bool AttributeIsComponent(unsigned i) const {return typeDescTable[i].isComponent; }
00176 bool AttributeIsDynamictype(unsigned i) const {return typeDescTable[i].isDynamicType; }
00177 bool IsAttributeInstantiated(unsigned i) const {return dynamicTable[i].offs!=-1; }
00178 const void * GetAttributeAsVoidPtr(unsigned i) const {
00179 return GetPtrToData_(i);
00180 }
00181 const Component * GetAttributeAsComponent(unsigned i) const {
00182 if (!typeDescTable[i].isComponent) return 0;
00183 return static_cast<const Component *> (GetPtrToData_(i));
00184 }
00185 Component * GetAttributeAsComponent(unsigned i) {
00186 if (! (typeDescTable[i].isComponent)) return 0;
00187 return static_cast<Component *> (GetPtrToData_(i));
00188 }
00189 void FullfilsInvariant() const;
00190
00191 virtual Component* DeepCopy() const;
00192 public:
00193 enum {idLength = 120, typeLength = 120};
00194
00195 protected:
00196 enum {shrinkThreshold = 80};
00197
00198
00199
00200 struct TAttr
00201 {
00202 char id[idLength];
00203 char type[typeLength];
00204 int size;
00205 int offset;
00206 t_new newObj;
00207 t_new_copy newObjCopy;
00208 t_destructor destructObj;
00209
00210
00211 bool isComponent : 1;
00212 bool isStorable : 1;
00213 bool isDynamicType : 1;
00214 bool isPointer : 1;
00215 };
00216
00217
00218 struct TDynInfo
00219 {
00220 int offs;
00221
00222 bool hasBeenAdded : 1;
00223 bool hasBeenRemoved : 1;
00224 };
00225 virtual DynamicType& GetDynamicTypeCopy(const bool shareData = false, const bool deep = false) const =0;
00226 virtual Component* ShallowCopy() const;
00227 DynamicType& operator= (const DynamicType& source);
00228
00229
00230
00231 inline unsigned GetNumAttr() const { return numAttr; };
00232 inline unsigned GetNumActiveAttr() const { return numActiveAttr; }
00233 inline char* GetData() const { return data; }
00234 inline void SetData(char* srcData) { data = srcData;}
00235 inline TDynInfo* GetDynamicTable() const { return dynamicTable; }
00236 inline TAttr* GetTypeDescTable() const { return typeDescTable; }
00237 inline unsigned GetDataSize() const { return dataSize; }
00238 inline bool IsInstanciate() const { return (data != 0); }
00239 inline bool OwnsItsMemory() const { return bOwnsItsMemory; }
00240 inline void SetOwnsItsMemory(const bool owns) { bOwnsItsMemory = owns; }
00241 inline bool ExistAttr(unsigned id) const;
00242 inline void SetPreAllocateAllAttributes() { bPreAllocateAllAttributes=true; }
00243
00244
00245 public:
00246
00247 void Debug() const;
00248
00249 protected:
00250
00251 unsigned numActiveAttr;
00252 char *data;
00253 TDynInfo *dynamicTable;
00254 TAttr *typeDescTable;
00255 unsigned dataSize;
00256 bool bOwnsItsMemory;
00257 unsigned numAttr;
00258 unsigned maxAttrSize;
00259 unsigned allocatedDataSize;
00260
00261 inline int DynTableRefCounter();
00262 inline void InitDynTableRefCounter();
00263 inline int DecrementDynTableRefCounter();
00264 inline int IncrementDynTableRefCounter();
00265
00266 private:
00267 inline bool AttrHasData(unsigned i) const { return (dynamicTable[i].offs > -1); };
00268 inline void RemoveAllMem();
00269 inline void* GetPtrToData_(const unsigned id) const;
00270 inline void* GetDataAsPtr_(const unsigned id) const;
00271 inline void SetDataAsPtr_(const unsigned id, void* p);
00272
00274 void BeMemoryOwner();
00280 void UpdateDataByShrinking();
00281
00286 void UpdateDataByStandardMode();
00287
00291 void UpdateDataGoingToPreAllocatedMode();
00292
00296 void UpdateDataInPreAllocatedMode();
00297
00298 void SelfCopyPrototype(const DynamicType &orig);
00299 void SelfSharedCopy(const DynamicType &orig);
00300 void SelfShallowCopy(const DynamicType &orig);
00301 void SelfDeepCopy(const DynamicType &orig);
00302 bool bPreAllocateAllAttributes;
00303
00304 public:
00305 virtual void StoreOn(CLAM::Storage & storage) const {
00306 this->StoreDynAttributes(storage);
00307 }
00308 virtual void LoadFrom(CLAM::Storage & storage) {
00309 this->LoadDynAttributes(storage);
00310 }
00311 template <unsigned int NAttrib>
00312 class AttributePositionBase {
00313 public:
00314 static const int value;
00315 };
00316
00317 protected:
00318 virtual void StoreDynAttributes(CLAM::Storage & s) const=0;
00319 virtual void LoadDynAttributes(CLAM::Storage & s)=0;
00320 template <typename AttribType>
00321 void StoreAttribute(StaticTrue* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) const
00322 {
00323 CLAM::XMLAdapter<AttribType> adapter(object, name, true);
00324 s.Store (adapter);
00325 }
00326 template <typename AttribType>
00327 void StoreAttribute(StaticFalse* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) const
00328 {
00329 CLAM::XMLComponentAdapter adapter(object, name, true);
00330 s.Store (adapter);
00331 }
00332 template <typename AttribType>
00333 void StoreIterableAttribute(CLAM::Storage &s ,AttribType & object, const char* name, const char* elemName) const
00334 {
00335 CLAM::XMLIterableAdapter<AttribType> adapter(object, elemName, name, true);
00336 s.Store (adapter);
00337 }
00338
00339 template <typename AttribType>
00340 bool LoadAttribute(StaticTrue* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) {
00341 CLAM::XMLAdapter<AttribType> adapter(object, name, true);
00342 return s.Load (adapter);
00343 }
00344 template <typename AttribType>
00345 bool LoadAttribute(StaticFalse* asLeave, CLAM::Storage &s ,AttribType & object, const char* name) {
00346 CLAM::XMLComponentAdapter adapter(object, name, true);
00347 return s.Load (adapter);
00348 }
00349 template <typename AttribType>
00350 bool LoadIterableAttribute(CLAM::Storage &s ,AttribType & object, const char* name, const char* elemName) {
00351 CLAM::XMLIterableAdapter<AttribType> adapter(object, elemName, name, true);
00352 return s.Load (adapter);
00353 }
00354 };
00355
00356
00358
00359
00360 template <unsigned int NAttrib> const int DynamicType::AttributePositionBase<NAttrib>::value = NAttrib;
00361
00363
00364
00365 inline bool DynamicType::ExistAttr(unsigned id) const
00366 {
00367
00368 if (!data) return false;
00369
00370 TDynInfo &inf = dynamicTable[id];
00371 return (inf.offs != -1 && !inf.hasBeenAdded && !inf.hasBeenRemoved);
00372 }
00373
00374 inline void* DynamicType::GetDataAsPtr_(const unsigned id) const
00375 {
00376 return *(void**)&data[dynamicTable[id].offs];
00377 }
00378
00379 inline void* DynamicType::GetPtrToData_(const unsigned id) const
00380 {
00381 return (void*)&data[dynamicTable[id].offs];
00382 }
00383
00384 inline void DynamicType::SetDataAsPtr_(const unsigned id, void* p)
00385 {
00386 *(void**)&data[dynamicTable[id].offs] = p;
00387 }
00388
00389
00391
00392
00393
00394 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
00395 const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const void* ptr)
00396 {
00397 InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
00398 typeDescTable[val].isComponent = false;
00399 typeDescTable[val].isDynamicType = false;
00400 typeDescTable[val].isStorable = false;
00401 }
00402
00403 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
00404 const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const Component* ptr)
00405 {
00406 InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
00407 typeDescTable[val].isComponent = true;
00408 typeDescTable[val].isDynamicType = false;
00409 typeDescTable[val].isStorable = false;
00410 }
00411
00412 inline void DynamicType::InformTypedAttr_(unsigned val, const char*name, unsigned size, const char *type, const bool isPtr,
00413 const t_new fnew, const t_new_copy fcopy, const t_destructor fdestr, const DynamicType* ptr)
00414 {
00415 InformAttr_(val, name, size, type, isPtr, fnew, fcopy, fdestr);
00416 typeDescTable[val].isComponent = true;
00417 typeDescTable[val].isDynamicType = true;
00418 typeDescTable[val].isStorable = false;
00419 }
00420
00421
00422 }
00423
00424 #endif // !defined _DynamicType_
00425