Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGFieldContainerType.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 #ifdef OSG_DOC_FILES_IN_MODULE
00040 
00043 #endif
00044 
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 
00048 #include "OSGConfig.h"
00049 
00050 #include <iostream>
00051 
00052 #include <algorithm>
00053 
00054 #include "OSGFieldContainerType.h"
00055 #include "OSGFieldContainerFactory.h"
00056 
00057 #include "OSGFieldDescription.h"
00058 
00059 #include "OSGNodePtr.h"
00060 #include "OSGAttachmentPtr.h"
00061 
00062 #include "OSGNodeCore.h"
00063 #include "OSGAttachment.h"
00064 
00065 OSG_USING_NAMESPACE
00066 
00067 //---------------------------------------------------------------------------
00068 //  Class
00069 //---------------------------------------------------------------------------
00070 
00071 /*-------------------------------------------------------------------------*/
00072 /*                              Register                                   */
00073 
00074 inline
00075 void FieldContainerType::registerType(const Char8 *szGroupName)
00076 {
00077     FieldContainerFactory::the()->registerType (this);
00078 
00079     _uiGroupId = FieldContainerFactory::the()->registerGroup(
00080         szGroupName != NULL ? szGroupName : _szName.str());
00081 }
00082 
00083 /*-------------------------------------------------------------------------*/
00084 /*                            Constructors                                 */
00085 
00086 FieldContainerType::FieldContainerType(const Char8    *szName,
00087                                    const Char8        *szParentName,
00088                                    const Char8        *szGroupName,
00089                                    PrototypeCreateF    fPrototypeCreate,
00090                                    InitContainerF      fInitMethod,
00091                                    FieldDescription  **pDesc,
00092                                    UInt32              uiDescByteCounter,
00093                                    bool                bDescsAddable) :
00094      Inherited        (szName, 
00095                        szParentName     ),
00096     _uiGroupId        (0                ),
00097 
00098     _bInitialized     (false            ),
00099     _bDescsAddable    (bDescsAddable    ),
00100 
00101     _baseType         (IsFieldContainer ),
00102 
00103     _pParent          (NULL             ),
00104 
00105     _szParentName     (szParentName     ),
00106     _szGroupName      (szGroupName      ),
00107 
00108     _pPrototype       (NullFC           ),
00109     _fPrototypeCreate (fPrototypeCreate ),
00110 
00111     _pDesc            (pDesc            ),
00112     _uiDescByteCounter(uiDescByteCounter),
00113 
00114     _mDescMap         (                 ),
00115     _vDescVec         (0                ),
00116     _bCopy            (false            )
00117 {
00118     registerType(szGroupName);
00119 
00120     if(fInitMethod != NULL)
00121         fInitMethod();
00122 }
00123 
00124 FieldContainerType::FieldContainerType(const FieldContainerType &obj) :
00125 
00126      Inherited        (obj                   ),
00127     _uiGroupId        (obj._uiGroupId        ),
00128 
00129     _bInitialized     (false                 ),
00130     _bDescsAddable    (obj._bDescsAddable    ),
00131 
00132     _baseType         (obj._baseType         ),
00133 
00134     _pParent          (obj._pParent          ),
00135 
00136     _szParentName     (obj._szParentName     ),
00137     _szGroupName      (obj._szGroupName      ),
00138 
00139     _pPrototype       (obj._pPrototype       ),
00140     _fPrototypeCreate (obj._fPrototypeCreate ),
00141 
00142     _pDesc            (obj._pDesc            ),
00143     _uiDescByteCounter(obj._uiDescByteCounter),
00144 
00145     _mDescMap         (                      ),
00146     _vDescVec         (0                     ),
00147     _bCopy            (true                  )
00148 {
00149     if(_pPrototype != NullFC)
00150         addRefCP(_pPrototype);
00151 
00152     initFields();
00153     initParentFields();
00154 
00155     _bInitialized = true;
00156 }
00157 
00158 /*-------------------------------------------------------------------------*/
00159 /*                             Destructor                                  */
00160 
00161 FieldContainerType::~FieldContainerType(void)
00162 {
00163     if(GlobalSystemState != Shutdown)
00164     {
00165         terminate();
00166         if(_bCopy == false)
00167         {
00168             FieldContainerFactory::the()->unregisterType(this);
00169         }
00170     }
00171 }
00172 
00173 /*-------------------------------------------------------------------------*/
00174 /*                            Add / Sub                                    */
00175 
00176 UInt32 FieldContainerType::addDescription(const FieldDescription &desc)
00177 {
00178     UInt32            returnValue = 0;
00179     DescMapConstIt    descIt;
00180     DescVecIt         descVIt;
00181 
00182     FieldDescription  *pDesc;
00183     FieldDescription  *pNullDesc = NULL;
00184 
00185     if(_bDescsAddable == false)
00186         return returnValue;
00187 
00188     descIt = _mDescMap.find(IDStringLink(desc.getCName()));
00189 
00190     if(desc.isValid())
00191     {
00192         if(descIt == _mDescMap.end())
00193         {
00194             pDesc = new FieldDescription(desc);
00195 
00196             _mDescMap[IDStringLink(pDesc->getCName())] = pDesc;
00197 
00198             descVIt = std::find(_vDescVec.begin(),
00199                                 _vDescVec.end(),
00200                                  pNullDesc);
00201 
00202             if(descVIt == _vDescVec.end())
00203             {
00204                 _vDescVec.push_back(pDesc);
00205 
00206                 returnValue = _vDescVec.size();
00207             }
00208             else
00209             {
00210                 (*descVIt) = pDesc;
00211 
00212                 returnValue  = descVIt - _vDescVec.begin();
00213                 returnValue += 1;
00214             }
00215         }
00216         else
00217         {
00218             SWARNING << "ERROR: Double field description "
00219                         << "in " << _szName.str() << " from "
00220                         << desc.getCName() << " (id:"
00221                         << desc.getTypeId() << ")" << std::endl;
00222         }
00223     }
00224     else
00225     {
00226         SWARNING << "ERROR: Invalid field description "
00227                     << "in " << _szName.str() << " from "
00228                     << desc.getTypeId() << std::endl;
00229     }
00230 
00231     return returnValue;
00232 }
00233 
00234 bool FieldContainerType::subDescription(UInt32 uiFieldId)
00235 {
00236     FieldDescription  *pDesc = getFieldDescription(uiFieldId);
00237     DescMapIt          descMIt;
00238     DescVecIt          descVIt;
00239     bool               returnValue = true;
00240 
00241     if(pDesc == NULL || _bDescsAddable == false)
00242         return false;
00243 
00244     descMIt = _mDescMap.find(IDStringLink(pDesc->getCName()));
00245 
00246     if(descMIt != _mDescMap.end())
00247     {
00248         _mDescMap.erase(descMIt);
00249     }
00250     else
00251     {
00252         returnValue = false;
00253     }
00254 
00255     descVIt = std::find(_vDescVec.begin(), _vDescVec.end(), pDesc);
00256 
00257     if(descVIt != _vDescVec.end())
00258     {
00259         (*descVIt) = NULL;
00260 
00261         returnValue &= true;
00262     }
00263     else
00264     {
00265         returnValue = false;
00266     }
00267 
00268     delete pDesc;
00269 
00270     return returnValue;
00271 }
00272 
00273 
00274 /*-------------------------------------------------------------------------*/
00275 /*                               Create                                    */
00276 
00277 FieldContainerPtr FieldContainerType::createFieldContainer(void) const
00278 {
00279     FieldContainerPtr fc;
00280 
00281     if(isAbstract()       == false)
00282     {
00283         fc = _pPrototype->shallowCopy();
00284     }
00285 
00286     return fc;
00287 
00288 }
00289 
00290 NodePtr  FieldContainerType::createNode(void) const
00291 {
00292     NodePtr fc;
00293 
00294     if(isAbstract() == false &&
00295        isNode()     == true)
00296     {
00297         fc = NodePtr::dcast(_pPrototype->shallowCopy());
00298     }
00299 
00300     return fc;
00301 }
00302 
00303 NodeCorePtr FieldContainerType::createNodeCore(void) const
00304 {
00305     NodeCorePtr fc;
00306 
00307     if(isAbstract() == false &&
00308        isNodeCore() == true)
00309     {
00310         fc = NodeCorePtr::dcast(_pPrototype->shallowCopy());
00311     }
00312 
00313     return fc;
00314 }
00315 
00316 AttachmentPtr FieldContainerType::createAttachment(void) const
00317 {
00318     AttachmentPtr fc;
00319 
00320     if(isAbstract()   == false &&
00321        isAttachment() == true)
00322     {
00323         fc = AttachmentPtr::dcast(_pPrototype->shallowCopy());
00324     }
00325 
00326     return fc;
00327 }
00328 
00329 
00330 /*-------------------------------------------------------------------------*/
00331 /*                                Dump                                     */
00332 
00333 void FieldContainerType::dump(      UInt32    OSG_CHECK_ARG(uiIndent),
00334                               const BitVector OSG_CHECK_ARG(bvFlags )) const
00335 {
00336     SLOG << "FieldContainerType: "
00337          << getCName()
00338          << ", Id: "       
00339          << getId()
00340          << ", parentP: " 
00341          << (_pParent ? _pParent->getCName() : "NONE")
00342          << ", groupId: "  
00343          << _uiGroupId
00344          << ", abstract: "
00345          << ((_pPrototype != NullFC) ? "false" : "true")
00346          << " "
00347          << _vDescVec.size()
00348          << std::endl;
00349 
00350     for(UInt32 i = 0; i < _vDescVec.size(); i++)
00351     {
00352         SLOG << "Desc : " << _vDescVec[i]->getCName() << std::endl;
00353     }
00354 }
00355 
00356 
00357 /*-------------------------------------------------------------------------*/
00358 /*                                Init                                     */
00359 
00360 bool FieldContainerType::initPrototype(void)
00361 {
00362     _bInitialized = true;
00363 
00364     if(_fPrototypeCreate != NULL)
00365     {
00366         _pPrototype = _fPrototypeCreate();
00367 
00368         addRefCP(_pPrototype);
00369     }
00370 
00371     return _bInitialized;
00372 }
00373 
00374 bool FieldContainerType::initBaseType(void)
00375 {
00376     if     (isDerivedFrom(NodeCore::getClassType())   == true)
00377     {
00378         _baseType = IsNodeCore;
00379     }
00380     else if(isDerivedFrom(Attachment::getClassType()) == true)
00381     {
00382         _baseType = IsAttachment;
00383     }
00384     else if(isDerivedFrom(Node::getClassType())       == true)
00385     {
00386         _baseType = IsNode;
00387     }
00388 
00389     return true;
00390 }
00391 
00392 bool FieldContainerType::initFields(void)
00393 {
00394     UInt32    i;
00395     DescMapIt descIt;
00396 
00397     _bInitialized = true;
00398 
00399     if(_pDesc == NULL)
00400         return true;
00401 
00402     for(i = 0; i < _uiDescByteCounter / sizeof(FieldDescription *); i++)
00403     {
00404         if(_pDesc[i]->isValid())
00405         {
00406             descIt = _mDescMap.find(IDStringLink(_pDesc[i]->getCName()));
00407 
00408             if(descIt == _mDescMap.end())
00409             {
00410                 _mDescMap[IDStringLink(_pDesc[i]->getCName())] = _pDesc[i];
00411 
00412                 _vDescVec.push_back(_pDesc[i]);
00413             }
00414             else
00415             {
00416                 SWARNING << "ERROR: Double field description "
00417                             << "in " << _szName.str() << " from "
00418                             << _pDesc[i]->getCName() << " (id:"
00419                             << _pDesc[i]->getTypeId() << ")" << std::endl;
00420 
00421                 _bInitialized = false;
00422             }
00423         }
00424         else
00425         {
00426             SWARNING << "ERROR: Invalid field description "
00427                         << "in " << _szName.str() << "from "
00428                         << (_pDesc[i]?_pDesc[i]->getTypeId():0) << std::endl;
00429 
00430             _bInitialized = false;
00431         }
00432 
00433     }
00434 
00435     std::sort(_vDescVec.begin(), _vDescVec.end(), FieldDescriptionPLT());
00436 
00437     return _bInitialized;
00438 }
00439 
00440 bool FieldContainerType::initParentFields(void)
00441 {
00442     DescMapIt dPIt;
00443 
00444     _bInitialized = true;
00445 
00446     if(_szParentName.str() != NULL)
00447     {
00448         _pParent =
00449             FieldContainerFactory::the()->findType(_szParentName.str());
00450 
00451         if(_pParent == NULL)
00452         {
00453             _pParent =
00454                 FieldContainerFactory::the()->findUninitializedType(
00455                     _szParentName.str());
00456         }
00457 
00458         if(_pParent != NULL)
00459         {
00460             _bInitialized = _pParent->initialize();
00461 
00462             if(_bInitialized == false)
00463             {
00464                 return _bInitialized;
00465             }
00466 
00467             for(  dPIt  = _pParent->_mDescMap.begin();
00468                   dPIt != _pParent->_mDescMap.end();
00469                 ++dPIt)
00470             {
00471                 if(_mDescMap.find((*dPIt).first) == _mDescMap.end())
00472                 {
00473                     _mDescMap[(*dPIt).first] = (*dPIt).second;
00474                 }
00475                 else
00476                 {
00477                     SWARNING << "ERROR: Can't add field "
00478                                 << "description a second time: "
00479                                 << (*dPIt).first.str() << std::endl;
00480                 }
00481             }
00482 
00483             _vDescVec.insert(_vDescVec.end(),
00484                              _pParent->_vDescVec.begin(),
00485                              _pParent->_vDescVec.end());
00486 
00487         }
00488         else
00489         {
00490             SWARNING << "ERROR: Can't find type with "
00491                         << "name " << _szParentName.str()
00492                         << std::endl;
00493 
00494             _bInitialized = false;
00495         }
00496     }
00497 
00498     return _bInitialized;
00499 }
00500 
00501 bool FieldContainerType::initialize(void)
00502 {
00503     if(_bInitialized == true)
00504         return _bInitialized;
00505 
00506     _bInitialized = initParentFields();
00507 
00508     if(_bInitialized == false)
00509         return _bInitialized;
00510 
00511     _bInitialized = initFields      ();
00512 
00513     if(_bInitialized == false)
00514         return _bInitialized;
00515 
00516     _bInitialized = initPrototype   ();
00517 
00518     if(_bInitialized == false)
00519         return _bInitialized;
00520 
00521     _bInitialized = initBaseType    ();
00522 
00523     FDEBUG ( ( "init FieldContainerType %s (%d)\n",
00524                _szName.str(), int(_bInitialized) ));
00525 
00526     if(_vDescVec.size() > sizeof(BitVector) * 8)
00527     {
00528         FWARNING(("FCType %s has %d (>%d) fields!\n", getCName(),
00529                     _vDescVec.size(), sizeof(BitVector) * 8));
00530     }
00531     
00532     return _bInitialized;
00533 }
00534 
00535 void FieldContainerType::terminate(void)
00536 {
00537     UInt32 i;
00538 
00539     subRefCP(_pPrototype);
00540 
00541     _bInitialized = false;
00542 
00543     for(i = 0; i < _uiDescByteCounter / sizeof(FieldDescription *); i++)
00544     {
00545         delete _pDesc[i];
00546     }
00547 }
00548 
00549 
00550 /*-------------------------------------------------------------------------*/
00551 /*                              cvs id's                                   */
00552 
00553 #ifdef __sgi
00554 #pragma set woff 1174
00555 #endif
00556 
00557 #ifdef OSG_LINUX_ICC
00558 #pragma warning( disable : 177 )
00559 #endif
00560 
00561 namespace
00562 {
00563     static Char8 cvsid_cpp[] = "@(#)$Id: $";
00564     static Char8 cvsid_hpp[] = OSGFIELDCONTAINERTYPE_HEADER_CVSID;
00565 }

Generated on Thu Aug 25 04:04:46 2005 for OpenSG by  doxygen 1.4.3