UniSet  2.2.1
HourGlass.h
00001 /* This file is part of the UniSet project
00002  * Copyright (c) 2002 Free Software Foundation, Inc.
00003  * Copyright (c) 2002 Pavel Vainerman
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018  */
00019 // --------------------------------------------------------------------------
00020 // idea: lav@etersoft.ru
00021 // realisation: pv@etersoft.ru, lav@etersoft.ru
00022 // --------------------------------------------------------------------------
00023 #ifndef HourGlass_H_
00024 #define HourGlass_H_
00025 // --------------------------------------------------------------------------
00026 #include "PassiveTimer.h"
00027 // --------------------------------------------------------------------------
00062 class HourGlass
00063 {
00064     public:
00065         HourGlass(): _state(false), _sand(0), _size(0) {}
00066         ~HourGlass() {}
00067 
00068         // запустить часы (заново)
00069         inline void run( timeout_t msec )
00070         {
00071             t.setTiming(msec);
00072             _state   = true;
00073             _sand    = msec;
00074             _size    = msec;
00075         }
00076 
00077         inline void reset()
00078         {
00079             run(_size);
00080         }
00081 
00082         // "ёмкость" песочных часов..
00083         inline int duration()
00084         {
00085             return _size;
00086         }
00087         // перевернуть часы
00088         // true - засечь время
00089         // false - перевернуть часы (обратный ход)
00090         // возвращает аргумент (т.е. идёт ли отсчёт времени)
00091         inline bool rotate( bool st )
00092         {
00093             if( st == _state )
00094                 return st;
00095 
00096             _state = st;
00097 
00098             // TODO 24.10.2015 Lav: follow code is very simular to remain function
00099             if( !_state )
00100             {
00101                 timeout_t cur = t.getCurrent();
00102 
00103                 if( cur > _size )
00104                     cur = _size;
00105 
00106                 _sand = ( _sand > cur ) ? (_sand - cur) : 0;
00107 
00108                 t.setTiming(cur);
00109             }
00110             else
00111             {
00112                 timeout_t cur = t.getCurrent();
00113 
00114                 if( cur > _size )
00115                     cur = _size;
00116 
00117                 _sand += cur;
00118 
00119                 if( _sand > _size )
00120                     _sand = _size;
00121 
00122                 t.setTiming(_sand);
00123             }
00124 
00125             return st;
00126         }
00127 
00128         // получить прошедшее время
00129         inline timeout_t current()
00130         {
00131             return t.getCurrent();
00132         }
00133 
00134         // получить заданное время
00135         inline timeout_t interval()
00136         {
00137             return t.getInterval();
00138         }
00139 
00140         // проверить наступление
00141         inline bool check()
00142         {
00143             // пока часы не "стоят"
00144             // всегда false
00145             if( !_state )
00146                 return false;
00147 
00148             return t.checkTime();
00149         }
00150 
00151         inline bool enabled()
00152         {
00153             return _state;
00154         }
00155 
00156         // текущее "насыпавшееся" количество "песка" (прошедшее время)
00157         inline timeout_t amount()
00158         {
00159             return ( _size - remain() );
00160         }
00161 
00162         // остаток песка (времени) (оставшееся время)
00163         inline timeout_t remain()
00164         {
00165             timeout_t c = t.getCurrent();
00166 
00167             if( c > _size )
00168                 c = _size;
00169 
00170             // _state=false - означает, что песок пересыпается обратно..
00171             if( !_state )
00172             {
00173                 timeout_t ret = ( _sand + c );
00174 
00175                 if( ret > _size )
00176                     return _size;
00177 
00178                 return ret;
00179             }
00180 
00181             // _state=true  - означает, что песок пересыпается..
00182             int ret = ( _sand - c );
00183 
00184             if( ret < 0 )
00185                 return 0;
00186 
00187             return ret;
00188         }
00189 
00190     protected:
00191         PassiveTimer t;   
00192         bool _state;      
00193         timeout_t _sand;  
00194         timeout_t _size;  
00195 };
00196 // --------------------------------------------------------------------------
00197 #endif
00198 // --------------------------------------------------------------------------