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
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
00069
00070
00071
00072
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
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
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
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
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
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
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
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 }