00001 // Filename: updateSeq.I 00002 // Created by: drose (30Sep99) 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: UpdateSeq::Default Constructor 00018 // Access: Published 00019 // Description: Creates an UpdateSeq in the 'initial' state. 00020 //////////////////////////////////////////////////////////////////// 00021 INLINE UpdateSeq:: 00022 UpdateSeq() { 00023 _seq = (unsigned int)SC_initial; 00024 } 00025 00026 //////////////////////////////////////////////////////////////////// 00027 // Function: UpdateSeq::initial (named constructor) 00028 // Access: Published, Static 00029 // Description: Returns an UpdateSeq in the 'initial' state. 00030 //////////////////////////////////////////////////////////////////// 00031 INLINE UpdateSeq UpdateSeq:: 00032 initial() { 00033 return UpdateSeq(); 00034 } 00035 00036 //////////////////////////////////////////////////////////////////// 00037 // Function: UpdateSeq::old (named constructor) 00038 // Access: Published, Static 00039 // Description: Returns an UpdateSeq in the 'old' state. 00040 //////////////////////////////////////////////////////////////////// 00041 INLINE UpdateSeq UpdateSeq:: 00042 old() { 00043 UpdateSeq result; 00044 result._seq = (unsigned int)SC_old; 00045 return result; 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: UpdateSeq::fresh (named constructor) 00050 // Access: Published, Static 00051 // Description: Returns an UpdateSeq in the 'fresh' state. 00052 //////////////////////////////////////////////////////////////////// 00053 INLINE UpdateSeq UpdateSeq:: 00054 fresh() { 00055 UpdateSeq result; 00056 result._seq = (unsigned int)SC_fresh; 00057 return result; 00058 } 00059 00060 //////////////////////////////////////////////////////////////////// 00061 // Function: UpdateSeq::Copy Constructor 00062 // Access: Published 00063 // Description: 00064 //////////////////////////////////////////////////////////////////// 00065 INLINE UpdateSeq:: 00066 UpdateSeq(const UpdateSeq ©) { 00067 _seq = AtomicAdjust::get(copy._seq); 00068 } 00069 00070 //////////////////////////////////////////////////////////////////// 00071 // Function: UpdateSeq::Copy Assignment operator 00072 // Access: Published 00073 // Description: 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE UpdateSeq &UpdateSeq:: 00076 operator = (const UpdateSeq ©) { 00077 AtomicAdjust::set(_seq, AtomicAdjust::get(copy._seq)); 00078 return *this; 00079 } 00080 00081 //////////////////////////////////////////////////////////////////// 00082 // Function: UpdateSeq::clear 00083 // Access: Published 00084 // Description: Resets the UpdateSeq to the 'initial' state. 00085 //////////////////////////////////////////////////////////////////// 00086 INLINE void UpdateSeq:: 00087 clear() { 00088 AtomicAdjust::set(_seq, (AtomicAdjust::Integer)SC_initial); 00089 } 00090 00091 //////////////////////////////////////////////////////////////////// 00092 // Function: UpdateSeq::is_initial 00093 // Access: Published 00094 // Description: Returns true if the UpdateSeq is in the 'initial' 00095 // state. 00096 //////////////////////////////////////////////////////////////////// 00097 INLINE bool UpdateSeq:: 00098 is_initial() const { 00099 return AtomicAdjust::get(_seq) == (AtomicAdjust::Integer)SC_initial; 00100 } 00101 00102 //////////////////////////////////////////////////////////////////// 00103 // Function: UpdateSeq::is_old 00104 // Access: Published 00105 // Description: Returns true if the UpdateSeq is in the 'old' state. 00106 //////////////////////////////////////////////////////////////////// 00107 INLINE bool UpdateSeq:: 00108 is_old() const { 00109 return AtomicAdjust::get(_seq) == (AtomicAdjust::Integer)SC_old; 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: UpdateSeq::is_fresh 00114 // Access: Published 00115 // Description: Returns true if the UpdateSeq is in the 'fresh' 00116 // state. 00117 //////////////////////////////////////////////////////////////////// 00118 INLINE bool UpdateSeq:: 00119 is_fresh() const { 00120 return AtomicAdjust::get(_seq) == (AtomicAdjust::Integer)SC_fresh; 00121 } 00122 00123 //////////////////////////////////////////////////////////////////// 00124 // Function: UpdateSeq::is_special 00125 // Access: Published 00126 // Description: Returns true if the UpdateSeq is in any special 00127 // states, i.e. 'initial', 'old', or 'fresh'. 00128 //////////////////////////////////////////////////////////////////// 00129 INLINE bool UpdateSeq:: 00130 is_special() const { 00131 // This relies on the assumption that (~0 + 1) == 0. 00132 return ((AtomicAdjust::get(_seq) + 1) <= 2); 00133 } 00134 00135 //////////////////////////////////////////////////////////////////// 00136 // Function: UpdateSeq::Equality operator 00137 // Access: Published 00138 // Description: 00139 //////////////////////////////////////////////////////////////////// 00140 INLINE bool UpdateSeq:: 00141 operator == (const UpdateSeq &other) const { 00142 return AtomicAdjust::get(_seq) == AtomicAdjust::get(other._seq); 00143 } 00144 00145 //////////////////////////////////////////////////////////////////// 00146 // Function: UpdateSeq::Inequality operator 00147 // Access: Published 00148 // Description: 00149 //////////////////////////////////////////////////////////////////// 00150 INLINE bool UpdateSeq:: 00151 operator != (const UpdateSeq &other) const { 00152 return AtomicAdjust::get(_seq) != AtomicAdjust::get(other._seq); 00153 } 00154 00155 //////////////////////////////////////////////////////////////////// 00156 // Function: UpdateSeq::Comparison operator 00157 // Access: Published 00158 // Description: 00159 //////////////////////////////////////////////////////////////////// 00160 INLINE bool UpdateSeq:: 00161 operator < (const UpdateSeq &other) const { 00162 return priv_lt(AtomicAdjust::get(_seq), AtomicAdjust::get(other._seq)); 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: UpdateSeq::Comparison operator 00167 // Access: Published 00168 // Description: 00169 //////////////////////////////////////////////////////////////////// 00170 INLINE bool UpdateSeq:: 00171 operator <= (const UpdateSeq &other) const { 00172 return priv_le(AtomicAdjust::get(_seq), AtomicAdjust::get(other._seq)); 00173 } 00174 00175 //////////////////////////////////////////////////////////////////// 00176 // Function: UpdateSeq::Comparison operator 00177 // Access: Published 00178 // Description: 00179 //////////////////////////////////////////////////////////////////// 00180 INLINE bool UpdateSeq:: 00181 operator > (const UpdateSeq &other) const { 00182 return (other < (*this)); 00183 } 00184 00185 //////////////////////////////////////////////////////////////////// 00186 // Function: UpdateSeq::Comparison operator 00187 // Access: Published 00188 // Description: 00189 //////////////////////////////////////////////////////////////////// 00190 INLINE bool UpdateSeq:: 00191 operator >= (const UpdateSeq &other) const { 00192 return (other <= (*this)); 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: UpdateSeq::Preincrement operator 00197 // Access: Published 00198 // Description: 00199 //////////////////////////////////////////////////////////////////// 00200 INLINE UpdateSeq UpdateSeq:: 00201 operator ++ () { 00202 AtomicAdjust::Integer old_seq = AtomicAdjust::get(_seq); 00203 AtomicAdjust::Integer new_seq = old_seq + 1; 00204 if (priv_is_special(new_seq)) { 00205 // Oops, wraparound. We don't want to confuse the new value 00206 // with our special cases. 00207 new_seq = (AtomicAdjust::Integer)SC_old + 1; 00208 } 00209 00210 #ifdef HAVE_THREADS 00211 AtomicAdjust::Integer result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq); 00212 while (result != old_seq) { 00213 // Some other thread beat us to it; try again. 00214 old_seq = AtomicAdjust::get(_seq); 00215 new_seq = old_seq + 1; 00216 if (priv_is_special(new_seq)) { 00217 // Oops, wraparound. We don't want to confuse the new value 00218 // with our special cases. 00219 new_seq = (AtomicAdjust::Integer)SC_old + 1; 00220 } 00221 result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq); 00222 } 00223 #else 00224 _seq = new_seq; 00225 #endif // HAVE_THREADS 00226 00227 return *this; 00228 } 00229 00230 //////////////////////////////////////////////////////////////////// 00231 // Function: UpdateSeq::Postincrement operator 00232 // Access: Published 00233 // Description: 00234 //////////////////////////////////////////////////////////////////// 00235 INLINE UpdateSeq UpdateSeq:: 00236 operator ++ (int) { 00237 AtomicAdjust::Integer old_seq = AtomicAdjust::get(_seq); 00238 AtomicAdjust::Integer new_seq = old_seq + 1; 00239 if (priv_is_special(new_seq)) { 00240 // Oops, wraparound. We don't want to confuse the new value 00241 // with our special cases. 00242 new_seq = (AtomicAdjust::Integer)SC_old + 1; 00243 } 00244 00245 #ifdef HAVE_THREADS 00246 AtomicAdjust::Integer result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq); 00247 while (result != old_seq) { 00248 // Some other thread beat us to it; try again. 00249 old_seq = AtomicAdjust::get(_seq); 00250 new_seq = old_seq + 1; 00251 if (priv_is_special(new_seq)) { 00252 // Oops, wraparound. We don't want to confuse the new value 00253 // with our special cases. 00254 new_seq = (AtomicAdjust::Integer)SC_old + 1; 00255 } 00256 result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq); 00257 } 00258 #else 00259 _seq = new_seq; 00260 #endif // HAVE_THREADS 00261 00262 UpdateSeq temp; 00263 temp._seq = old_seq; 00264 return temp; 00265 } 00266 00267 //////////////////////////////////////////////////////////////////// 00268 // Function: UpdateSeq::output 00269 // Access: Published 00270 // Description: 00271 //////////////////////////////////////////////////////////////////// 00272 INLINE void UpdateSeq:: 00273 output(ostream &out) const { 00274 AtomicAdjust::Integer seq = AtomicAdjust::get(_seq); 00275 switch (seq) { 00276 case SC_initial: 00277 out << "initial"; 00278 break; 00279 00280 case SC_old: 00281 out << "old"; 00282 break; 00283 00284 case SC_fresh: 00285 out << "fresh"; 00286 break; 00287 00288 default: 00289 out << (unsigned int)seq; 00290 } 00291 } 00292 00293 //////////////////////////////////////////////////////////////////// 00294 // Function: UpdateSeq::priv_is_special 00295 // Access: Private, Static 00296 // Description: The private implementation of is_special(). 00297 //////////////////////////////////////////////////////////////////// 00298 INLINE bool UpdateSeq:: 00299 priv_is_special(AtomicAdjust::Integer seq) { 00300 // This relies on the assumption that (~0 + 1) == 0. 00301 return (((unsigned int)seq + 1) <= 2); 00302 } 00303 00304 //////////////////////////////////////////////////////////////////// 00305 // Function: UpdateSeq::priv_lt 00306 // Access: Private, Static 00307 // Description: The private implementation of operator < (). 00308 //////////////////////////////////////////////////////////////////// 00309 INLINE bool UpdateSeq:: 00310 priv_lt(AtomicAdjust::Integer a, AtomicAdjust::Integer b) { 00311 // The special cases of SC_initial or SC_old are less than all other 00312 // non-special numbers, and SC_initial is less than SC_old. The 00313 // special case of SC_fresh is greater than all other non-special 00314 // numbers. For all other cases, we use a circular comparision such 00315 // that n < m iff (signed)(n - m) < 0. 00316 return 00317 (priv_is_special(a) || priv_is_special(b)) ? ((unsigned int)a < (unsigned int)b) : 00318 ((signed int)(a - b) < 0); 00319 } 00320 00321 //////////////////////////////////////////////////////////////////// 00322 // Function: UpdateSeq::priv_le 00323 // Access: Private, Static 00324 // Description: The private implementation of operator <= (). 00325 //////////////////////////////////////////////////////////////////// 00326 INLINE bool UpdateSeq:: 00327 priv_le(AtomicAdjust::Integer a, AtomicAdjust::Integer b) { 00328 return (a == b) || priv_lt(a, b); 00329 } 00330 00331 INLINE ostream &operator << (ostream &out, const UpdateSeq &value) { 00332 value.output(out); 00333 return out; 00334 }