Panda3D
 All Classes Functions Variables Enumerations
updateSeq.I
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 &copy) {
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 &copy) {
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 }
 All Classes Functions Variables Enumerations