Panda3D
|
00001 // Filename: pipelineCyclerTrivialImpl.I 00002 // Created by: drose (31Jan06) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 00016 //////////////////////////////////////////////////////////////////// 00017 // Function: PipelineCyclerTrivialImpl::Constructor 00018 // Access: Public 00019 // Description: 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE PipelineCyclerTrivialImpl:: 00022 PipelineCyclerTrivialImpl(CycleData *initial_data, Pipeline *) { 00023 // In the trivial implementation, a derived class (the 00024 // PipelineCycler template class) stores the CycleData object 00025 // directly within itself, and since we have no data members or 00026 // virtual functions, we get away with assuming the pointer is the 00027 // same as the 'this' pointer. 00028 00029 // If this turns out not to be true on a particular platform, we 00030 // will have to store the pointer in this class, for a little bit of 00031 // extra overhead. 00032 #ifdef SIMPLE_STRUCT_POINTERS 00033 nassertv(initial_data == (CycleData *)this); 00034 #else 00035 _data = initial_data; 00036 #endif // SIMPLE_STRUCT_POINTERS 00037 } 00038 00039 //////////////////////////////////////////////////////////////////// 00040 // Function: PipelineCyclerTrivialImpl::Copy Constructor 00041 // Access: Private 00042 // Description: 00043 //////////////////////////////////////////////////////////////////// 00044 INLINE PipelineCyclerTrivialImpl:: 00045 PipelineCyclerTrivialImpl(const PipelineCyclerTrivialImpl &) { 00046 // The copy constructor for the PipelineCyclerTrivialImpl case 00047 // doesn't work. Don't try to use it. The PipelineCycler template 00048 // class is #ifdeffed appropriately to call the normal constructor 00049 // instead. 00050 nassertv(false); 00051 } 00052 00053 //////////////////////////////////////////////////////////////////// 00054 // Function: PipelineCyclerTrivialImpl::Copy Assignment 00055 // Access: Private 00056 // Description: 00057 //////////////////////////////////////////////////////////////////// 00058 INLINE void PipelineCyclerTrivialImpl:: 00059 operator = (const PipelineCyclerTrivialImpl &) { 00060 // The copy assignment operator for the PipelineCyclerTrivialImpl 00061 // case doesn't work. Don't try to use it. The PipelineCycler 00062 // template class is #ifdeffed appropriately not to call this 00063 // method. 00064 nassertv(false); 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: PipelineCyclerTrivialImpl::Destructor 00069 // Access: Public 00070 // Description: 00071 //////////////////////////////////////////////////////////////////// 00072 INLINE PipelineCyclerTrivialImpl:: 00073 ~PipelineCyclerTrivialImpl() { 00074 } 00075 00076 //////////////////////////////////////////////////////////////////// 00077 // Function: PipelineCyclerTrivialImpl::acquire 00078 // Access: Public 00079 // Description: Grabs an overall lock on the cycler. Release it with 00080 // a call to release(). This lock should be held while 00081 // walking the list of stages. 00082 //////////////////////////////////////////////////////////////////// 00083 INLINE void PipelineCyclerTrivialImpl:: 00084 acquire(Thread *) { 00085 } 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: PipelineCyclerTrivialImpl::release 00089 // Access: Public 00090 // Description: Release the overall lock on the cycler that was 00091 // grabbed via acquire(). 00092 //////////////////////////////////////////////////////////////////// 00093 INLINE void PipelineCyclerTrivialImpl:: 00094 release() { 00095 } 00096 00097 //////////////////////////////////////////////////////////////////// 00098 // Function: PipelineCyclerTrivialImpl::read_unlocked 00099 // Access: Public 00100 // Description: Returns a const CycleData pointer, filled with the 00101 // data for the current stage of the pipeline as seen by 00102 // this thread. No lock is made on the contents; there 00103 // is no guarantee that some other thread won't modify 00104 // this object's data while you are working on it. 00105 // (However, the data within the returned CycleData 00106 // object itself is safe from modification; if another 00107 // thread modifies the data, it will perform a 00108 // copy-on-write, and thereby change the pointer stored 00109 // within the object.) 00110 //////////////////////////////////////////////////////////////////// 00111 INLINE const CycleData *PipelineCyclerTrivialImpl:: 00112 read_unlocked(Thread *) const { 00113 #ifdef SIMPLE_STRUCT_POINTERS 00114 return (const CycleData *)this; 00115 #else 00116 return _data; 00117 #endif // SIMPLE_STRUCT_POINTERS 00118 } 00119 00120 //////////////////////////////////////////////////////////////////// 00121 // Function: PipelineCyclerTrivialImpl::read 00122 // Access: Public 00123 // Description: Returns a const CycleData pointer, filled with the 00124 // data for the current stage of the pipeline as seen by 00125 // this thread. This pointer should eventually be 00126 // released by calling release_read(). 00127 //////////////////////////////////////////////////////////////////// 00128 INLINE const CycleData *PipelineCyclerTrivialImpl:: 00129 read(Thread *) const { 00130 #ifdef SIMPLE_STRUCT_POINTERS 00131 return (const CycleData *)this; 00132 #else 00133 return _data; 00134 #endif // SIMPLE_STRUCT_POINTERS 00135 } 00136 00137 //////////////////////////////////////////////////////////////////// 00138 // Function: PipelineCyclerTrivialImpl::increment_read 00139 // Access: Public 00140 // Description: Increments the count on a pointer previously 00141 // retrieved by read(); now the pointer will need to be 00142 // released twice. 00143 //////////////////////////////////////////////////////////////////// 00144 INLINE void PipelineCyclerTrivialImpl:: 00145 increment_read(const CycleData *) const { 00146 } 00147 00148 //////////////////////////////////////////////////////////////////// 00149 // Function: PipelineCyclerTrivialImpl::release_read 00150 // Access: Public 00151 // Description: Releases a pointer previously obtained via a call to 00152 // read(). 00153 //////////////////////////////////////////////////////////////////// 00154 INLINE void PipelineCyclerTrivialImpl:: 00155 release_read(const CycleData *) const { 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: PipelineCyclerTrivialImpl::write 00160 // Access: Public 00161 // Description: Returns a non-const CycleData pointer, filled with a 00162 // unique copy of the data for the current stage of the 00163 // pipeline as seen by this thread. This pointer may 00164 // now be used to write to the data, and that copy of 00165 // the data will be propagated to all later stages of the 00166 // pipeline. This pointer should eventually be released 00167 // by calling release_write(). 00168 // 00169 // There may only be one outstanding write pointer on a 00170 // given stage at a time, and if there is a write 00171 // pointer there may be no read pointers on the same 00172 // stage (but see elevate_read). 00173 //////////////////////////////////////////////////////////////////// 00174 INLINE CycleData *PipelineCyclerTrivialImpl:: 00175 write(Thread *) { 00176 #ifdef SIMPLE_STRUCT_POINTERS 00177 return (CycleData *)this; 00178 #else 00179 return _data; 00180 #endif // SIMPLE_STRUCT_POINTERS 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: PipelineCyclerTrivialImpl::write_upstream 00185 // Access: Public 00186 // Description: This special variant on write() will automatically 00187 // propagate changes back to upstream pipeline stages. 00188 // If force_to_0 is false, then it propagates back only 00189 // as long as the CycleData pointers are equivalent, 00190 // guaranteeing that it does not modify upstream data 00191 // (other than the modification that will be performed 00192 // by the code that returns this pointer). This is 00193 // particularly appropriate for minor updates, where it 00194 // doesn't matter much if the update is lost, such as 00195 // storing a cached value. 00196 // 00197 // If force_to_0 is trivial, then the CycleData pointer for 00198 // the current pipeline stage is propagated all the way 00199 // back up to stage 0; after this call, there will be 00200 // only one CycleData pointer that is duplicated in all 00201 // stages between stage 0 and the current stage. This 00202 // may undo some recent changes that were made 00203 // independently at pipeline stage 0 (or any other 00204 // upstream stage). However, it guarantees that the 00205 // change that is to be applied at this pipeline stage 00206 // will stick. This is slightly dangerous because of 00207 // the risk of losing upstream changes; generally, this 00208 // should only be done when you are confident that there 00209 // are no upstream changes to be lost (for instance, for 00210 // an object that has been recently created). 00211 //////////////////////////////////////////////////////////////////// 00212 CycleData *PipelineCyclerTrivialImpl:: 00213 write_upstream(bool, Thread *) { 00214 #ifdef SIMPLE_STRUCT_POINTERS 00215 return (CycleData *)this; 00216 #else 00217 return _data; 00218 #endif // SIMPLE_STRUCT_POINTERS 00219 } 00220 00221 //////////////////////////////////////////////////////////////////// 00222 // Function: PipelineCyclerTrivialImpl::elevate_read 00223 // Access: Public 00224 // Description: Elevates a currently-held read pointer into a write 00225 // pointer. This may or may not change the value of the 00226 // pointer. It is only valid to do this if this is the 00227 // only currently-outstanding read pointer on the 00228 // current stage. 00229 //////////////////////////////////////////////////////////////////// 00230 INLINE CycleData *PipelineCyclerTrivialImpl:: 00231 elevate_read(const CycleData *, Thread *) { 00232 #ifdef SIMPLE_STRUCT_POINTERS 00233 return (CycleData *)this; 00234 #else 00235 return _data; 00236 #endif // SIMPLE_STRUCT_POINTERS 00237 } 00238 00239 //////////////////////////////////////////////////////////////////// 00240 // Function: PipelineCyclerTrivialImpl::elevate_read_upstream 00241 // Access: Public 00242 // Description: Elevates a currently-held read pointer into a write 00243 // pointer, like elevate_read(), but also propagates the 00244 // pointer back to upstream stages, like 00245 // write_upstream(). 00246 //////////////////////////////////////////////////////////////////// 00247 INLINE CycleData *PipelineCyclerTrivialImpl:: 00248 elevate_read_upstream(const CycleData *, bool, Thread *) { 00249 #ifdef SIMPLE_STRUCT_POINTERS 00250 return (CycleData *)this; 00251 #else 00252 return _data; 00253 #endif // SIMPLE_STRUCT_POINTERS 00254 } 00255 00256 //////////////////////////////////////////////////////////////////// 00257 // Function: PipelineCyclerTrivialImpl::increment_write 00258 // Access: Public 00259 // Description: Increments the count on a pointer previously 00260 // retrieved by write(); now the pointer will need to be 00261 // released twice. 00262 //////////////////////////////////////////////////////////////////// 00263 INLINE void PipelineCyclerTrivialImpl:: 00264 increment_write(CycleData *) const { 00265 } 00266 00267 //////////////////////////////////////////////////////////////////// 00268 // Function: PipelineCyclerTrivialImpl::release_write 00269 // Access: Public 00270 // Description: Releases a pointer previously obtained via a call to 00271 // write(). 00272 //////////////////////////////////////////////////////////////////// 00273 INLINE void PipelineCyclerTrivialImpl:: 00274 release_write(CycleData *) { 00275 } 00276 00277 //////////////////////////////////////////////////////////////////// 00278 // Function: PipelineCyclerTrivialImpl::get_num_stages 00279 // Access: Public 00280 // Description: Returns the number of stages in the pipeline. 00281 //////////////////////////////////////////////////////////////////// 00282 INLINE int PipelineCyclerTrivialImpl:: 00283 get_num_stages() { 00284 return 1; 00285 } 00286 00287 //////////////////////////////////////////////////////////////////// 00288 // Function: PipelineCyclerTrivialImpl::read_stage_unlocked 00289 // Access: Public 00290 // Description: Returns a const CycleData pointer, filled with the 00291 // data for the indicated stage of the pipeline. As in 00292 // read_unlocked(), no lock is held on the returned 00293 // pointer. 00294 //////////////////////////////////////////////////////////////////// 00295 INLINE const CycleData *PipelineCyclerTrivialImpl:: 00296 read_stage_unlocked(int) const { 00297 #ifdef SIMPLE_STRUCT_POINTERS 00298 return (const CycleData *)this; 00299 #else 00300 return _data; 00301 #endif // SIMPLE_STRUCT_POINTERS 00302 } 00303 00304 //////////////////////////////////////////////////////////////////// 00305 // Function: PipelineCyclerTrivialImpl::read_stage 00306 // Access: Public 00307 // Description: Returns a const CycleData pointer, filled with the 00308 // data for the indicated pipeline stage. This pointer 00309 // should eventually be released by calling 00310 // release_read(). 00311 //////////////////////////////////////////////////////////////////// 00312 INLINE const CycleData *PipelineCyclerTrivialImpl:: 00313 read_stage(int, Thread *) const { 00314 #ifdef SIMPLE_STRUCT_POINTERS 00315 return (const CycleData *)this; 00316 #else 00317 return _data; 00318 #endif // SIMPLE_STRUCT_POINTERS 00319 } 00320 00321 //////////////////////////////////////////////////////////////////// 00322 // Function: PipelineCyclerTrivialImpl::release_read_stage 00323 // Access: Public 00324 // Description: Releases a pointer previously obtained via a call to 00325 // read_stage(). 00326 //////////////////////////////////////////////////////////////////// 00327 INLINE void PipelineCyclerTrivialImpl:: 00328 release_read_stage(int, const CycleData *) const { 00329 } 00330 00331 //////////////////////////////////////////////////////////////////// 00332 // Function: PipelineCyclerTrivialImpl::write_stage 00333 // Access: Public 00334 // Description: Returns a pointer suitable for writing to the nth 00335 // stage of the pipeline. This is for special 00336 // applications that need to update the entire pipeline 00337 // at once (for instance, to remove an invalid pointer). 00338 // This pointer should later be released with 00339 // release_write_stage(). 00340 //////////////////////////////////////////////////////////////////// 00341 INLINE CycleData *PipelineCyclerTrivialImpl:: 00342 write_stage(int, Thread *) { 00343 #ifdef SIMPLE_STRUCT_POINTERS 00344 return (CycleData *)this; 00345 #else 00346 return _data; 00347 #endif // SIMPLE_STRUCT_POINTERS 00348 } 00349 00350 //////////////////////////////////////////////////////////////////// 00351 // Function: PipelineCyclerTrivialImpl::write_stage_upstream 00352 // Access: Public 00353 // Description: Returns a pointer suitable for writing to the nth 00354 // stage of the pipeline. This is for special 00355 // applications that need to update the entire pipeline 00356 // at once (for instance, to remove an invalid pointer). 00357 // This pointer should later be released with 00358 // release_write_stage(). 00359 //////////////////////////////////////////////////////////////////// 00360 INLINE CycleData *PipelineCyclerTrivialImpl:: 00361 write_stage_upstream(int, bool, Thread *) { 00362 #ifdef SIMPLE_STRUCT_POINTERS 00363 return (CycleData *)this; 00364 #else 00365 return _data; 00366 #endif // SIMPLE_STRUCT_POINTERS 00367 } 00368 00369 //////////////////////////////////////////////////////////////////// 00370 // Function: PipelineCyclerTrivialImpl::elevate_read_stage 00371 // Access: Public 00372 // Description: Elevates a currently-held read pointer into a write 00373 // pointer. This may or may not change the value of the 00374 // pointer. It is only valid to do this if this is the 00375 // only currently-outstanding read pointer on the 00376 // current stage. 00377 //////////////////////////////////////////////////////////////////// 00378 INLINE CycleData *PipelineCyclerTrivialImpl:: 00379 elevate_read_stage(int, const CycleData *, Thread *) { 00380 #ifdef SIMPLE_STRUCT_POINTERS 00381 return (CycleData *)this; 00382 #else 00383 return _data; 00384 #endif // SIMPLE_STRUCT_POINTERS 00385 } 00386 00387 //////////////////////////////////////////////////////////////////// 00388 // Function: PipelineCyclerTrivialImpl::elevate_read_stage_upstream 00389 // Access: Public 00390 // Description: Elevates a currently-held read pointer into a write 00391 // pointer. This may or may not change the value of the 00392 // pointer. It is only valid to do this if this is the 00393 // only currently-outstanding read pointer on the 00394 // current stage. 00395 //////////////////////////////////////////////////////////////////// 00396 INLINE CycleData *PipelineCyclerTrivialImpl:: 00397 elevate_read_stage_upstream(int, const CycleData *, bool, Thread *) { 00398 #ifdef SIMPLE_STRUCT_POINTERS 00399 return (CycleData *)this; 00400 #else 00401 return _data; 00402 #endif // SIMPLE_STRUCT_POINTERS 00403 } 00404 00405 //////////////////////////////////////////////////////////////////// 00406 // Function: PipelineCyclerTrivialImpl::release_write_stage 00407 // Access: Public 00408 // Description: Releases a pointer previously obtained via a call to 00409 // write_stage(). 00410 //////////////////////////////////////////////////////////////////// 00411 INLINE void PipelineCyclerTrivialImpl:: 00412 release_write_stage(int, CycleData *) { 00413 } 00414 00415 //////////////////////////////////////////////////////////////////// 00416 // Function: PipelineCyclerTrivialImpl::get_parent_type 00417 // Access: Public 00418 // Description: Returns the type of object that owns this cycler, as 00419 // reported by CycleData::get_parent_type(). 00420 //////////////////////////////////////////////////////////////////// 00421 INLINE TypeHandle PipelineCyclerTrivialImpl:: 00422 get_parent_type() const { 00423 return cheat()->get_parent_type(); 00424 } 00425 00426 //////////////////////////////////////////////////////////////////// 00427 // Function: PipelineCyclerTrivialImpl::cheat 00428 // Access: Public 00429 // Description: Returns a pointer without counting it. This is only 00430 // intended for use as the return value for certain 00431 // nassertr() functions, so the application can recover 00432 // after a failure to manage the read and write pointers 00433 // correctly. You should never call this function 00434 // directly. 00435 //////////////////////////////////////////////////////////////////// 00436 INLINE CycleData *PipelineCyclerTrivialImpl:: 00437 cheat() const { 00438 #ifdef SIMPLE_STRUCT_POINTERS 00439 return (CycleData *)this; 00440 #else 00441 return _data; 00442 #endif // SIMPLE_STRUCT_POINTERS 00443 } 00444 00445 //////////////////////////////////////////////////////////////////// 00446 // Function: PipelineCyclerTrivialImpl::get_read_count 00447 // Access: Public 00448 // Description: Returns the number of handles currently outstanding 00449 // to read the current stage of the data. This should 00450 // only be used for debugging purposes. 00451 //////////////////////////////////////////////////////////////////// 00452 INLINE int PipelineCyclerTrivialImpl:: 00453 get_read_count() const { 00454 return 0; 00455 } 00456 00457 //////////////////////////////////////////////////////////////////// 00458 // Function: PipelineCyclerTrivialImpl::get_write_count 00459 // Access: Public 00460 // Description: Returns the number of handles currently outstanding 00461 // to read the current stage of the data. This will 00462 // normally only be either 0 or 1. This should only be 00463 // used for debugging purposes. 00464 //////////////////////////////////////////////////////////////////// 00465 INLINE int PipelineCyclerTrivialImpl:: 00466 get_write_count() const { 00467 return 0; 00468 } 00469