libmoost
/home/mhx/git/github/libmoost/include/moost/progress/policy/spinner.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_UTILS_PROGRESS_POLICY_SPINNER_HPP__
00029 #define MOOST_UTILS_PROGRESS_POLICY_SPINNER_HPP__
00030 
00031 #include <vector>
00032 #include <iostream>
00033 #include <iomanip>
00034 
00035 #include <boost/date_time/posix_time/posix_time_types.hpp>
00036 #include <boost/thread/thread_time.hpp>
00037 
00038 namespace moost { namespace progress { namespace policy {
00039 
00040    class spinner
00041    {
00042    public:
00043       typedef size_t counter_type;
00044 
00045       spinner(size_t msecs = 500, std::ostream & out = std::cout)
00046          : counter_(0), msecs_(msecs), out_(out), ptime_(boost::get_system_time())
00047       {
00048          frames_.push_back('|');
00049          frames_.push_back('/');
00050          frames_.push_back('-');
00051          frames_.push_back('\\');
00052 
00053          frame_ = frames_.begin();
00054       }
00055 
00056       counter_type  operator+=(counter_type const incr)
00057       {
00058          boost::posix_time::ptime now = boost::get_system_time();
00059 
00060          if(now >= ptime_)
00061          {
00062             animate();
00063             ptime_ = now + boost::posix_time::milliseconds(msecs_);
00064          }
00065 
00066          return counter_ += incr;
00067       }
00068 
00069       counter_type operator ++ ()
00070       {
00071          return *this += 1;
00072       }
00073 
00074       counter_type operator ++ (int)
00075       {
00076          counter_type const tmp = counter_;
00077          ++*this;
00078          return tmp;
00079       }
00080 
00081       counter_type count() const
00082       {
00083          return counter_;
00084       }
00085 
00086       counter_type expected_count() const
00087       {
00088          return counter_;
00089       }
00090 
00091    private:
00092       void animate()
00093       {
00094          out_ << *frame_++ << '\r' << std::flush;
00095          if(frame_ == frames_.end())
00096          {
00097             frame_ = frames_.begin();
00098          }
00099       }
00100 
00101       std::vector<char> frames_;
00102       std::vector<char>::const_iterator frame_;
00103       counter_type counter_;
00104       size_t const msecs_; // the min number of milliseconds before we'll update spinner
00105       std::ostream & out_;
00106       boost::posix_time::ptime ptime_;
00107    };
00108 
00109 }}}
00110 
00111 #endif // MOOST_UTILS_PROGRESS_POLICY_SPINNER_HPP__