00001 // Filename: cycleDataReader.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 #ifdef DO_PIPELINING 00020 // This is the implementation for full support of pipelining (as well 00021 // as the sanity-check only implementation). 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: CycleDataReader::Constructor (full) 00025 // Access: Public 00026 // Description: 00027 //////////////////////////////////////////////////////////////////// 00028 template<class CycleDataType> 00029 INLINE CycleDataReader<CycleDataType>:: 00030 CycleDataReader(const PipelineCycler<CycleDataType> &cycler) : 00031 _cycler(&cycler) 00032 { 00033 _pointer = _cycler->read(); 00034 _write_pointer = (CycleDataType *)NULL; 00035 } 00036 00037 //////////////////////////////////////////////////////////////////// 00038 // Function: CycleDataReader::Copy Constructor (full) 00039 // Access: Public 00040 // Description: 00041 //////////////////////////////////////////////////////////////////// 00042 template<class CycleDataType> 00043 INLINE CycleDataReader<CycleDataType>:: 00044 CycleDataReader(const CycleDataReader<CycleDataType> ©) : 00045 _cycler(copy._cycler), 00046 _pointer(copy._pointer), 00047 _write_pointer(copy._write_pointer) 00048 { 00049 nassertv(_pointer != (const CycleDataType *)NULL); 00050 // We cannot copy a CycleDataReader that has elevated itself to a 00051 // write pointer. 00052 nassertv(_write_pointer == (const CycleDataType *)NULL); 00053 _cycler->increment_read(_pointer); 00054 } 00055 00056 //////////////////////////////////////////////////////////////////// 00057 // Function: CycleDataReader::Copy Assignment (full) 00058 // Access: Public 00059 // Description: 00060 //////////////////////////////////////////////////////////////////// 00061 template<class CycleDataType> 00062 INLINE void CycleDataReader<CycleDataType>:: 00063 operator = (const CycleDataReader<CycleDataType> ©) { 00064 _cycler = copy._cycler; 00065 _pointer = copy._pointer; 00066 _write_pointer = copy._write_pointer; 00067 00068 nassertv(_pointer != (const CycleDataType *)NULL); 00069 // We cannot copy a CycleDataReader that has elevated itself to a 00070 // write pointer. 00071 nassertv(_write_pointer == (const CycleDataType *)NULL); 00072 _cycler->increment_read(_pointer); 00073 } 00074 00075 //////////////////////////////////////////////////////////////////// 00076 // Function: CycleDataReader::Destructor (full) 00077 // Access: Public 00078 // Description: 00079 //////////////////////////////////////////////////////////////////// 00080 template<class CycleDataType> 00081 INLINE CycleDataReader<CycleDataType>:: 00082 ~CycleDataReader() { 00083 if (_write_pointer != (CycleDataType *)NULL) { 00084 // If the _write_pointer is non-NULL, then someone called 00085 // elevate_to_write() at some point, and we now actually hold a 00086 // write pointer, not a read pointer. 00087 ((PipelineCycler<CycleDataType> *)_cycler)->release_write(_write_pointer); 00088 } else if (_pointer != (CycleDataType *)NULL) { 00089 _cycler->release_read(_pointer); 00090 } 00091 } 00092 00093 //////////////////////////////////////////////////////////////////// 00094 // Function: CycleDataReader::operator -> (full) 00095 // Access: Public 00096 // Description: This provides an indirect member access to the actual 00097 // CycleData data. 00098 //////////////////////////////////////////////////////////////////// 00099 template<class CycleDataType> 00100 INLINE const CycleDataType *CycleDataReader<CycleDataType>:: 00101 operator -> () const { 00102 nassertr(_pointer != (const CycleDataType *)NULL, _cycler->cheat()); 00103 return _pointer; 00104 } 00105 00106 //////////////////////////////////////////////////////////////////// 00107 // Function: CycleDataReader::Typecast pointer (full) 00108 // Access: Public 00109 // Description: This allows the CycleDataReader to be passed to any 00110 // function that expects a const CycleDataType pointer. 00111 //////////////////////////////////////////////////////////////////// 00112 template<class CycleDataType> 00113 INLINE CycleDataReader<CycleDataType>:: 00114 operator const CycleDataType * () const { 00115 nassertr(_pointer != (const CycleDataType *)NULL, _cycler->cheat()); 00116 return _pointer; 00117 } 00118 00119 //////////////////////////////////////////////////////////////////// 00120 // Function: CycleDataReader::take_pointer (full) 00121 // Access: Public 00122 // Description: This is intended to be called only from 00123 // CycleDataWriter when it elevates the pointer from 00124 // read to write status. This function returns the 00125 // reader's pointer and relinquishes ownership of the 00126 // pointer, rendering the reader invalid for future 00127 // reads. 00128 //////////////////////////////////////////////////////////////////// 00129 template<class CycleDataType> 00130 INLINE const CycleDataType *CycleDataReader<CycleDataType>:: 00131 take_pointer() { 00132 const CycleDataType *pointer = _pointer; 00133 _pointer = (CycleDataType *)NULL; 00134 _write_pointer = (CycleDataType *)NULL; 00135 nassertr(pointer != (const CycleDataType *)NULL, _cycler->cheat()); 00136 return pointer; 00137 } 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: CycleDataReader::elevate_to_write (full) 00141 // Access: Public 00142 // Description: Call this to permanently elevate the readable pointer 00143 // to a writable pointer. This returns a writable 00144 // pointer; subsequent calls to the same function will 00145 // trivially return the same writable pointer. 00146 //////////////////////////////////////////////////////////////////// 00147 template<class CycleDataType> 00148 INLINE CycleDataType *CycleDataReader<CycleDataType>:: 00149 elevate_to_write(PipelineCycler<CycleDataType> &cycler) { 00150 nassertr(&cycler = &_cycler, cycler.cheat()); 00151 if (_write_pointer == (CycleDataType *)NULL) { 00152 _write_pointer = cycler.elevate_read(_pointer); 00153 _pointer = _write_pointer; 00154 } 00155 return _write_pointer; 00156 } 00157 00158 #else // !DO_PIPELINING 00159 // This is the trivial, do-nothing implementation. 00160 00161 //////////////////////////////////////////////////////////////////// 00162 // Function: CycleDataReader::Constructor (trivial) 00163 // Access: Public 00164 // Description: 00165 //////////////////////////////////////////////////////////////////// 00166 template<class CycleDataType> 00167 INLINE CycleDataReader<CycleDataType>:: 00168 CycleDataReader(const PipelineCycler<CycleDataType> &cycler) { 00169 _pointer = cycler.read(); 00170 } 00171 00172 //////////////////////////////////////////////////////////////////// 00173 // Function: CycleDataReader::Copy Constructor (trivial) 00174 // Access: Public 00175 // Description: 00176 //////////////////////////////////////////////////////////////////// 00177 template<class CycleDataType> 00178 INLINE CycleDataReader<CycleDataType>:: 00179 CycleDataReader(const CycleDataReader<CycleDataType> ©) : 00180 _pointer(copy._pointer) 00181 { 00182 } 00183 00184 //////////////////////////////////////////////////////////////////// 00185 // Function: CycleDataReader::Copy Assignment (trivial) 00186 // Access: Public 00187 // Description: 00188 //////////////////////////////////////////////////////////////////// 00189 template<class CycleDataType> 00190 INLINE void CycleDataReader<CycleDataType>:: 00191 operator = (const CycleDataReader<CycleDataType> ©) { 00192 _pointer = copy._pointer; 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: CycleDataReader::Destructor (trivial) 00197 // Access: Public 00198 // Description: 00199 //////////////////////////////////////////////////////////////////// 00200 template<class CycleDataType> 00201 INLINE CycleDataReader<CycleDataType>:: 00202 ~CycleDataReader() { 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: CycleDataReader::operator -> (trivial) 00207 // Access: Public 00208 // Description: This provides an indirect member access to the actual 00209 // CycleData data. 00210 //////////////////////////////////////////////////////////////////// 00211 template<class CycleDataType> 00212 INLINE const CycleDataType *CycleDataReader<CycleDataType>:: 00213 operator -> () const { 00214 return _pointer; 00215 } 00216 00217 //////////////////////////////////////////////////////////////////// 00218 // Function: CycleDataReader::Typecast pointer (trivial) 00219 // Access: Public 00220 // Description: This allows the CycleDataReader to be passed to any 00221 // function that expects a const CycleDataType pointer. 00222 //////////////////////////////////////////////////////////////////// 00223 template<class CycleDataType> 00224 INLINE CycleDataReader<CycleDataType>:: 00225 operator const CycleDataType * () const { 00226 return _pointer; 00227 } 00228 00229 //////////////////////////////////////////////////////////////////// 00230 // Function: CycleDataReader::take_pointer (trivial) 00231 // Access: Public 00232 // Description: This is intended to be called only from 00233 // CycleDataWriter when it elevates the pointer from 00234 // read to write status. This function returns the 00235 // reader's pointer and relinquishes ownership of the 00236 // pointer, rendering the reader invalid for future 00237 // reads. 00238 //////////////////////////////////////////////////////////////////// 00239 template<class CycleDataType> 00240 INLINE const CycleDataType *CycleDataReader<CycleDataType>:: 00241 take_pointer() { 00242 return _pointer; 00243 } 00244 00245 //////////////////////////////////////////////////////////////////// 00246 // Function: CycleDataReader::elevate_to_write (trivial) 00247 // Access: Public 00248 // Description: Call this to permanently elevate the readable pointer 00249 // to a writable pointer. This returns a writable 00250 // pointer; subsequent calls to the same function will 00251 // trivially return the same writable pointer. 00252 //////////////////////////////////////////////////////////////////// 00253 template<class CycleDataType> 00254 INLINE CycleDataType *CycleDataReader<CycleDataType>:: 00255 elevate_to_write(PipelineCycler<CycleDataType> &cycler) { 00256 return (CycleDataType *)_pointer; 00257 } 00258 00259 #endif // DO_PIPELINING