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

OSGFieldContainerFactory.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 #include <string>
00052 
00053 #include "OSGFieldContainerFactory.h"
00054 #include "OSGFieldContainerType.h"
00055 #include "OSGFieldDescription.h"
00056 
00057 #include "OSGNodePtr.h"
00058 #include "OSGAttachmentPtr.h"
00059 
00060 #include "OSGFieldFactory.h"
00061 #include "OSGFieldType.h"
00062 
00063 OSG_USING_NAMESPACE
00064 
00065 FieldContainerFactory *FieldContainerFactory::_the = NULL;
00066 
00067 FieldContainerFactory::TypeMapIterator 
00068                        FieldContainerFactory::_defaultTypeMapIt;
00069 
00070 FieldContainerMapper::~FieldContainerMapper()
00071 {
00072 }
00073  
00074 /*-------------------------------------------------------------------------*/
00075 /*                                The                                      */
00076 
00077 FieldContainerFactory *FieldContainerFactory::the(void)
00078 {
00079     if(_the == NULL)
00080         _the = new FieldContainerFactory();
00081 
00082     return _the;
00083 }
00084 
00085 /*-------------------------------------------------------------------------*/
00086 /*                               Types                                     */
00087 
00088 FieldContainerType *FieldContainerFactory::findType(UInt32 uiTypeId) const
00089 {
00090     TypeIdMapConstIt  typeIt;
00091     FieldContainerType    *pType = NULL;
00092 
00093     if(_pTypeIdMap)
00094     {
00095         typeIt = _pTypeIdMap->find(uiTypeId);
00096         pType   = (typeIt == _pTypeIdMap->end()) ? NULL : (*typeIt).second;
00097     }
00098 
00099     return pType;
00100 }
00101 
00102 FieldContainerType *FieldContainerFactory::findType(const Char8 *szName) const
00103 {
00104     TypeNameMapCnstIt   typeIt;
00105     FieldContainerType *pType = NULL;
00106 
00107     if(_pTypeNameMap)
00108     {
00109         typeIt = _pTypeNameMap->find(IDStringLink(szName));
00110         pType  = (typeIt == _pTypeNameMap->end()) ? NULL : (*typeIt).second;
00111     }
00112 
00113     return pType;
00114 }
00115 
00116 UInt32 FieldContainerFactory::getNumTypes(void) const
00117 {
00118     return _pTypeNameMap ? _pTypeNameMap->size() : 0;
00119 }
00120 
00121 FieldContainerType *FieldContainerFactory::findUninitializedType(
00122     const Char8  *szName) const
00123 {
00124     FieldContainerType *returnValue = NULL;
00125 
00126     if(_pUnitTypesStore == NULL || szName == NULL)
00127         return returnValue;
00128 
00129     for(UInt32 i = 0; i < _pUnitTypesStore->size(); i++)
00130     {
00131         if(stringcmp(szName, (*_pUnitTypesStore)[i]->getCName()) == 0)
00132         {
00133             returnValue = (*_pUnitTypesStore)[i];
00134             break;
00135         }
00136     }
00137 
00138     return returnValue;
00139 }
00140 
00141 #ifdef OSG_WIN32_ICL
00142 #pragma warning (disable : 383)
00143 #endif
00144 
00145 bool FieldContainerFactory::initializePendingTypes(void)
00146 {
00147     bool                returnValue = true;
00148     FieldContainerType *pType       = NULL;
00149 
00150     if(_bInitialized == false)
00151         return false;
00152 
00153     SINFO << "OSGFieldContainerFactory init pending types" << std::endl;
00154 
00155     if(_pUnitTypesStore != NULL)
00156     {
00157         if(_pMapLock != NULL)
00158             _pMapLock->aquire();
00159 
00160         UninitTypeStoreIt uninitIt = _pUnitTypesStore->begin();
00161 
00162         while(uninitIt != _pUnitTypesStore->end())
00163         {
00164             pType = *uninitIt;
00165 
00166             if(pType->isInitialized() == true)
00167             {
00168                 uninitIt = _pUnitTypesStore->erase(uninitIt);
00169 
00170 //                (*_pTypeIdMap  )[pType->getId()                 ] = pType;
00171 
00172                 TypeIdMap::value_type val(pType->getId(), pType);
00173 
00174                 _pTypeIdMap->insert(val);
00175 
00176                 (*_pTypeNameMap)[IDStringLink(pType->getCName())] = pType;
00177             }
00178             else
00179             {
00180                 if(pType->initialize() == true)
00181                 {
00182                     uninitIt = _pUnitTypesStore->erase(uninitIt);
00183 
00184 //                  (*_pTypeIdMap  )[pType->getId()                 ] = pType;
00185 
00186                     TypeIdMap::value_type val(pType->getId(), pType);
00187                     
00188                     _pTypeIdMap->insert(val);
00189 
00190                     (*_pTypeNameMap)[IDStringLink(pType->getCName())] = pType;
00191                 }
00192                 else
00193                 {
00194                     returnValue = false;
00195 
00196                     uninitIt++;
00197                 }
00198             }
00199         }
00200 
00201         if(_pMapLock != NULL)
00202             _pMapLock->release();
00203 
00204         PINFO << "("
00205                  << returnValue
00206                  << "|"
00207                  << _pUnitTypesStore->size()
00208                  << ")"
00209                  << std::endl;
00210     }
00211 
00212     return returnValue;
00213 }
00214 
00215 #ifdef OSG_WIN32_ICL
00216 #pragma warning (default : 383)
00217 #endif
00218 
00219 FieldContainerFactory::TypeMapIterator FieldContainerFactory::beginTypes(void)
00220 {
00221     TypeMapIterator returnValue = _defaultTypeMapIt;
00222 
00223     if(_pTypeIdMap != NULL)
00224     {
00225         returnValue = _pTypeIdMap->begin();
00226     }
00227 
00228     return returnValue;
00229 }
00230 
00231 FieldContainerFactory::TypeMapIterator FieldContainerFactory::endTypes(void)
00232 {
00233     TypeMapIterator returnValue = _defaultTypeMapIt;
00234 
00235     if(_pTypeIdMap != NULL)
00236     {
00237         returnValue = _pTypeIdMap->end();
00238     }
00239 
00240     return returnValue;
00241 }
00242 
00243 
00244 /*-------------------------------------------------------------------------*/
00245 /*                               Groups                                    */
00246 
00247 UInt16 FieldContainerFactory::findGroupId(const Char8 *szName) const
00248 {
00249     GroupMapConstIt gIt;
00250 
00251     if (_pGroupMap)
00252     {
00253         gIt = _pGroupMap->find(IDStringLink(szName));
00254         return ((gIt == _pGroupMap->end()) ? 0 : (*gIt).second);
00255     }
00256 
00257     return 0;
00258 }
00259 
00260 const Char8 *FieldContainerFactory::findGroupName(UInt16 uiGroupId) const
00261 {
00262     GroupMapConstIt gIt;
00263 
00264     for(gIt = _pGroupMap->begin(); gIt != _pGroupMap->end(); gIt++)
00265     {
00266         if((*gIt).second == uiGroupId)
00267             return (*gIt).first.str();
00268     }
00269 
00270     return NULL;
00271 }
00272 
00273 UInt16 FieldContainerFactory::getNumGroups (void) const
00274 {
00275     return _pGroupMap ? _pGroupMap->size() : 0;
00276 }
00277 
00278 
00279 /*-------------------------------------------------------------------------*/
00280 /*                               Create                                    */
00281 
00282 FieldContainerPtr FieldContainerFactory::createFieldContainer(
00283     const Char8 *name) const
00284 {
00285     FieldContainerPtr returnValue;
00286 
00287     const FieldContainerType *pType = findType(name);
00288 
00289     if(pType != NULL)
00290         returnValue = pType->createFieldContainer();
00291 
00292     return returnValue;
00293 }
00294 
00295 NodePtr FieldContainerFactory::createNode(const Char8 *name) const
00296 {
00297     NodePtr returnValue;
00298 
00299     const FieldContainerType *pType = findType(name);
00300 
00301     if(pType != NULL)
00302         returnValue = pType->createNode();
00303 
00304     return returnValue;
00305 }
00306 
00307 NodeCorePtr FieldContainerFactory::createNodeCore(
00308     const Char8 *name) const
00309 {
00310     NodeCorePtr returnValue;
00311 
00312     const FieldContainerType *pType = findType(name);
00313 
00314     if(pType != NULL)
00315         returnValue = pType->createNodeCore();
00316 
00317     return returnValue;
00318 }
00319 
00320 AttachmentPtr FieldContainerFactory::createAttachment(
00321     const Char8 *name) const
00322 {
00323     AttachmentPtr returnValue;
00324 
00325     const FieldContainerType *pType = findType(name);
00326 
00327     if(pType != NULL)
00328         returnValue = pType->createAttachment();
00329 
00330     return returnValue;
00331 }
00332 
00333 /*-------------------------------------------------------------------------*/
00334 /*                            Write FCD                                    */
00335 
00336 /* type output */
00337 /* name given: output only the given type,
00338    out given: output all types into the stream,
00339    no name, no out: output all types into separate files
00340 */
00341 
00342 void FieldContainerFactory::writeFCD(Char8 * name, std::ostream *out)
00343 {
00344           TypeIdMapIt         type;
00345     const FieldContainerType *pType = NULL;
00346 
00347     if(_pTypeIdMap == NULL)
00348         return;
00349 
00350     if(name != NULL)
00351     {
00352         pType  = findType(name);
00353 
00354         if(pType == NULL)
00355         {
00356             SWARNING << "FieldContainerFactory::writeFCD: type " << name
00357                      << " is unknown!" << std::endl;
00358             return;
00359         }
00360 
00361         if(out != NULL)
00362         {
00363             writeSingleTypeFCD(*out, pType);
00364         }
00365         else
00366         {
00367             std::string s(pType->getCName());
00368 
00369             s.append(".fcd");
00370 
00371             std::ofstream f(s.c_str());
00372 
00373             writeSingleTypeFCD(f, pType);
00374         }
00375 
00376         return;
00377     }
00378 
00379     // write header once?
00380     if(out != NULL)
00381     {
00382         *out << "<?xml version=\"1.0\" ?>" << std::endl << std::endl;
00383     }
00384 
00385     for(  type  = _pTypeIdMap->begin();
00386           type != _pTypeIdMap->end  ();
00387         ++type)
00388     {
00389         if(out != NULL)
00390         {
00391             writeSingleTypeFCD(*out, (*type).second);
00392         }
00393         else
00394         {
00395             std::string s((*type).second->getCName());
00396 
00397             s.append(".fcd");
00398 
00399             std::ofstream f(s.c_str());
00400 
00401             f << "<?xml version=\"1.0\" ?>" << std::endl << std::endl;
00402 
00403             writeSingleTypeFCD(f, (*type).second);
00404         }
00405 
00406         if(out != NULL)
00407         {
00408             *out << std::endl;
00409         }
00410     }
00411 }
00412 
00413 /*-------------------------------------------------------------------------*/
00414 /*                                Get                                      */
00415 
00416 const FieldContainerFactory::FieldContainerStore *
00417     FieldContainerFactory::getFieldContainerStore(void) const
00418 {
00419     return _pFieldContainerStore;
00420 }
00421 
00422 
00423 /*-------------------------------------------------------------------------*/
00424 /*                            Static Init                                  */
00425 
00426 bool FieldContainerFactory::initializeFactory(void)
00427 {
00428     bool returnValue = the()->initialize();
00429 
00430     // CHECKCHECK
00431     // clear changelist from prototypes, move this to a different place soon
00432     OSG::Thread::getCurrentChangeList()->clearAll();
00433 
00434     return returnValue;
00435 }
00436 
00437 bool FieldContainerFactory::terminateFactory(void)
00438 {
00439     return the()->terminate();
00440 }
00441 
00442 /*-------------------------------------------------------------------------*/
00443 /*                            Constructors                                 */
00444 
00445 FieldContainerFactory::FieldContainerFactory(void) :
00446     _bInitialized        (false),
00447     _pTypeIdMap          (NULL ),
00448     _pTypeNameMap        (NULL ),
00449     _pGroupMap           (NULL ),
00450     _pUnitTypesStore     (NULL ),
00451     _pFieldContainerStore(NULL ),
00452     _pStoreLock          (NULL ),
00453     _pMapLock            (NULL ),
00454     _pMapper             (NULL )
00455 {
00456     addInitFunction      (&FieldContainerPtr::initialize           );
00457     addInitFunction      (&FieldContainerFactory::initializeFactory);
00458 
00459     addSystemExitFunction(&FieldContainerPtr::terminate            );
00460     addSystemExitFunction(&FieldContainerFactory::terminateFactory );
00461 
00462     initTypeMap();
00463 }
00464 
00465 /*-------------------------------------------------------------------------*/
00466 /*                             Destructor                                  */
00467 
00468 FieldContainerFactory::~FieldContainerFactory(void)
00469 {
00470 }
00471 
00472 /*-------------------------------------------------------------------------*/
00473 /*                                Init                                     */
00474 
00475 bool FieldContainerFactory::initialize(void)
00476 {
00477     TypeIdMapIt typeIt;
00478 
00479     if(_bInitialized == true)
00480         return true;
00481 
00482     SINFO << "init singleton FieldContainerFactory" << std::endl;
00483 
00484     _pStoreLock = ThreadManager::the()->getLock(
00485         "OSGFieldContainerFactory::_pStoreLock");
00486 
00487     addRefP(_pStoreLock);
00488 
00489     _pMapLock   = ThreadManager::the()->getLock(
00490         "OSGFieldContainerFactory::_pMaoLock");
00491 
00492     addRefP(_pMapLock);
00493 
00494     FDEBUG( ("Got shore lock %p, Got map %p",
00495              _pStoreLock, _pMapLock) );
00496 
00497     _bInitialized = true;
00498 
00499     initializePendingTypes();
00500 
00501     return _pStoreLock != NULL && _pMapLock != NULL;
00502 }
00503 
00504 bool FieldContainerFactory::terminate(void)
00505 {
00506     TypeIdMapIt typeIt;
00507 
00508     SINFO << "terminate singleton FieldContainerFactory" << std::endl;
00509 
00510     if(_bInitialized == false)
00511         return true;
00512 
00513     if(_pTypeIdMap != NULL)
00514     {
00515         int i = 0;
00516         for(  typeIt  = _pTypeIdMap->begin();
00517               typeIt != _pTypeIdMap->end();
00518             ++typeIt)
00519         {
00520             (*typeIt).second->terminate();
00521 
00522             i++;
00523         }
00524     }
00525 
00526     subRefP(_pStoreLock);
00527     subRefP(_pMapLock);
00528 
00529     _bInitialized = false;
00530 
00531     return true;
00532 }
00533 
00534 void FieldContainerFactory::initTypeMap(void)
00535 {
00536     if(_pTypeIdMap   == NULL &&
00537        _pTypeNameMap == NULL)
00538     {
00539         _pTypeIdMap      = new TypeIdMap;
00540         _pTypeNameMap    = new TypeNameMap;
00541         _pGroupMap       = new GroupMap;
00542         _pUnitTypesStore = new UninitializedTypeStore;
00543     }
00544 }
00545 
00546 /*-------------------------------------------------------------------------*/
00547 /*                              Register                                   */
00548 
00549 UInt32 FieldContainerFactory::registerType(FieldContainerType *pType)
00550 {
00551     UInt32 returnValue = 0;
00552 
00553     if(_pMapLock != NULL)
00554         _pMapLock->aquire();
00555 
00556     if(pType->getId() != 0)
00557     {
00558         _pUnitTypesStore->push_back(pType);
00559     }
00560 
00561     if(_pMapLock != NULL)
00562         _pMapLock->release();
00563 
00564     return returnValue;
00565 }
00566 
00567 UInt16 FieldContainerFactory::registerGroup(const Char8 *szName)
00568 {
00569     UInt16 returnValue;
00570 
00571     if(szName == NULL || *szName == '\0')
00572     {
00573         SWARNING << "Group without name" << std::endl;
00574         return 0;
00575     }
00576 
00577     returnValue = findGroupId(szName);
00578 
00579     if(returnValue == 0)
00580     {
00581         if(_pMapLock != NULL)
00582             _pMapLock->aquire();
00583 
00584         returnValue                         = _pGroupMap->size() + 1;
00585 
00586         (*_pGroupMap)[IDStringLink(szName)] = returnValue;
00587 
00588         if(_pMapLock != NULL)
00589             _pMapLock->release();
00590     }
00591 
00592     return returnValue;
00593 }
00594 
00595 void FieldContainerFactory::unregisterType(FieldContainerType *pType)
00596 {
00597     TypeIdMapIt   typeIdIt;
00598     TypeNameMapIt typeNameIt;
00599 
00600     if(pType == NULL)
00601         return;
00602 
00603     if(_pTypeIdMap)
00604     {
00605         UInt32 uiId =  pType->getId();
00606 
00607         typeIdIt    = _pTypeIdMap->find(uiId);
00608 
00609         if(typeIdIt != _pTypeIdMap->end())
00610         {
00611             _pTypeIdMap->erase(typeIdIt);
00612         }
00613     }
00614 
00615     if(_pTypeNameMap)
00616     {
00617         typeNameIt = _pTypeNameMap->find(IDStringLink(pType->getCName()));
00618 
00619         if(typeNameIt != _pTypeNameMap->end())
00620         {
00621             _pTypeNameMap->erase(typeNameIt);
00622         }
00623     }
00624 }
00625 
00626 /*-------------------------------------------------------------------------*/
00627 /*                      Write Single FCD                                   */
00628 
00629 void FieldContainerFactory::writeSingleTypeFCD(      std::ostream       &out, 
00630                                                const FieldContainerType *t  )
00631 {
00632     FieldContainerType *parent = t->getParent();
00633 
00634     out << "<FieldContainer"                          << std::endl;
00635     out << "\tname=\""       << t->getCName() << "\"" << std::endl;
00636 
00637     if(parent != NULL)
00638         out << "\tparent=\"" << parent->getCName() << "\"" << std::endl;
00639     
00640     out << "\tlibrary=\""
00641         << "???"
00642         << "\"" 
00643         << std::endl;
00644     out << "\tstructure=\"" 
00645         << ( t->isAbstract()?"abstract":"concrete" ) 
00646         << "\""
00647         << std::endl;
00648 
00649     // look for pointerfield types
00650            std::string s;
00651            Int32       pt        = 0;
00652     static Char8 *pftypes[] = {"none", "single", "multi", "both"};
00653 
00654     s  = "SF";
00655     s += t->getCName();
00656     s += "Ptr";
00657 
00658     if(FieldFactory::the().getFieldType(s.c_str()) != NULL)
00659     {
00660         pt |= 1;
00661     }
00662 
00663     s  = "MF";
00664     s += t->getCName();
00665     s += "Ptr";
00666     
00667     if(FieldFactory::the().getFieldType(s.c_str()) != NULL)
00668     {
00669         pt |= 2;
00670     }
00671 
00672     out << "\tpointerfieldtypes=\"" << pftypes[pt] << "\"" << std::endl;
00673     out << ">"                                             << std::endl;
00674 
00675     // Print the fields in this FC, ignore the parents' fields
00676     // !!! This should start at 0, FIX ME
00677 
00678     for(UInt32 i  = parent ? parent->getNumFieldDescs() + 1 : 1;
00679                i <= t->getNumFieldDescs();
00680                i++)
00681     {
00682         const FieldDescription *f  = t->getFieldDescription(i);
00683               FieldType        *ft = NULL;
00684 
00685         ft = FieldFactory::the().getFieldType(f->getTypeId());
00686 
00687         out << "\t<Field"                             << std::endl;
00688         out << "\t\tname=\"" << f->getCName() << "\"" << std::endl;
00689 
00690         // Filter the SF/MF from the type
00691         const Char8 *c = ft->getCName();
00692 
00693         if (! strncmp(c, "SF", 2) || ! strncmp(c, "MF", 2))
00694         {
00695             c += 2;
00696         }
00697 
00698         out << "\t\ttype=\"" << c << "\"" << std::endl;
00699 
00700         out << "\t\tcardinality=\""
00701             << (ft->getCardinality() ? "multi" : "single")
00702             << "\"" << std::endl;
00703 
00704         out << "\t\tvisibility=\"" 
00705             << (f->isInternal() ? "internal" : "external")
00706             << "\"" 
00707             << std::endl;
00708         
00709         out << "\t>"        << std::endl;
00710         out << "\t</Field>" << std::endl;
00711     }
00712 
00713     out << "</FieldContainer>" << std::endl;
00714 }
00715 
00716 
00717 /*-------------------------------------------------------------------------*/
00718 /*                              cvs id's                                   */
00719 
00720 #ifdef __sgi
00721 #pragma set woff 1174
00722 #endif
00723 
00724 #ifdef OSG_LINUX_ICC
00725 #pragma warning( disable : 177 )
00726 #endif
00727 
00728 namespace
00729 {
00730     static Char8 cvsid_cpp[] = "@(#)$Id: $";
00731     static Char8 cvsid_hpp[] = OSGFIELDCONTAINERFACTORY_HEADER_CVSID;
00732 }

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