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
00026
00027
00028
00029
00030
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
00076
00077 FieldContainerFactory *FieldContainerFactory::the(void)
00078 {
00079 if(_the == NULL)
00080 _the = new FieldContainerFactory();
00081
00082 return _the;
00083 }
00084
00085
00086
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
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
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
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
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
00335
00336
00337
00338
00339
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
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
00415
00416 const FieldContainerFactory::FieldContainerStore *
00417 FieldContainerFactory::getFieldContainerStore(void) const
00418 {
00419 return _pFieldContainerStore;
00420 }
00421
00422
00423
00424
00425
00426 bool FieldContainerFactory::initializeFactory(void)
00427 {
00428 bool returnValue = the()->initialize();
00429
00430
00431
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
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
00467
00468 FieldContainerFactory::~FieldContainerFactory(void)
00469 {
00470 }
00471
00472
00473
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
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
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
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
00676
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
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
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 }