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

panda/src/express/circBuffer.I

Go to the documentation of this file.
00001 // Filename: circBuffer.I
00002 // Created by:  drose (08Feb99)
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 #include <pandabase.h>
00020 
00021 #include "config_express.h"
00022 
00023 #include <notify.h>
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: CircBuffer::Constructor
00027 //       Access: Public
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 template<class Thing, int max_size>
00031 INLINE CircBuffer<Thing, max_size>::
00032 CircBuffer() {
00033   _in = _out = 0;
00034 }
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: CircBuffer::Destructor
00038 //       Access: Public
00039 //  Description:
00040 ////////////////////////////////////////////////////////////////////
00041 template<class Thing, int max_size>
00042 INLINE CircBuffer<Thing, max_size>::
00043 ~CircBuffer() {
00044 }
00045 
00046 ////////////////////////////////////////////////////////////////////
00047 //     Function: CircBuffer::size
00048 //       Access: Public
00049 //  Description: Returns the number of items currently in the buffer.
00050 //               This can safely be called without synchronization
00051 //               from either the reader or the writer thread, but the
00052 //               size may of course vary without warning after the
00053 //               call.
00054 ////////////////////////////////////////////////////////////////////
00055 template<class Thing, int max_size>
00056 INLINE int CircBuffer<Thing, max_size>::
00057 size() const {
00058   int diff = _in - _out;
00059   return (diff >= 0) ? diff : max_size + 1 + diff;
00060 }
00061 
00062 ////////////////////////////////////////////////////////////////////
00063 //     Function: CircBuffer::empty
00064 //       Access: Public
00065 //  Description: Returns true if the buffer is empty.  It is safe to
00066 //               call this without synchronization primitives from
00067 //               either the reader or the writer thread, but the
00068 //               result may vary without warning after the call.
00069 ////////////////////////////////////////////////////////////////////
00070 template<class Thing, int max_size>
00071 INLINE bool CircBuffer<Thing, max_size>::
00072 empty() const {
00073   return _in == _out;
00074 }
00075 
00076 ////////////////////////////////////////////////////////////////////
00077 //     Function: CircBuffer::full
00078 //       Access: Public
00079 //  Description: Returns true if the buffer is full; if this is true,
00080 //               push_back() will fail.  It is safe to call this
00081 //               without synchronization primitives from either the
00082 //               reader or the writer thread, but the result may vary
00083 //               without warning after the call.
00084 ////////////////////////////////////////////////////////////////////
00085 template<class Thing, int max_size>
00086 INLINE bool CircBuffer<Thing, max_size>::
00087 full() const {
00088   //  return _in == _out-1 || (_in==max_size && _out==0);
00089   return ((_in + 1) % (max_size + 1)) == _out;
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: CircBuffer::front
00094 //       Access: Public
00095 //  Description: Returns a reference to the first item in the queue.
00096 //               It is invalid to call this if empty() is true.  It is
00097 //               safe to call this without synchronization only from
00098 //               the reading thread: the thread that calls pop_front().
00099 ////////////////////////////////////////////////////////////////////
00100 template<class Thing, int max_size>
00101 INLINE const Thing &CircBuffer<Thing, max_size>::
00102 front() const {
00103   nassertr(!empty(), _array[0]);
00104   return _array[_out];
00105 }
00106 
00107 ////////////////////////////////////////////////////////////////////
00108 //     Function: CircBuffer::front
00109 //       Access: Public
00110 //  Description: Returns a reference to the first item in the queue.
00111 //               It is invalid to call this if empty() is true.  It is
00112 //               safe to call this without synchronization only from
00113 //               the reading thread: the thread that calls pop_front().
00114 ////////////////////////////////////////////////////////////////////
00115 template<class Thing, int max_size>
00116 INLINE Thing &CircBuffer<Thing, max_size>::
00117 front() {
00118   nassertr(!empty(), _array[0]);
00119   return _array[_out];
00120 }
00121 
00122 ////////////////////////////////////////////////////////////////////
00123 //     Function: CircBuffer::operator []
00124 //       Access: Public
00125 //  Description: Returns the nth element in the buffer.  It is safe to
00126 //               call this without synchronization only from the
00127 //               reading thread: the thread that calls pop_front().
00128 ////////////////////////////////////////////////////////////////////
00129 template<class Thing, int max_size>
00130 INLINE const Thing &CircBuffer<Thing, max_size>::
00131 operator[] (int n) const {
00132   nassertr(!empty(), _array[0]);
00133   return _array[(_out + n) % (max_size + 1)];
00134 }
00135 
00136 ////////////////////////////////////////////////////////////////////
00137 //     Function: CircBuffer::operator []
00138 //       Access: Public
00139 //  Description: Returns the nth element in the buffer.  It is safe to
00140 //               call this without synchronization only from the
00141 //               reading thread: the thread that calls pop_front().
00142 ////////////////////////////////////////////////////////////////////
00143 template<class Thing, int max_size>
00144 INLINE Thing &CircBuffer<Thing, max_size>::
00145 operator[] (int n) {
00146   nassertr(!empty(), _array[0]);
00147   return _array[(_out + n) % (max_size + 1)];
00148 }
00149 
00150 
00151 ////////////////////////////////////////////////////////////////////
00152 //     Function: CircBuffer::pop_front
00153 //       Access: Public
00154 //  Description: Removes the first item from the buffer.
00155 ////////////////////////////////////////////////////////////////////
00156 template<class Thing, int max_size>
00157 INLINE void CircBuffer<Thing, max_size>::
00158 pop_front() {
00159   nassertv(!empty());
00160 
00161   // We need to clear out the old element to force its destructor to
00162   // be called; it might be important.  This will generate yet another
00163   // UMR warning in Purify if the default constructor doesn't fully
00164   // initialize the class.
00165   _array[_out] = Thing();
00166 
00167   _out = (_out+1)%(max_size+1);
00168 }
00169 
00170 
00171 
00172 
00173 ////////////////////////////////////////////////////////////////////
00174 //     Function: CircBuffer::back
00175 //       Access: Public
00176 //  Description: Returns a reference to the last item in the queue.
00177 //               It is invalid to call this if empty() is true.  It is
00178 //               safe to call this without synchronization primitives
00179 //               only from the writing thread: the thread that calls
00180 //               push_back().
00181 ////////////////////////////////////////////////////////////////////
00182 template<class Thing, int max_size>
00183 INLINE const Thing &CircBuffer<Thing, max_size>::
00184 back() const {
00185   nassertr(!empty(), _array[0]);
00186   return _array[(_in + max_size) % (max_size + 1)];
00187 }
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: CircBuffer::back
00191 //       Access: Public
00192 //  Description: Returns a reference to the last item in the queue.
00193 //               It is invalid to call this if empty() is true.  It is
00194 //               safe to call this without synchronization primitives
00195 //               only from the writing thread: the thread that calls
00196 //               push_back().
00197 ////////////////////////////////////////////////////////////////////
00198 template<class Thing, int max_size>
00199 INLINE Thing &CircBuffer<Thing, max_size>::
00200 back() {
00201   nassertr(!empty(), _array[0]);
00202   return _array[(_in + max_size) % (max_size + 1)];
00203 }
00204 
00205 ////////////////////////////////////////////////////////////////////
00206 //     Function: CircBuffer::push_back
00207 //       Access: Public
00208 //  Description: Adds an item to the end of the buffer.  This may fail
00209 //               if full() is true.
00210 ////////////////////////////////////////////////////////////////////
00211 template<class Thing, int max_size>
00212 INLINE void CircBuffer<Thing, max_size>::
00213 push_back(const Thing &t) {
00214   if (full()) {
00215     express_cat.error()
00216       << "Circular buffer is full; cannot add requests.\n";
00217   } else {
00218     _array[_in] = t;
00219     _in = (_in+1)%(max_size+1);
00220   }
00221 }

Generated on Fri May 2 00:38:18 2003 for Panda by doxygen1.3