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
00040
00041
00042
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045
00046 #include "OSGConfig.h"
00047
00048 #include <OSGGL.h>
00049
00050 #include "OSGStateChunk.h"
00051
00052 #include "OSGState.h"
00053
00054
00055 #if !defined(OSG_DO_DOC) || defined(OSG_DOC_DEV)
00056
00057 OSG_BEGIN_NAMESPACE
00058
00064 struct ClearSlot : public std::unary_function< StateChunkPtr &,
00065 const NullFieldContainerPtr &>
00066 {
00067 const NullFieldContainerPtr &operator() (StateChunkPtr &slotPtr)
00068 {
00069 subRefCP(slotPtr);
00070
00071 return NullFC;
00072 }
00073 };
00074
00075 OSG_END_NAMESPACE
00076
00077 #endif
00078
00079 OSG_USING_NAMESPACE
00080
00081
00082
00083
00084
00085
00086
00094
00095
00096
00097
00098 char State::cvsid[] = "@(#)$Id: $";
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 void State::initMethod (void)
00109 {
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 State::State(void) :
00124 Inherited()
00125 {
00126 }
00127
00128 State::State(const State &source) :
00129 Inherited(source)
00130 {
00131 }
00132
00133 State::~State(void)
00134 {
00135 clearChunks();
00136 }
00137
00138
00139 void State::changed(BitVector whichField, UInt32 origin)
00140 {
00141 Inherited::changed(whichField, origin);
00142 }
00143
00144
00145
00146 void State::dump( UInt32 OSG_CHECK_ARG(uiIndent),
00147 const BitVector OSG_CHECK_ARG(bvFlags)) const
00148 {
00149 std::cerr << "State at " << this << std::endl;
00150
00151 MFStateChunkPtr::const_iterator it;
00152 UInt32 cind;
00153
00154 for(it = _mfChunks.begin(), cind = 0; it != _mfChunks.end(); it++, cind++)
00155 {
00156 std::cerr << StateChunkClass::getName(cind) << "\t";
00157 if(*it == NullFC)
00158 std::cerr << "NullChunk" << std::endl;
00159 else
00160 std::cerr << *it << std::endl;
00161 }
00162 }
00163
00164
00165
00170 void State::activate(DrawActionBase *action)
00171 {
00172 MFStateChunkPtr::iterator it;
00173 Int32 ind = 0;
00174 UInt32 cind;
00175
00176 for(it = _mfChunks.begin(), cind = 0; it != _mfChunks.end();
00177 ++it, ++cind)
00178 {
00179 if(*it != NullFC)
00180 {
00181 (*it)->activate(action, UInt32(ind));
00182 }
00183 if(++ind >= StateChunkClass::getNumSlots(cind))
00184 ind = 0;
00185 }
00186 }
00187
00188
00193 void State::changeFrom(DrawActionBase *action, State *old)
00194 {
00195 MFStateChunkPtr::iterator it;
00196 Int32 ind = 0;
00197 UInt32 i;
00198 UInt32 cind;
00199
00200 for(it = _mfChunks.begin(), cind = 0; it != _mfChunks.end();
00201 ++it, ++cind)
00202 {
00203 StateChunkPtr o = old->getChunk(cind);
00204 StateChunkPtr n = *it;
00205
00206 if(n != NullFC)
00207 {
00208 if(o != NullFC)
00209 n->changeFrom(action, o.getCPtr(), UInt32(ind));
00210 else
00211 n->activate(action, UInt32(ind));
00212 }
00213 else if(o != NullFC)
00214 o->deactivate(action, UInt32(ind));
00215
00216 if(++ind >= StateChunkClass::getNumSlots(cind))
00217 ind = 0;
00218 }
00219
00220 if(ind >= StateChunkClass::getNumSlots(cind))
00221 ind = 0;
00222
00223 for(i = cind; i < old->getChunks().size(); ++i)
00224 {
00225 StateChunkPtr o = old->getChunk(i);
00226
00227 if(o != NullFC)
00228 {
00229 o->deactivate(action, UInt32(ind));
00230 }
00231
00232 if(++ind >= StateChunkClass::getNumSlots(i))
00233 {
00234 ind = 0;
00235 }
00236 }
00237 }
00238
00239
00244 void State::deactivate(DrawActionBase *action)
00245 {
00246 MFStateChunkPtr::iterator it;
00247 Int32 ind = 0;
00248 UInt32 cind;
00249
00250 for(it = _mfChunks.begin(), cind = 0; it != _mfChunks.end();
00251 ++it, ++cind)
00252 {
00253 if(*it != NullFC)
00254 (*it)->deactivate(action, UInt32(ind));
00255 if(++ind >= StateChunkClass::getNumSlots(cind))
00256 ind = 0;
00257 }
00258 }
00259
00260
00261
00262
00282 bool State::addChunk(StateChunkPtr chunk, Int32 index)
00283 {
00284 if(index > 0 && index > chunk->getClass()->getNumSlots())
00285 {
00286 SWARNING << "addChunk: index "
00287 << index
00288 << " > Numslots "
00289 << chunk->getClass()->getNumSlots()
00290 << ", ignored!"
00291 << std::endl;
00292 return true;
00293 }
00294
00295 UInt32 cindex = chunk->getClassId();
00296 UInt32 csize = _mfChunks.size();
00297
00298
00299 if(index == AutoSlot || index == AutoSlotReplace)
00300 {
00301 UInt8 nslots = chunk->getClass()->getNumSlots();
00302 UInt8 ci;
00303
00304 for(ci = cindex; ci < cindex + nslots && ci < csize; ++ci)
00305 {
00306 if(_mfChunks[ci] == NullFC)
00307 {
00308 break;
00309 }
00310 }
00311
00312 if(ci >= cindex + nslots)
00313 {
00314 if(index == AutoSlot)
00315 {
00316 SWARNING << "addChunk: no free slot found for "
00317 << chunk->getClass()->getName()
00318 << " class, ignored!" << std::endl;
00319 return true;
00320 }
00321
00322 --ci;
00323 }
00324
00325 cindex = ci;
00326 }
00327 else
00328 {
00329 cindex += index;
00330 }
00331
00332
00333 if(cindex >= csize)
00334 {
00335 UInt32 oldsize = csize;
00336 UInt32 newsize = cindex + 1;
00337
00338 _mfChunks.resize(newsize);
00339
00340 for(UInt32 i = oldsize; i < newsize; i++)
00341 {
00342 _mfChunks[i] = NullFC;
00343 }
00344 }
00345
00346 setRefdCP(_mfChunks[cindex], chunk);
00347
00348 return false;
00349 }
00350
00355 bool State::subChunk(StateChunkPtr chunk)
00356 {
00357 if(chunk == NullFC)
00358 return true;
00359
00360 UInt32 cindex = chunk->getClassId();
00361 UInt32 csize = _mfChunks.size();
00362
00363
00364 UInt8 nslots = chunk->getClass()->getNumSlots();
00365 UInt8 ci;
00366
00367 for(ci = cindex; ci < cindex + nslots && ci < csize; ci++)
00368 {
00369 if(_mfChunks[ci] == chunk)
00370 {
00371 break;
00372 }
00373 }
00374
00375 if(ci >= cindex + nslots)
00376 {
00377 SWARNING << "subChunk: chunk "
00378 << chunk
00379 << " of class "
00380 << chunk->getClass()->getName()
00381 << " not found!"
00382 << std::endl;
00383 return true;
00384 }
00385
00386
00387
00388 subRefCP(_mfChunks[ci]);
00389
00390 _mfChunks[ci] = NullFC;
00391
00392 return false;
00393 }
00394
00395
00400 bool State::subChunk(UInt32 classid, Int32 index)
00401 {
00402 if(index < 0 || index > StateChunkClass::getNumSlots(classid))
00403 {
00404 SWARNING << "subChunk: index " << index << " > Numslots "
00405 << StateChunkClass::getNumSlots(classid)
00406 << ", ignored!" << std::endl;
00407 return true;
00408 }
00409
00410 if(_mfChunks[classid + index] == NullFC)
00411 return true;
00412
00413
00414
00415 subRefCP(_mfChunks[classid + index]);
00416
00417 _mfChunks[classid + index] = NullFC;
00418
00419 return false;
00420 }
00421
00425 void State::clearChunks(void)
00426 {
00427 std::transform(_mfChunks.begin(),
00428 _mfChunks.end (),
00429 _mfChunks.begin(),
00430 ClearSlot());
00431 }
00432
00433
00434
00435
00440 Real32 State::switchCost(State *OSG_CHECK_ARG(state))
00441 {
00442 return 0;
00443 }
00444
00445 bool State::operator < (const State &other) const
00446 {
00447 return this < &other;
00448 }
00449
00453 bool State::operator == (const State &OSG_CHECK_ARG(other)) const
00454 {
00455 return false;
00456 }
00457
00458 bool State::operator != (const State &other) const
00459 {
00460 return ! (*this == other);
00461 }