Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGState.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00039 //---------------------------------------------------------------------------
00040 //  Includes
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  *                            Description                                  *
00084 \***************************************************************************/
00085 
00086 
00094 /***************************************************************************\
00095  *                           Class variables                               *
00096 \***************************************************************************/
00097 
00098 char State::cvsid[] = "@(#)$Id: $";
00099 
00100 /***************************************************************************\
00101  *                           Class methods                                 *
00102 \***************************************************************************/
00103 
00104 /*-------------------------------------------------------------------------*\
00105  -  private                                                                -
00106 \*-------------------------------------------------------------------------*/
00107 
00108 void State::initMethod (void)
00109 {
00110 }
00111 
00112 /***************************************************************************\
00113  *                           Instance methods                              *
00114 \***************************************************************************/
00115 
00116 /*-------------------------------------------------------------------------*\
00117  -  public                                                                 -
00118 \*-------------------------------------------------------------------------*/
00119 
00120 
00121 /*------------- constructors & destructors --------------------------------*/
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 /*------------------------------- dump ----------------------------------*/
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 /*-------------------- OpenGL State Management --------------------------*/
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 /*---------------------------- Access -----------------------------------*/
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     // special case: find empty slot automatically
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)    // no free slot found
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             // use last slot
00322             --ci;
00323         }
00324 
00325         cindex = ci;
00326     }
00327     else
00328     {
00329         cindex += index;
00330     }
00331 
00332     // add the chunk to the state at cindex
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     // special case: find it in the slots
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)    // chunk not found
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     // remove the chunk from the state
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     // remove the chunk from the state
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 /*-------------------------- comparison -----------------------------------*/
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 }

Generated on Thu Aug 25 04:10:38 2005 for OpenSG by  doxygen 1.4.3