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(_bReadOnly == true)
00215 return;
00216
00217 UInt32 uiContainerId = pFieldContainer.getFieldContainerId();
00218
00219 _vSubRefdFieldContainers.push_back(uiContainerId);
00220 }
00221
00222 void ChangeList::addCreated (const UInt32 uiContainerId)
00223 {
00224 if(_bReadOnly == true)
00225 return;
00226
00227 _vCreatedFieldContainers.push_back(uiContainerId);
00228 }
00229
00230 void ChangeList::addDestroyed(const UInt32 uiContainerId)
00231 {
00232 if(_bReadOnly == true)
00233 return;
00234
00235 _vDestroyedFieldContainers.push_back(uiContainerId);
00236 }
00237
00238
00239
00240
00241 void ChangeList::clearAll(void)
00242 {
00243 _vChangedFieldContainers.clear();
00244 _vAddRefdFieldContainers.clear();
00245 _vSubRefdFieldContainers.clear();
00246
00247 _vCreatedFieldContainers .clear();
00248 _vDestroyedFieldContainers.clear();
00249 }
00250
00251 bool ChangeList::merge(const ChangeList &clist)
00252 {
00253 bool returnValue = true;
00254
00255 _vChangedFieldContainers.insert(_vChangedFieldContainers.end(),
00256 clist.beginChanged(),
00257 clist.endChanged());
00258
00259
00260 _vAddRefdFieldContainers.insert(_vAddRefdFieldContainers.end(),
00261 clist.beginAddRefd(),
00262 clist.endAddRefd());
00263
00264
00265 _vSubRefdFieldContainers.insert(_vSubRefdFieldContainers.end(),
00266 clist.beginSubRefd(),
00267 clist.endSubRefd());
00268
00269 _vCreatedFieldContainers.insert(_vCreatedFieldContainers.end(),
00270 clist.beginCreated(),
00271 clist.endCreated());
00272
00273 _vDestroyedFieldContainers.insert(_vDestroyedFieldContainers.end(),
00274 clist.beginDestroyed(),
00275 clist.endDestroyed());
00276
00277 return returnValue;
00278 }
00279
00280 void ChangeList::setAspect(UInt32 uiAspectId)
00281 {
00282 if(_vChangedFieldContainers.size() != 0 ||
00283 _vAddRefdFieldContainers.size() != 0 ||
00284 _vSubRefdFieldContainers.size() != 0)
00285 {
00286 SWARNING << "Changing aspect on non empty changelist, all currrent "
00287 << "entries will be lost" << std::endl;
00288 }
00289
00290 clearAll();
00291
00292
00293
00294 _uiAspectId = uiAspectId;
00295 }
00296
00297 void ChangeList::setReadOnly(bool bReadOnly)
00298 {
00299 _bReadOnly = bReadOnly;
00300 }
00301
00310 void ChangeList::setReadWriteDefault(bool bReadWrite)
00311 {
00312 if(GlobalSystemState != Startup)
00313 FWARNING(("setReadWriteDefault: called after startup!\n"));
00314
00315 _bReadWriteDefault = bReadWrite;
00316 }
00317
00318
00319
00320
00321 #ifndef OSG_DISABLE_DEPRECATED
00322
00323 void ChangeList::applyTo(UInt32 uiAspectId)
00324 {
00325 UInt32 i;
00326
00327 if(uiAspectId == _uiAspectId)
00328 {
00329 SWARNING << "Sync on the same aspect, ignored " << std::endl;
00330 return;
00331 }
00332
00333 if(uiAspectId >= ThreadManager::getNumAspects())
00334 {
00335 SWARNING << "Invalid AspectId" << std::endl;
00336 }
00337
00338 _bReadOnly = true;
00339 OSG::Thread::getCurrentChangeList()->setReadOnly(true);
00340
00341 FieldContainerPtr pTmp;
00342
00343 for(i = 0; i < _vChangedFieldContainers.size(); i++)
00344 {
00345 pTmp = FieldContainerFactory::the()->getContainer(
00346 _vChangedFieldContainers[i].first);
00347
00348 if(pTmp == NullFC)
00349 continue;
00350
00351 pTmp.executeSync(_uiAspectId,
00352 uiAspectId,
00353 _vChangedFieldContainers[i].second);
00354 }
00355
00356 for(i = 0; i < _vAddRefdFieldContainers.size(); i++)
00357 {
00358 pTmp = FieldContainerFactory::the()->getContainer(
00359 _vAddRefdFieldContainers[i]);
00360
00361 if(pTmp == NullFC)
00362 continue;
00363
00364 addRefCP(pTmp);
00365 }
00366
00367 for(i = 0; i < _vSubRefdFieldContainers.size(); i++)
00368 {
00369 pTmp = FieldContainerFactory::the()->getContainer(
00370 _vSubRefdFieldContainers[i]);
00371
00372 if(pTmp == NullFC)
00373 continue;
00374
00375 subRefCP(pTmp);
00376 }
00377
00378 clearAll();
00379
00380 _bReadOnly = false;
00381 OSG::Thread::getCurrentChangeList()->setReadOnly(false);
00382
00383 }
00384
00385 void ChangeList::applyToCurrent(void)
00386 {
00387 applyTo(Thread::getAspect());
00388 }
00389
00390 #endif
00391
00392 void ChangeList::apply(void)
00393 {
00394 UInt32 i;
00395
00396 if(OSG::Thread::getCurrentChangeList() == this)
00397 {
00398 SWARNING << "try to apply current changelist : ignored" << std::endl;
00399 }
00400
00401 _bReadOnly = true;
00402
00403 OSG::Thread::getCurrentChangeList()->setReadOnly(true);
00404
00405 FieldContainerPtr pTmp;
00406
00407 for(i = 0; i < _vChangedFieldContainers.size(); i++)
00408 {
00409 pTmp = FieldContainerFactory::the()->getContainer(
00410 _vChangedFieldContainers[i].first);
00411
00412 if(pTmp == NullFC)
00413 continue;
00414
00415 pTmp.executeSync(_uiAspectId,
00416 Thread::getAspect(),
00417 _vChangedFieldContainers[i].second);
00418 }
00419
00420 for(i = 0; i < _vAddRefdFieldContainers.size(); i++)
00421 {
00422 pTmp = FieldContainerFactory::the()->getContainer(
00423 _vAddRefdFieldContainers[i]);
00424
00425 if(pTmp == NullFC)
00426 continue;
00427
00428 addRefCP(pTmp);
00429 }
00430
00431 for(i = 0; i < _vSubRefdFieldContainers.size(); i++)
00432 {
00433 pTmp = FieldContainerFactory::the()->getContainer(
00434 _vSubRefdFieldContainers[i]);
00435
00436 if(pTmp == NullFC)
00437 continue;
00438
00439 subRefCP(pTmp);
00440 }
00441
00442 _bReadOnly = false;
00443
00444 OSG::Thread::getCurrentChangeList()->setReadOnly(false);
00445 }
00446
00447 void ChangeList::applyAndClear(void)
00448 {
00449 apply ();
00450 clearAll();
00451 }
00452
00453
00454
00455
00456 void ChangeList::dump(void)
00457 {
00458 UInt32 i;
00459
00460 fprintf(stderr, "CL: %u\n", _uiAspectId);
00461 fprintf(stderr, "CLChanged:\n");
00462
00463 for(i = 0; i < _vChangedFieldContainers.size(); i++)
00464 {
00465
00466
00467 fprintf(stderr, "\t%u\n",
00468 _vChangedFieldContainers[i].first);
00469 }
00470
00471 fprintf(stderr, "CLAdd:\n");
00472 for(i = 0; i < _vAddRefdFieldContainers.size(); i++)
00473 {
00474
00475
00476 fprintf(stderr, "\t%u\n",
00477 _vAddRefdFieldContainers[i]);
00478 }
00479
00480 fprintf(stderr, "CLSub:\n");
00481 for(i = 0; i < _vSubRefdFieldContainers.size(); i++)
00482 {
00483
00484
00485 fprintf(stderr, "\t%u\n",
00486 _vSubRefdFieldContainers[i]);
00487 }
00488
00489 fprintf(stderr, "CLCreate:\n");
00490 for(i = 0; i < _vCreatedFieldContainers.size(); i++)
00491 {
00492 fprintf(stderr, "\t%u\n", _vCreatedFieldContainers[i]);
00493 }
00494
00495 fprintf(stderr, "CLDestroy:\n");
00496 for(i = 0; i < _vDestroyedFieldContainers.size(); i++)
00497 {
00498 fprintf(stderr, "\t%u\n", _vDestroyedFieldContainers[i]);
00499 }
00500 }
00501
00502
00503
00504
00505
00506 #ifdef __sgi
00507 #pragma set woff 1174
00508 #endif
00509
00510 #ifdef OSG_LINUX_ICC
00511 #pragma warning( disable : 177 )
00512 #endif
00513
00514 namespace
00515 {
00516 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00517 static Char8 cvsid_hpp[] = OSGCHANGELIST_HEADER_CVSID;
00518 }