CCA
SingleItemBuffer.h
Go to the documentation of this file.
00001 /* ============================================================
00002  *
00003  * This file is a part of CCA project
00004  *
00005  * Copyright (C) 2011 by Arne Nordmann <anordman at cor-lab dot uni-bielefeld dot de>
00006  *
00007  * This file may be licensed under the terms of the
00008  * GNU Lesser General Public License Version 3 (the ``LGPL''),
00009  * or (at your option) any later version.
00010  *
00011  * Software distributed under the License is distributed
00012  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
00013  * express or implied. See the LGPL for the specific language
00014  * governing rights and limitations.
00015  *
00016  * You should have received a copy of the LGPL along with this
00017  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
00018  * or write to the Free Software Foundation, Inc.,
00019  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  * The development of this software was supported by:
00022  *   CoR-Lab, Research Institute for Cognition and Robotics
00023  *     Bielefeld University
00024  *
00025  * ============================================================ */
00026 
00027 #pragma once
00028 
00029 #include <string>
00030 #include <sstream>
00031 #include <iostream>
00032 #include <exception>
00033 
00034 #include <boost/thread/recursive_mutex.hpp>
00035 
00036 #include "cca/buffer/Buffer.h"
00037 
00038 namespace cca {
00039 
00047 template<class DATATYPE>
00048 class SingleItemBuffer: public Buffer<DATATYPE> {
00049 public:
00050 
00052     typedef ::boost::shared_ptr<SingleItemBuffer<DATATYPE> > Ptr;
00053 
00055     typedef ::boost::shared_ptr<DATATYPE> DataPtr;
00056 
00063     SingleItemBuffer(bool alwaysKeepLatest = true) :
00064             Buffer<DATATYPE>(alwaysKeepLatest), _buffer(), bufferMutex() {
00065     }
00066 
00067     virtual ~SingleItemBuffer() {
00068     }
00069 
00073     std::string print() const {
00074         std::ostringstream outstream(std::ostringstream::out);
00075         outstream.precision(3); // Precision when printing double values
00076         outstream << "SingleItemBuffer";
00077         if (this->keepLatest) {
00078             outstream << ", keep latest";
00079             if (this->warm) {
00080                 outstream << " (warm)";
00081             } else {
00082                 outstream << " (cold)";
00083             }
00084         }
00085         if (this->newItem()) {
00086             outstream << ", 1 new item";
00087         }
00088         return outstream.str();
00089     }
00090 
00097     virtual DataPtr get() throw () {
00098         boost::recursive_mutex::scoped_lock scoped_lock(bufferMutex);
00099         if (this->keepLatest && this->warm) {
00100             this->numItems = 0;
00101             this->newitem = false;
00102             return _buffer;
00103         }
00104 
00105         if (this->empty()) {
00106             throw std::runtime_error("Single Item Buffer is empty.");
00107         }
00108 
00109         DataPtr item = this->_buffer;
00110         this->_buffer = DataPtr();
00111         this->numItems = 0;
00112         this->newitem = false;
00113         return item;
00114     }
00115 
00122     virtual void add(DataPtr item) {
00123         boost::recursive_mutex::scoped_lock scoped_lock(bufferMutex);
00124         this->_buffer = item;
00125         this->numItems = 1;
00126         this->newitem = true;
00127         this->warm = true;
00128     }
00129 
00133     virtual void purge() {
00134         boost::recursive_mutex::scoped_lock scoped_lock(bufferMutex);
00135         this->_buffer = DataPtr();
00136         this->numItems = 0;
00137         this->newitem = false;
00138         this->warm = false;
00139     }
00140 
00141 private:
00143     SingleItemBuffer(SingleItemBuffer &buffer);
00144 
00146     void operator=(const SingleItemBuffer &buffer);
00147 
00148     DataPtr _buffer;
00149     mutable boost::recursive_mutex bufferMutex;
00150 };
00151 
00152 }