Orocos Real-Time Toolkit  2.9.0
BufferUnSync.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Thu Oct 22 11:59:07 CEST 2009 BufferUnSync.hpp
3 
4  BufferUnSync.hpp - description
5  -------------------
6  begin : Thu October 22 2009
7  copyright : (C) 2009 Peter Soetens
8  email : peter@thesourcworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 
40 #ifndef ORO_CORELIB_BUFFER_UNSYNC_HPP
41 #define ORO_CORELIB_BUFFER_UNSYNC_HPP
42 
43 #include "BufferInterface.hpp"
44 #include <deque>
45 
46 namespace RTT
47 { namespace base {
48 
49 
57  template<class T>
59  :public BufferInterface<T>
60  {
61  public:
62  typedef typename BufferBase::Options Options;
66  typedef T value_t;
67 
71  BufferUnSync( size_type size, const Options &options = Options() )
72  : cap(size), buf(), mcircular(options.circular()), initialized(false), droppedSamples(0)
73  {
74  }
75 
79  BufferUnSync( size_type size, param_t initial_value, const Options &options = Options() )
80  : cap(size), buf(), mcircular(options.circular()), initialized(false), droppedSamples(0)
81  {
82  data_sample(initial_value);
83  }
84 
85  virtual bool data_sample( param_t sample, bool reset = true )
86  {
87  if (!initialized || reset) {
88  buf.resize(cap, sample);
89  buf.resize(0);
90  return true;
91  } else {
92  return initialized;
93  }
94  }
95 
96  virtual value_t data_sample() const
97  {
98  return lastSample;
99  }
100 
105 
106  bool Push( param_t item )
107  {
108  if (cap == (size_type)buf.size() ) {
109  //buffer is full, we either overwrite a sample, or drop the given one
110  droppedSamples++;
111  if (!mcircular)
112  {
113  return false;
114  }
115  else
116  {
117  buf.pop_front();
118  }
119  }
120  buf.push_back( item );
121  return true;
122  }
123 
124  size_type Push(const std::vector<value_t>& items)
125  {
126  typename std::vector<value_t>::const_iterator itl( items.begin() );
127  if (mcircular && (size_type)items.size() >= cap ) {
128  // clear out current data and reset iterator to first element we're going to take.
129  buf.clear();
130  //note the ignored samples are added below to the dropped samples.
131  droppedSamples += cap;
132  itl = items.begin() + ( items.size() - cap );
133  } else if ( mcircular && (size_type)(buf.size() + items.size()) > cap) {
134  // drop excess elements from front
135  assert( (size_type)items.size() < cap );
136  while ( (size_type)(buf.size() + items.size()) > cap )
137  {
138  droppedSamples++;
139  buf.pop_front();
140  }
141  // itl still points at first element of items.
142  }
143  while ( ((size_type)buf.size() != cap) && (itl != items.end()) ) {
144  buf.push_back( *itl );
145  ++itl;
146  }
147 
148  size_type written = (itl - items.begin());
149 
150  droppedSamples += items.size() - written;
151 
152  return written;
153  }
154 
155  FlowStatus Pop( reference_t item )
156  {
157  if ( buf.empty() ) {
158  return NoData;
159  }
160  item = buf.front();
161  buf.pop_front();
162  return NewData;
163  }
164 
165  size_type Pop(std::vector<value_t>& items )
166  {
167  int quant = 0;
168  items.clear();
169  while ( !buf.empty() ) {
170  items.push_back( buf.front() );
171  buf.pop_front();
172  ++quant;
173  }
174  return quant;
175  }
176 
177  value_t* PopWithoutRelease()
178  {
179  if(buf.empty())
180  return 0;
181 
182  //note we need to copy the sample, as
183  //front is not garanteed to be valid after
184  //any other operation on the deque
185  lastSample = buf.front();
186  buf.pop_front();
187  return &lastSample;
188  }
189 
190  void Release(value_t *item)
191  {
192  //we do not need to release any memory, but we can check
193  //if the other side messed up
194  assert(item == &lastSample && "Wrong pointer given back to buffer");
195  }
196 
197  size_type capacity() const {
198  return cap;
199  }
200 
201  size_type size() const {
202  return buf.size();
203  }
204 
205  void clear() {
206  buf.clear();
207  }
208 
209  bool empty() const {
210  return buf.empty();
211  }
212 
213  bool full() const {
214  return (size_type)buf.size() == cap;
215  }
216 
217  virtual size_type dropped() const
218  {
219  return droppedSamples;
220  }
221  private:
222  size_type cap;
223  std::deque<value_t> buf;
224  value_t lastSample;
225  const bool mcircular;
226  bool initialized;
227  size_type droppedSamples;
228  };
229 }}
230 
231 #endif // BUFFERSIMPLE_HPP
value_t * PopWithoutRelease()
Returns a pointer to the first element in the buffer.
FlowStatus Pop(reference_t item)
Read the oldest value from the buffer.
BufferUnSync(size_type size, const Options &options=Options())
Create an uninitialized buffer of size size.
size_type size() const
Returns the actual number of items that are stored in the buffer.
BufferInterface< T >::size_type size_type
bool empty() const
Check if this buffer is empty.
BufferInterface< T >::param_t param_t
boost::call_traits< T >::reference reference_t
BufferUnSync(size_type size, param_t initial_value, const Options &options=Options())
Create a buffer of size size.
A Buffer is an object which is used to store (Push) and retrieve (Pop) values from.
FlowStatus
Returns the status of a data flow read operation.
Definition: FlowStatus.hpp:56
size_type capacity() const
Returns the maximum number of items that can be stored in the buffer.
boost::call_traits< T >::param_type param_t
BufferBase::Options Options
BufferInterface< T >::reference_t reference_t
~BufferUnSync()
Destructor.
size_type Pop(std::vector< value_t > &items)
Read the whole buffer.
Implements a not threadsafe buffer.
BufferBase::size_type size_type
virtual bool data_sample(param_t sample, bool reset=true)
Initializes this buffer with a data sample, such that for dynamical allocated types T...
size_type Push(const std::vector< value_t > &items)
Write a sequence of values to the buffer.
virtual value_t data_sample() const
Reads back a data sample.
bool Push(param_t item)
Write a single value to the buffer.
bool full() const
Check if this buffer is full.
void clear()
Clears all contents of this buffer.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
virtual size_type dropped() const
Returns the number of dropped samples, because the buffer was full.
void Release(value_t *item)
Releases the pointer.