Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/putil/pipelineCyclerBase.I

Go to the documentation of this file.
00001 // Filename: pipelineCyclerBase.I
00002 // Created by:  drose (21Feb02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 
00020 #ifdef DO_PIPELINING
00021 // The following implementations are to support compiled-in pipeline
00022 // sanity checks.
00023 
00024 ////////////////////////////////////////////////////////////////////
00025 //     Function: PipelineCyclerBase::Constructor (sanity-check)
00026 //       Access: Public
00027 //  Description: 
00028 ////////////////////////////////////////////////////////////////////
00029 INLINE PipelineCyclerBase::
00030 PipelineCyclerBase(CycleData *initial_data, Pipeline *pipeline) :
00031   _data(initial_data),
00032   _pipeline(pipeline),
00033   _read_count(0),
00034   _write_count(0)
00035 {
00036   if (_pipeline == (Pipeline *)NULL) {
00037     _pipeline = Pipeline::get_render_pipeline();
00038   }
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: PipelineCyclerBase::Copy Constructor (sanity-check)
00043 //       Access: Public
00044 //  Description: 
00045 ////////////////////////////////////////////////////////////////////
00046 INLINE PipelineCyclerBase::
00047 PipelineCyclerBase(CycleData *, const PipelineCyclerBase &copy) :
00048   _data(copy._data->make_copy()),
00049   _pipeline(copy._pipeline),
00050   _read_count(0),
00051   _write_count(0)
00052 {
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: PipelineCyclerBase::Copy Assignment (sanity-check)
00057 //       Access: Public
00058 //  Description: 
00059 ////////////////////////////////////////////////////////////////////
00060 INLINE void PipelineCyclerBase::
00061 operator = (const PipelineCyclerBase &copy) {
00062   nassertv(_read_count == 0 && _write_count == 0);
00063   _data = copy._data->make_copy();
00064   _pipeline = copy._pipeline;
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: PipelineCyclerBase::Destructor (sanity-check)
00069 //       Access: Public
00070 //  Description: 
00071 ////////////////////////////////////////////////////////////////////
00072 INLINE PipelineCyclerBase::
00073 ~PipelineCyclerBase() {
00074   nassertv(_read_count == 0 && _write_count == 0);
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: PipelineCyclerBase::read (sanity-check)
00079 //       Access: Public
00080 //  Description: Returns a const CycleData pointer, filled with the
00081 //               data for the current stage of the pipeline as seen by
00082 //               this thread.  This pointer should eventually be
00083 //               released by calling release_read().
00084 //
00085 //               There should be no outstanding write pointers on the
00086 //               data when this function is called.
00087 ////////////////////////////////////////////////////////////////////
00088 INLINE const CycleData *PipelineCyclerBase::
00089 read() const {
00090   // This function isn't truly const, but it doesn't change the data
00091   // in any meaningful way, so we pretend it is.
00092   ((PipelineCyclerBase *)this)->_read_count++;
00093 
00094   // It's not an error to grab a read pointer while someone else holds
00095   // a read or a write pointer.
00096   return _data;
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: PipelineCyclerBase::increment_read (sanity-check)
00101 //       Access: Public
00102 //  Description: Increments the count on a pointer previously
00103 //               retrieved by read(); now the pointer will need to be
00104 //               released twice.
00105 ////////////////////////////////////////////////////////////////////
00106 INLINE void PipelineCyclerBase::
00107 increment_read(const CycleData *pointer) const {
00108   // This function isn't truly const, but it doesn't change the data
00109   // in any meaningful way, so we pretend it is.
00110   nassertv(pointer == _data);
00111   nassertv(_read_count > 0);
00112   ((PipelineCyclerBase *)this)->_read_count++;
00113 }
00114 
00115 ////////////////////////////////////////////////////////////////////
00116 //     Function: PipelineCyclerBase::release_read (sanity-check)
00117 //       Access: Public
00118 //  Description: Releases a pointer previously obtained via a call to
00119 //               read().
00120 ////////////////////////////////////////////////////////////////////
00121 INLINE void PipelineCyclerBase::
00122 release_read(const CycleData *pointer) const {
00123   // This function isn't truly const, but it doesn't change the data
00124   // in any meaningful way, so we pretend it is.
00125   nassertv(pointer == _data);
00126   nassertv(_read_count > 0);
00127   ((PipelineCyclerBase *)this)->_read_count--;
00128 }
00129 
00130 ////////////////////////////////////////////////////////////////////
00131 //     Function: PipelineCyclerBase::write (sanity-check)
00132 //       Access: Public
00133 //  Description: Returns a non-const CycleData pointer, filled with a
00134 //               unique copy of the data for the current stage of the
00135 //               pipeline as seen by this thread.  This pointer may
00136 //               now be used to write to the data, and that copy of
00137 //               the data will be propagate to all later stages of the
00138 //               pipeline.  This pointer should eventually be released
00139 //               by calling release_write().
00140 //
00141 //               There may only be one outstanding write pointer on a
00142 //               given stage at a time, and if there is a write
00143 //               pointer there may be no read pointers on the same
00144 //               stage (but see elevate_read).
00145 ////////////////////////////////////////////////////////////////////
00146 INLINE CycleData *PipelineCyclerBase::
00147 write() {
00148   _write_count++;
00149 
00150   // It's an error to grab a write pointer while someone else holds a
00151   // read pointer, because doing so may invalidate the read pointer.
00152   nassertr(_read_count == 0, _data);
00153 
00154   // It's not an error to do this while someone else holds a write
00155   // pointer, however.
00156 
00157   return _data;
00158 }
00159 
00160 ////////////////////////////////////////////////////////////////////
00161 //     Function: PipelineCyclerBase::elevate_read (sanity-check)
00162 //       Access: Public
00163 //  Description: Elevates a currently-held read pointer into a write
00164 //               pointer.  This may or may not change the value of the
00165 //               pointer.  It is only valid to do this if this is the
00166 //               only currently-outstanding read pointer on the
00167 //               current stage.
00168 ////////////////////////////////////////////////////////////////////
00169 INLINE CycleData *PipelineCyclerBase::
00170 elevate_read(const CycleData *pointer) {
00171   release_read(pointer);
00172   return write();
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: PipelineCyclerBase::release_write (sanity-check)
00177 //       Access: Public
00178 //  Description: Releases a pointer previously obtained via a call to
00179 //               write().
00180 ////////////////////////////////////////////////////////////////////
00181 INLINE void PipelineCyclerBase::
00182 release_write(CycleData *pointer) {
00183   nassertv(pointer == _data);
00184   nassertv(_write_count > 0);
00185   _write_count--;
00186 }
00187 
00188 ////////////////////////////////////////////////////////////////////
00189 //     Function: PipelineCyclerBase::get_num_stages (sanity-check)
00190 //       Access: Public
00191 //  Description: Returns the number of stages in the pipeline.
00192 ////////////////////////////////////////////////////////////////////
00193 INLINE int PipelineCyclerBase::
00194 get_num_stages() {
00195   return 1;
00196 }
00197 
00198 ////////////////////////////////////////////////////////////////////
00199 //     Function: PipelineCyclerBase::is_stage_unique (sanity-check)
00200 //       Access: Public
00201 //  Description: Returns true if the nth stage is a different pointer
00202 //               than the previous stage, or false if its pointer is
00203 //               shared with the previous one.
00204 ////////////////////////////////////////////////////////////////////
00205 INLINE bool PipelineCyclerBase::
00206 is_stage_unique(int n) const {
00207   nassertr(n == 0, false);
00208   return true;
00209 }
00210 
00211 ////////////////////////////////////////////////////////////////////
00212 //     Function: PipelineCyclerBase::write_stage (sanity-check)
00213 //       Access: Public
00214 //  Description: Returns a pointer suitable for writing to the nth
00215 //               stage of the pipeline.  This is for special
00216 //               applications that need to update the entire pipeline
00217 //               at once (for instance, to remove an invalid pointer).
00218 //               This pointer should later be released with
00219 //               release_write_stage().
00220 ////////////////////////////////////////////////////////////////////
00221 INLINE CycleData *PipelineCyclerBase::
00222 write_stage(int n) {
00223   nassertr(n == 0, (CycleData *)NULL);
00224   _write_count++;
00225   return _data;
00226 }
00227 
00228 ////////////////////////////////////////////////////////////////////
00229 //     Function: PipelineCyclerBase::release_write_stage (sanity-check)
00230 //       Access: Public
00231 //  Description: Releases a pointer previously obtained via a call to
00232 //               write_stage().
00233 ////////////////////////////////////////////////////////////////////
00234 INLINE void PipelineCyclerBase::
00235 release_write_stage(int n, CycleData *pointer) {
00236   nassertv(n == 0 && pointer == _data);
00237   nassertv(_write_count > 0);
00238   _write_count--;
00239 }
00240 
00241 ////////////////////////////////////////////////////////////////////
00242 //     Function: PipelineCyclerBase::cheat (sanity-check)
00243 //       Access: Public
00244 //  Description: Returns a pointer without counting it.  This is only
00245 //               intended for use as the return value for certain
00246 //               nassertr() functions, so the application can recover
00247 //               after a failure to manage the read and write pointers
00248 //               correctly.  You should never call this function
00249 //               directly.
00250 ////////////////////////////////////////////////////////////////////
00251 INLINE CycleData *PipelineCyclerBase::
00252 cheat() const {
00253   return _data;
00254 }
00255 
00256 ////////////////////////////////////////////////////////////////////
00257 //     Function: PipelineCyclerBase::get_read_count (sanity-check)
00258 //       Access: Public
00259 //  Description: Returns the number of handles currently outstanding
00260 //               to read the current stage of the data.  This should
00261 //               only be used for debugging purposes.
00262 ////////////////////////////////////////////////////////////////////
00263 INLINE int PipelineCyclerBase::
00264 get_read_count() const {
00265   return _read_count;
00266 }
00267 
00268 ////////////////////////////////////////////////////////////////////
00269 //     Function: PipelineCyclerBase::get_write_count (sanity-check)
00270 //       Access: Public
00271 //  Description: Returns the number of handles currently outstanding
00272 //               to read the current stage of the data.  This will
00273 //               normally only be either 0 or 1.  This should only be
00274 //               used for debugging purposes.
00275 ////////////////////////////////////////////////////////////////////
00276 INLINE int PipelineCyclerBase::
00277 get_write_count() const {
00278   return _write_count;
00279 }
00280 
00281 #else  // !DO_PIPELINING
00282 // The following implementations are provided for when pipelining is
00283 // not compiled in.  They are trivial functions that do as little as
00284 // possible.
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 //     Function: PipelineCyclerBase::Constructor (trivial)
00288 //       Access: Public
00289 //  Description: 
00290 ////////////////////////////////////////////////////////////////////
00291 INLINE PipelineCyclerBase::
00292 PipelineCyclerBase(CycleData *initial_data, Pipeline *) {
00293   // In the trivial implementation, a derived class (the
00294   // PipelineCycler template class) stores the CycleData object
00295   // directly within itself, and since we have no data members or
00296   // virtual functions, we get away with assuming the pointer is the
00297   // same as the 'this' pointer.
00298 
00299   // If this turns out not to be true on a particular platform, we
00300   // will have to store the pointer in this class, for a little bit of
00301   // extra overhead.
00302 #ifdef SIMPLE_STRUCT_POINTERS
00303   nassertv(initial_data == (CycleData *)this);
00304 #else
00305   _data = initial_data;
00306 #endif  // SIMPLE_STRUCT_POINTERS
00307 }
00308 
00309 ////////////////////////////////////////////////////////////////////
00310 //     Function: PipelineCyclerBase::Copy Constructor (trivial)
00311 //       Access: Public
00312 //  Description: 
00313 ////////////////////////////////////////////////////////////////////
00314 INLINE PipelineCyclerBase::
00315 PipelineCyclerBase(CycleData *initial_data, const PipelineCyclerBase &) {
00316   // The copy constructor for the DO_PIPELINING case is 
00317 #ifdef SIMPLE_STRUCT_POINTERS
00318   nassertv(initial_data == (CycleData *)this);
00319 #else
00320   _data = initial_data;
00321 #endif  // SIMPLE_STRUCT_POINTERS
00322 }
00323 
00324 ////////////////////////////////////////////////////////////////////
00325 //     Function: PipelineCyclerBase::Copy Assignment (trivial)
00326 //       Access: Public
00327 //  Description: 
00328 ////////////////////////////////////////////////////////////////////
00329 INLINE void PipelineCyclerBase::
00330 operator = (const PipelineCyclerBase &) {
00331   // We don't reassign the _data pointer here; we assume it was set
00332   // correctly previously.
00333 }
00334 
00335 ////////////////////////////////////////////////////////////////////
00336 //     Function: PipelineCyclerBase::Destructor (trivial)
00337 //       Access: Public
00338 //  Description: 
00339 ////////////////////////////////////////////////////////////////////
00340 INLINE PipelineCyclerBase::
00341 ~PipelineCyclerBase() {
00342 }
00343 
00344 ////////////////////////////////////////////////////////////////////
00345 //     Function: PipelineCyclerBase::read (trivial)
00346 //       Access: Public
00347 //  Description: Returns a const CycleData pointer, filled with the
00348 //               data for the current stage of the pipeline as seen by
00349 //               this thread.  This pointer should eventually be
00350 //               released by calling release_read().
00351 ////////////////////////////////////////////////////////////////////
00352 INLINE const CycleData *PipelineCyclerBase::
00353 read() const {
00354 #ifdef SIMPLE_STRUCT_POINTERS
00355   return (const CycleData *)this;
00356 #else
00357   return _data;
00358 #endif  // SIMPLE_STRUCT_POINTERS
00359 }
00360 
00361 ////////////////////////////////////////////////////////////////////
00362 //     Function: PipelineCyclerBase::increment_read (trivial)
00363 //       Access: Public
00364 //  Description: Increments the count on a pointer previously
00365 //               retrieved by read(); now the pointer will need to be
00366 //               released twice.
00367 ////////////////////////////////////////////////////////////////////
00368 INLINE void PipelineCyclerBase::
00369 increment_read(const CycleData *) const {
00370 }
00371 
00372 ////////////////////////////////////////////////////////////////////
00373 //     Function: PipelineCyclerBase::release_read (trivial)
00374 //       Access: Public
00375 //  Description: Releases a pointer previously obtained via a call to
00376 //               read().
00377 ////////////////////////////////////////////////////////////////////
00378 INLINE void PipelineCyclerBase::
00379 release_read(const CycleData *) const {
00380 }
00381 
00382 ////////////////////////////////////////////////////////////////////
00383 //     Function: PipelineCyclerBase::write (trivial)
00384 //       Access: Public
00385 //  Description: Returns a non-const CycleData pointer, filled with a
00386 //               unique copy of the data for the current stage of the
00387 //               pipeline as seen by this thread.  This pointer may
00388 //               now be used to write to the data, and that copy of
00389 //               the data will be propagate to all later stages of the
00390 //               pipeline.  This pointer should eventually be released
00391 //               by calling release_write().
00392 //
00393 //               There may only be one outstanding write pointer on a
00394 //               given stage at a time, and if there is a write
00395 //               pointer there may be no read pointers on the same
00396 //               stage (but see elevate_read).
00397 ////////////////////////////////////////////////////////////////////
00398 INLINE CycleData *PipelineCyclerBase::
00399 write() {
00400 #ifdef SIMPLE_STRUCT_POINTERS
00401   return (CycleData *)this;
00402 #else
00403   return _data;
00404 #endif  // SIMPLE_STRUCT_POINTERS
00405 }
00406 
00407 ////////////////////////////////////////////////////////////////////
00408 //     Function: PipelineCyclerBase::elevate_read (trivial)
00409 //       Access: Public
00410 //  Description: Elevates a currently-held read pointer into a write
00411 //               pointer.  This may or may not change the value of the
00412 //               pointer.  It is only valid to do this if this is the
00413 //               only currently-outstanding read pointer on the
00414 //               current stage.
00415 ////////////////////////////////////////////////////////////////////
00416 INLINE CycleData *PipelineCyclerBase::
00417 elevate_read(const CycleData *) {
00418 #ifdef SIMPLE_STRUCT_POINTERS
00419   return (CycleData *)this;
00420 #else
00421   return _data;
00422 #endif  // SIMPLE_STRUCT_POINTERS
00423 }
00424 
00425 ////////////////////////////////////////////////////////////////////
00426 //     Function: PipelineCyclerBase::release_write (trivial)
00427 //       Access: Public
00428 //  Description: Releases a pointer previously obtained via a call to
00429 //               write().
00430 ////////////////////////////////////////////////////////////////////
00431 INLINE void PipelineCyclerBase::
00432 release_write(CycleData *) {
00433 }
00434 
00435 ////////////////////////////////////////////////////////////////////
00436 //     Function: PipelineCyclerBase::get_num_stages (trivial)
00437 //       Access: Public
00438 //  Description: Returns the number of stages in the pipeline.
00439 ////////////////////////////////////////////////////////////////////
00440 INLINE int PipelineCyclerBase::
00441 get_num_stages() {
00442   return 1;
00443 }
00444 
00445 ////////////////////////////////////////////////////////////////////
00446 //     Function: PipelineCyclerBase::is_stage_unique (trivial)
00447 //       Access: Public
00448 //  Description: Returns true if the nth stage is a different pointer
00449 //               than the previous stage, or false if its pointer is
00450 //               shared with the previous one.
00451 ////////////////////////////////////////////////////////////////////
00452 INLINE bool PipelineCyclerBase::
00453 is_stage_unique(int n) const {
00454   return true;
00455 }
00456 
00457 ////////////////////////////////////////////////////////////////////
00458 //     Function: PipelineCyclerBase::write_stage (trivial)
00459 //       Access: Public
00460 //  Description: Returns a pointer suitable for writing to the nth
00461 //               stage of the pipeline.  This is for special
00462 //               applications that need to update the entire pipeline
00463 //               at once (for instance, to remove an invalid pointer).
00464 //               This pointer should later be released with
00465 //               release_write_stage().
00466 ////////////////////////////////////////////////////////////////////
00467 INLINE CycleData *PipelineCyclerBase::
00468 write_stage(int) {
00469   return (CycleData *)this;
00470 }
00471 
00472 ////////////////////////////////////////////////////////////////////
00473 //     Function: PipelineCyclerBase::release_write_stage (trivial)
00474 //       Access: Public
00475 //  Description: Releases a pointer previously obtained via a call to
00476 //               write_stage().
00477 ////////////////////////////////////////////////////////////////////
00478 INLINE void PipelineCyclerBase::
00479 release_write_stage(int, CycleData *) {
00480 }
00481 
00482 ////////////////////////////////////////////////////////////////////
00483 //     Function: PipelineCyclerBase::cheat (trivial)
00484 //       Access: Public
00485 //  Description: Returns a pointer without counting it.  This is only
00486 //               intended for use as the return value for certain
00487 //               nassertr() functions, so the application can recover
00488 //               after a failure to manage the read and write pointers
00489 //               correctly.  You should never call this function
00490 //               directly.
00491 ////////////////////////////////////////////////////////////////////
00492 INLINE CycleData *PipelineCyclerBase::
00493 cheat() const {
00494 #ifdef SIMPLE_STRUCT_POINTERS
00495   return (CycleData *)this;
00496 #else
00497   return _data;
00498 #endif  // SIMPLE_STRUCT_POINTERS
00499 }
00500 
00501 ////////////////////////////////////////////////////////////////////
00502 //     Function: PipelineCyclerBase::get_read_count (trivial)
00503 //       Access: Public
00504 //  Description: Returns the number of handles currently outstanding
00505 //               to read the current stage of the data.  This should
00506 //               only be used for debugging purposes.
00507 ////////////////////////////////////////////////////////////////////
00508 INLINE int PipelineCyclerBase::
00509 get_read_count() const {
00510   return 0;
00511 }
00512 
00513 ////////////////////////////////////////////////////////////////////
00514 //     Function: PipelineCyclerBase::get_write_count (trivial)
00515 //       Access: Public
00516 //  Description: Returns the number of handles currently outstanding
00517 //               to read the current stage of the data.  This will
00518 //               normally only be either 0 or 1.  This should only be
00519 //               used for debugging purposes.
00520 ////////////////////////////////////////////////////////////////////
00521 INLINE int PipelineCyclerBase::
00522 get_write_count() const {
00523   return 0;
00524 }
00525 
00526 
00527 #endif   // DO_PIPELINING

Generated on Fri May 2 00:43:41 2003 for Panda by doxygen1.3