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 "OSGChangeList.h"
00053 #include "OSGThread.h"
00054 #include "OSGThreadManager.h"
00055 #include "OSGLog.h"
00056 #include "OSGFieldContainerFactory.h"
00057 #include <OSGFieldContainerPtr.h>
00058 #include "OSGRemoteAspect.h"
00059
00060 OSG_USING_NAMESPACE
00061
00062 bool ChangeList::_bReadWriteDefault = false;
00063
00064
00065
00066
00067 ChangeList::ChangeList(void) :
00068 Inherited ( ),
00069 _bReadOnly (!_bReadWriteDefault),
00070 _uiAspectId (Thread::getAspect()),
00071 _listMode (Public ),
00072 _vChangedFieldContainers ( ),
00073 _vAddRefdFieldContainers ( ),
00074 _vSubRefdFieldContainers ( ),
00075 _vCreatedFieldContainers ( ),
00076 _vDestroyedFieldContainers( )
00077 {
00078
00079 }
00080
00081
00082
00083
00084 ChangeList::~ChangeList(void)
00085 {
00086 }
00087
00088
00089
00090
00091 ChangeList::changed_size_type ChangeList::sizeChanged(void)
00092 {
00093 return _vChangedFieldContainers.size();
00094 }
00095
00096 ChangeList::changed_const_iterator ChangeList::beginChanged(void) const
00097 {
00098 return _vChangedFieldContainers.begin();
00099 }
00100
00101 ChangeList::changed_const_iterator ChangeList::endChanged(void) const
00102 {
00103 return _vChangedFieldContainers.end();
00104 }
00105
00106 ChangeList::refd_size_type ChangeList::sizeAddRefd(void)
00107 {
00108 return _vAddRefdFieldContainers.size();
00109 }
00110
00111 ChangeList::refd_const_iterator ChangeList::beginAddRefd(void) const
00112 {
00113 return _vAddRefdFieldContainers.begin();
00114 }
00115
00116 ChangeList::refd_const_iterator ChangeList::endAddRefd(void) const
00117 {
00118 return _vAddRefdFieldContainers.end();
00119 }
00120
00121 ChangeList::refd_size_type ChangeList::sizeSubRefd(void)
00122 {
00123 return _vSubRefdFieldContainers.size();
00124 }
00125
00126 ChangeList::refd_const_iterator ChangeList::beginSubRefd(void) const
00127 {
00128 return _vSubRefdFieldContainers.begin();
00129 }
00130
00131 ChangeList::refd_const_iterator ChangeList::endSubRefd(void) const
00132 {
00133 return _vSubRefdFieldContainers.end();
00134 }
00135
00136 ChangeList::idrefd_const_iterator ChangeList::beginCreated(void) const
00137 {
00138 return _vCreatedFieldContainers.begin();
00139 }
00140
00141 ChangeList::idrefd_const_iterator ChangeList::endCreated(void) const
00142 {
00143 return _vCreatedFieldContainers.end();
00144 }
00145
00146 ChangeList::idrefd_size_type ChangeList::sizeCreated(void) const
00147 {
00148 return _vCreatedFieldContainers.size();
00149 }
00150
00151 ChangeList::idrefd_const_iterator ChangeList::beginDestroyed(void) const
00152 {
00153 return _vDestroyedFieldContainers.begin();
00154 }
00155
00156 ChangeList::idrefd_const_iterator ChangeList::endDestroyed(void) const
00157 {
00158 return _vDestroyedFieldContainers.end();
00159 }
00160
00161 ChangeList::idrefd_size_type ChangeList::sizeDestroyed(void) const
00162 {
00163 return _vDestroyedFieldContainers.size();
00164 }
00165
00166
00167
00168
00169 void ChangeList::addChanged(const FieldContainerPtr &pFieldContainer,
00170 BitVector bvWhichField)
00171 {
00172 if(_bReadOnly == true)
00173 return;
00174
00175 UInt32 uiContainerId(pFieldContainer.getFieldContainerId());
00176
00177 ChangeEntry tmpEntry (uiContainerId, bvWhichField);
00178
00179 try
00180 {
00181 _vChangedFieldContainers.push_back(tmpEntry);
00182 }
00183
00184
00185 catch(...)
00186 {
00187
00188
00189
00190 std::vector<ChangeEntry>::size_type oldSize = _vChangedFieldContainers.size();
00191 SWARNING << "Compacting ChangeList ..." << std::endl;
00192
00193 RemoteAspect::storeChangeList(this);
00194 clearAll();
00195 RemoteAspect::restoreChangeList(this);
00196 SWARNING << "Compacted ChangeList from " << oldSize
00197 << " to " << _vChangedFieldContainers.size() << " entries." << std::endl;
00198 _vChangedFieldContainers.push_back(tmpEntry);
00199 }
00200 }
00201
00202 void ChangeList::addAddRefd(const FieldContainerPtr &pFieldContainer)
00203 {
00204 if(_bReadOnly == true)
00205 return;
00206
00207 UInt32 uiContainerId = pFieldContainer.getFieldContainerId();
00208
00209 _vAddRefdFieldContainers.push_back(uiContainerId);
00210 }
00211
00212 void ChangeList::addSubRefd(const FieldContainerPtr &pFieldContainer)
00213 {
00214 #if !defined(OSG_FIXED_MFIELDSYNC)
00215 if(_bReadOnly == true)
00216 return;
00217 #endif
00218
00219 UInt32 uiContainerId = pFieldContainer.getFieldContainerId();
00220
00221 _vSubRefdFieldContainers.push_back(uiContainerId);
00222 }
00223
00224 void ChangeList::addCreated (const UInt32 uiContainerId)
00225 {
00226 if(_bReadOnly == true)
00227 return;
00228
00229 _vCreatedFieldContainers.push_back(uiContainerId);
00230 }
00231
00232 void ChangeList::addDestroyed(const UInt32 uiContainerId)
00233 {
00234 if(_bReadOnly == true)
00235 return;
00236
00237 _vDestroyedFieldContainers.push_back(uiContainerId);
00238 }
00239
00240
00241
00242
00243 void ChangeList::clearAll(void)
00244 {
00245 _vChangedFieldContainers.clear();
00246 _vAddRefdFieldContainers.clear();
00247 _vSubRefdFieldContainers.clear();
00248
00249 _vCreatedFieldContainers .clear();
00250 _vDestroyedFieldContainers.clear();
00251 }
00252
00253 void ChangeList::swap(ChangeList &clist)
00254 {
00255 _vChangedFieldContainers.swap(clist._vChangedFieldContainers);
00256 _vAddRefdFieldContainers.swap(clist._vAddRefdFieldContainers);
00257 _vSubRefdFieldContainers.swap(clist._vSubRefdFieldContainers);
00258 _vCreatedFieldContainers.swap(clist._vCreatedFieldContainers);
00259 _vDestroyedFieldContainers.swap(clist._vDestroyedFieldContainers);
00260 }
00261
00262 bool ChangeList::merge(const ChangeList &clist)
00263 {
00264 bool returnValue = true;
00265
00266 _vChangedFieldContainers.insert(_vChangedFieldContainers.end(),
00267 clist.beginChanged(),
00268 clist.endChanged());
00269
00270
00271 _vAddRefdFieldContainers.insert(_vAddRefdFieldContainers.end(),
00272 clist.beginAddRefd(),
00273 clist.endAddRefd());
00274
00275
00276 _vSubRefdFieldContainers.insert(_vSubRefdFieldContainers.end(),
00277 clist.beginSubRefd(),
00278 clist.endSubRefd());
00279
00280 _vCreatedFieldContainers.insert(_vCreatedFieldContainers.end(),
00281 clist.beginCreated(),
00282 clist.endCreated());
00283
00284 _vDestroyedFieldContainers.insert(_vDestroyedFieldContainers.end(),
00285 clist.beginDestroyed(),
00286 clist.endDestroyed());
00287
00288 return returnValue;
00289 }
00290
00291 bool ChangeList::empty() const
00292 {
00293 return _vChangedFieldContainers.empty() &&
00294 _vAddRefdFieldContainers.empty() &&
00295 _vSubRefdFieldContainers.empty() &&
00296 _vCreatedFieldContainers.empty() &&
00297 _vDestroyedFieldContainers.empty();
00298 }
00299
00300 void ChangeList::setAspect(UInt32 uiAspectId)
00301 {
00302 if(_vChangedFieldContainers.size() != 0 ||
00303 _vAddRefdFieldContainers.size() != 0 ||
00304 _vSubRefdFieldContainers.size() != 0)
00305 {
00306 SWARNING << "Changing aspect on non empty changelist, all currrent "
00307 << "entries will be lost" << std::endl;
00308 }
00309
00310 clearAll();
00311
00312
00313
00314 _uiAspectId = uiAspectId;
00315 }
00316
00317 void ChangeList::setReadOnly(bool bReadOnly)
00318 {
00319 _bReadOnly = bReadOnly;
00320 }
00321
00330 void ChangeList::setReadWriteDefault(bool bReadWrite)
00331 {
00332 if(GlobalSystemState != Startup)
00333 FWARNING(("setReadWriteDefault: called after startup!\n"));
00334
00335 _bReadWriteDefault = bReadWrite;
00336 }
00337
00338
00339
00340
00341 #ifndef OSG_DISABLE_DEPRECATED
00342
00343 void ChangeList::applyTo(UInt32 uiAspectId)
00344 {
00345 UInt32 i;
00346
00347 if(uiAspectId == _uiAspectId)
00348 {
00349 SWARNING << "Sync on the same aspect, ignored " << std::endl;
00350 return;
00351 }
00352
00353 if(uiAspectId >= ThreadManager::getNumAspects())
00354 {
00355 SWARNING << "Invalid AspectId" << std::endl;
00356 }
00357
00358 _bReadOnly = true;
00359 OSG::Thread::getCurrentChangeList()->setReadOnly(true);
00360
00361 FieldContainerPtr pTmp;
00362
00363 for(i = 0; i < _vChangedFieldContainers.size(); i++)
00364 {
00365 pTmp = FieldContainerFactory::the()->getContainer(
00366 _vChangedFieldContainers[i].first);
00367
00368 if(pTmp == NullFC)
00369 continue;
00370
00371 pTmp.executeSync(_uiAspectId,
00372 uiAspectId,
00373 _vChangedFieldContainers[i].second);
00374 }
00375
00376 for(i = 0; i < _vAddRefdFieldContainers.size(); i++)
00377 {
00378 pTmp = FieldContainerFactory::the()->getContainer(
00379 _vAddRefdFieldContainers[i]);
00380
00381 if(pTmp == NullFC)
00382 continue;
00383
00384 addRefCP(pTmp);
00385 }
00386
00387 for(i = 0; i < _vSubRefdFieldContainers.size(); i++)
00388 {
00389 pTmp = FieldContainerFactory::the()->getContainer(
00390 _vSubRefdFieldContainers[i]);
00391
00392 if(pTmp == NullFC)
00393 continue;
00394
00395 subRefCP(pTmp);
00396 }
00397
00398 clearAll();
00399
00400 _bReadOnly = false;
00401 OSG::Thread::getCurrentChangeList()->setReadOnly(false);
00402
00403 }
00404
00405 void ChangeList::applyToCurrent(void)
00406 {
00407 applyTo(Thread::getAspect());
00408 }
00409
00410 #endif
00411
00412 void ChangeList::apply(void)
00413 {
00414 UInt32 i;
00415
00416 if(OSG::Thread::getCurrentChangeList() == this)
00417 {
00418 SWARNING << "try to apply current changelist : ignored" << std::endl;
00419 }
00420
00421 _bReadOnly = true;
00422
00423 OSG::Thread::getCurrentChangeList()->setReadOnly(true);
00424
00425 FieldContainerPtr pTmp;
00426
00427 for(i = 0; i < _vChangedFieldContainers.size(); i++)
00428 {
00429 pTmp = FieldContainerFactory::the()->getContainer(
00430 _vChangedFieldContainers[i].first);
00431
00432 if(pTmp == NullFC)
00433 continue;
00434
00435 pTmp.executeSync(_uiAspectId,
00436 Thread::getAspect(),
00437 _vChangedFieldContainers[i].second);
00438 }
00439
00440 #if !defined(OSG_FIXED_MFIELDSYNC)
00441 for(i = 0; i < _vAddRefdFieldContainers.size(); i++)
00442 {
00443 pTmp = FieldContainerFactory::the()->getContainer(
00444 _vAddRefdFieldContainers[i]);
00445
00446 if(pTmp == NullFC)
00447 continue;
00448
00449 addRefCP(pTmp);
00450 }
00451
00452 for(i = 0; i < _vSubRefdFieldContainers.size(); i++)
00453 {
00454 pTmp = FieldContainerFactory::the()->getContainer(
00455 _vSubRefdFieldContainers[i]);
00456
00457 if(pTmp == NullFC)
00458 continue;
00459
00460 subRefCP(pTmp);
00461 }
00462 #endif
00463
00464 _bReadOnly = false;
00465
00466 OSG::Thread::getCurrentChangeList()->setReadOnly(false);
00467 }
00468
00469 #if defined(OSG_FIXED_MFIELDSYNC)
00470 void ChangeList::applySubRefs(void)
00471 {
00472 _bReadOnly = false;
00473
00474 OSG::Thread::getCurrentChangeList()->setReadOnly(false);
00475
00476 FieldContainerPtr pTmp;
00477
00478 std::vector<IdRefEntry> tmpList;
00479
00480 tmpList.swap(_vSubRefdFieldContainers);
00481
00482 while(tmpList.size() != 0)
00483 {
00484 _vSubRefdFieldContainers.clear();
00485
00486 for(UInt32 i = 0; i < tmpList.size(); i++)
00487 {
00488
00489
00490 pTmp = FieldContainerFactory::the()->getContainer(
00491 tmpList[i]);
00492
00493 if(pTmp == NullFC)
00494 continue;
00495
00496 pTmp.doSubRef();
00497 }
00498
00499 tmpList.clear();
00500 tmpList.swap(_vSubRefdFieldContainers);
00501 }
00502
00503 _bReadOnly = false;
00504
00505 OSG::Thread::getCurrentChangeList()->setReadOnly(false);
00506 }
00507 #endif
00508
00509 void ChangeList::applyAndClear(void)
00510 {
00511 apply ();
00512 clearAll();
00513 }
00514
00515
00516
00517
00518 void ChangeList::dump(void)
00519 {
00520 UInt32 i;
00521
00522 fprintf(stderr, "CL: %u\n", _uiAspectId);
00523 #if 0
00524 fprintf(stderr, "CLChanged:\n");
00525
00526 for(i = 0; i < _vChangedFieldContainers.size(); i++)
00527 {
00528
00529
00530 fprintf(stderr, "\t%u\n",
00531 _vChangedFieldContainers[i].first);
00532 }
00533 #endif
00534
00535 fprintf(stderr, "CLAdd:\n");
00536 for(i = 0; i < _vAddRefdFieldContainers.size(); i++)
00537 {
00538
00539
00540 fprintf(stderr, "\t%u\n",
00541 _vAddRefdFieldContainers[i]);
00542 }
00543
00544 fprintf(stderr, "CLSub:\n");
00545 for(i = 0; i < _vSubRefdFieldContainers.size(); i++)
00546 {
00547
00548
00549 fprintf(stderr, "\t%u\n",
00550 _vSubRefdFieldContainers[i]);
00551 }
00552
00553 fprintf(stderr, "CLCreate:\n");
00554 for(i = 0; i < _vCreatedFieldContainers.size(); i++)
00555 {
00556 fprintf(stderr, "\t%u | ", _vCreatedFieldContainers[i]);
00557
00558 FieldContainerPtr pTmp = FieldContainerFactory::the()->getContainer(
00559 _vCreatedFieldContainers[i]);
00560
00561 if(pTmp != NullFC)
00562 {
00563 fprintf(stderr, "%s\n", pTmp->getType().getCName());
00564 }
00565 else
00566 {
00567 fprintf(stderr, "\n");
00568 }
00569 }
00570
00571 fprintf(stderr, "CLDestroy:\n");
00572 for(i = 0; i < _vDestroyedFieldContainers.size(); i++)
00573 {
00574 fprintf(stderr, "\t%u\n", _vDestroyedFieldContainers[i]);
00575 }
00576 }
00577
00578
00579
00580
00581
00582 #ifdef __sgi
00583 #pragma set woff 1174
00584 #endif
00585
00586 #ifdef OSG_LINUX_ICC
00587 #pragma warning( disable : 177 )
00588 #endif
00589
00590 namespace
00591 {
00592 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00593 static Char8 cvsid_hpp[] = OSGCHANGELIST_HEADER_CVSID;
00594 }