CLAM-Development
1.1
|
00001 /* DynamicType.hxx: interface for the DynamicType class. 00002 * written by Pau Arumí - May 2001 00003 * new version (that stores every type) : 21-July-2001 00004 * 00005 * Copyright (c) 2001-2004 MUSIC TECHNOLOGY GROUP (MTG) 00006 * UNIVERSITAT POMPEU FABRA 00007 * 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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" //this file is not included anywhere but here. 00033 00034 #include "Component.hxx" 00035 #include "DataTypes.hxx" 00036 00037 #include <new> 00038 00039 namespace CLAM { 00040 00042 // Class DynamicType declaration : 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 // lets calculates the offsets of the "Pre allocated mode" 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 // Types of the constructors and destructors that all registerd type must have. 00149 // A pointer to these functions is stored into the typeDescTable. (an array of TAttr) 00150 // The definition of TAttr is following: 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}; //TODO: rise exception if the type is too long 00194 00195 protected: 00196 enum {shrinkThreshold = 80}; // Bytes. That constant means that when updating data, if the 00197 // used data disminish an amount superior that this threshold, 00198 // data will be reallocated (shrunk) 00199 // item of the typeDescTable, that is static created only once in the concrete class constructor 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 // bool isInformed : 1; Deprecated!! Now the concrete constr. calls InformAll() chain.method. 00211 bool isComponent : 1; 00212 bool isStorable : 1; 00213 bool isDynamicType : 1; 00214 bool isPointer : 1; 00215 }; 00216 00217 // item of the dynamicTable, that holds the dynamic information of the dynamic type 00218 struct TDynInfo 00219 { 00220 int offs; // attribute offset of the data table. Has a -1 value when 00221 // the attr is not instantiated (have no entry at the data table). 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 // Public Accesors to protected data. Necesary in the implementation of Branches (aggregates) 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 // Developing tools: 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; // the total number of dyn. attrs. 00258 unsigned maxAttrSize; // the total dyn. attrs. size 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 // STATIC MEMBERS DEFINITION 00359 00360 template <unsigned int NAttrib> const int DynamicType::AttributePositionBase<NAttrib>::value = NAttrib; 00361 00363 // IMPLEMENTATION OF INLINE FUNCTIONS 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 } //namespace CLAM 00423 00424 #endif // !defined _DynamicType_ 00425