Commit a5d9315a authored by Pavel Vainerman's avatar Pavel Vainerman

Переименовал SandClock --> HourGlass.

Добавил класс DelayTimer удобный для случаев, когда необходима задержка, отдельно на срабатывание и отдельно на отпускание..
parent 68bee78c
......@@ -3,7 +3,7 @@
Name: libuniset
Version: 1.5
Release: alt5
Release: alt6
Summary: UniSet - library for building distributed industrial control systems
License: GPL
Group: Development/C++
......@@ -211,6 +211,10 @@ rm -f %buildroot%_libdir/*.la
%exclude %_pkgconfigdir/libUniSet.pc
%changelog
* Thu Nov 29 2012 Pavel Vainerman <pv@altlinux.ru> 1.5-alt6
- add DelayTimer class
- rename SandClock --> HourGlass
* Fri Nov 23 2012 Pavel Vainerman <pv@altlinux.ru> 1.5-alt5
- (Calibration): add getLeftRaw(),getRightRaw(),getLeftVal(),getRightVal()
- (Calibration): fixed bugs
......
// --------------------------------------------------------------------------
#ifndef _COMPORT_H_
#define _COMPORT_H_
// --------------------------------------------------------------------------
#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string>
// --------------------------------------------------------------------------
class ComPort
{
public:
......@@ -114,5 +113,6 @@ protected:
private:
struct termios oldTermios;
};
// --------------------------------------------------------------------------
#endif // _COMPORT_H_
// --------------------------------------------------------------------------
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
#ifndef DelayTimer_H_
#define DelayTimer_H_
// --------------------------------------------------------------------------
#include "PassiveTimer.h"
// --------------------------------------------------------------------------
/*! Таймер реализующий задержку на срабатывание и отпускание сигнала.
Для проверки вызывается функция check( state ), где state - это текущее состояние
сигнала, а функция check() возвращает сигнал с задержкой.
Чтобы состояние переключилось, оно должно продержаться не менее заданного времени.
*/
class DelayTimer
{
public:
DelayTimer():prevState(false),state(false),
onDelay(0),offDelay(0),waiting_on(false),waiting_off(false){}
DelayTimer( timeout_t on_msec, timeout_t off_msec ):prevState(false),state(false),
onDelay(on_msec),offDelay(off_msec),waiting_on(false),waiting_off(false)
{
}
~DelayTimer(){}
// запустить часы (заново)
inline void set( timeout_t on_msec, timeout_t off_msec )
{
onDelay = on_msec;
offDelay = off_msec;
}
inline void reset()
{
pt.reset();
}
inline bool check( bool st )
{
if( waiting_off )
{
if( !st && pt.checkTime() )
{
waiting_off = false;
state = false;
return state;
}
else if( st != prevState )
pt.reset();
prevState = st;
return state;
}
if( waiting_on )
{
if( st && pt.checkTime() )
{
waiting_on = false;
state = true;
return state;
}
else if( st != prevState )
pt.reset();
prevState = st;
return state;
}
if( state != st )
{
prevState = st;
if( st )
{
pt.setTiming(onDelay);
waiting_on = true;
}
else
{
pt.setTiming(offDelay);
waiting_off = true;
}
if( pt.checkTime() )
return st;
}
return state;
}
protected:
PassiveTimer pt;
bool prevState;
bool state;
timeout_t onDelay;
timeout_t offDelay;
bool waiting_on;
bool waiting_off;
};
// --------------------------------------------------------------------------
#endif
// --------------------------------------------------------------------------
......@@ -20,19 +20,49 @@
// idea: lav@etersoft.ru
// realisation: pv@etersoft.ru, lav@etersoft.ru
// --------------------------------------------------------------------------
#ifndef SandClock_H_
#define SandClock_H_
#ifndef HourGlass_H_
#define HourGlass_H_
// --------------------------------------------------------------------------
#include "PassiveTimer.h"
// --------------------------------------------------------------------------
class SandClock
/*! Песочные часы. Класс реализующий логику песочных часов.
Удобен для создания задержек на срабатывание и на отпускание
(как фильтр от кратковременных изменений). Аналогия с песочными часами:
\par
Выставляете время(run).. устанавливаются в какое-то положение часы (rotate)...
песок сыплется... если весь пересыпался - срабатывает условие (check()==true).
Если во время работы условие изменилось (часы перевернули в обратную сторону), то
уже успевший пересыпаться песок, начинает пересыпаться в обратную сторону. Если опять
повернули часы... продолжает сыпаться опять (добвляясь к тому песку, что "не успел" высыпаться обратно).
и т.д. по кругу...
Класс является "пассивным", т.е. требует периодического вызова функции check, для проверки наступления условия срабатывания.
\par Пример использования.
Допустим у вас есть сигнал "перегрев"(in_overheating) и вам необходимо выставить какой-то
флаг о перегреве (isOverheating), если этот сигнал устойчиво держится в течение 10 секунд,
и при этом если сигнал снялся, то вам необходимо как минимум те же 10 секунд,
подождать прежде чем "снять" флаг. Для этого удобно использовать данный класс.
\code
HourGlass hg;
hg.run(10000); // настриваем часы на 10 сек..
while( ....)
{
hg.rotate(in_overheating); // управляем состоянием песочных часов (прямой или обратный ход).
isOverheating = hg.check();
}
\endcode
*/
class HourGlass
{
public:
SandClock(): _state(false),_sand(0),_size(0){}
~SandClock(){}
HourGlass(): _state(false),_sand(0),_size(0){}
~HourGlass(){}
// запустить часы (заново)
inline void run( int msec )
inline void run( timeout_t msec )
{
t.setTiming(msec);
_state = true;
......@@ -40,7 +70,7 @@ class SandClock
_size = msec;
}
inline void reset ()
inline void reset()
{
run(_size);
}
......@@ -90,14 +120,14 @@ class SandClock
// получить прошедшее время
// для положения st
inline int current( bool st )
inline timeout_t current( bool st )
{
return t.getCurrent();
}
// получить заданное время
// для положения st
inline int interval( bool st )
inline timeout_t interval( bool st )
{
return t.getInterval();
}
......@@ -119,7 +149,7 @@ class SandClock
PassiveTimer t;
bool _state;
int _sand;
int _size;
timeout_t _size;
};
// --------------------------------------------------------------------------
#endif
......
......@@ -4,12 +4,20 @@
SUBDIRS=JrnTests
noinst_PROGRAMS = passivetimer unixml ui umutex conftest iterator_test sscanf_hex calibration
noinst_PROGRAMS = passivetimer hourglass delaytimer unixml ui umutex conftest iterator_test sscanf_hex calibration
passivetimer_SOURCES = passivetimer.cc
passivetimer_LDADD = $(top_builddir)/lib/libUniSet.la
passivetimer_CPPFLAGS = -I$(top_builddir)/include
hourglass_SOURCES = hourglass.cc
hourglass_LDADD = $(top_builddir)/lib/libUniSet.la
hourglass_CPPFLAGS = -I$(top_builddir)/include
delaytimer_SOURCES = delaytimer.cc
delaytimer_LDADD = $(top_builddir)/lib/libUniSet.la
delaytimer_CPPFLAGS = -I$(top_builddir)/include
unixml_SOURCES = unixml.cc
unixml_LDADD = $(top_builddir)/lib/libUniSet.la ${SIGC_LIBS}
unixml_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS}
......
#include <iostream>
using namespace std;
#include "HourGlass.h"
#include "DelayTimer.h"
#include "UniSetTypes.h"
int main()
{
// ----------------------
// test DelayTimer
DelayTimer dtm(1000,500);
if( dtm.check(true) )
{
cerr << "DelayTimer: TEST1 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST1 OK!" << endl;
msleep(1100);
if( !dtm.check(true) )
{
cerr << "DelayTimer: TEST2 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST2 OK!" << endl;
if( !dtm.check(false) )
{
cerr << "DelayTimer: TEST3 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST3 OK!" << endl;
msleep(200);
if( !dtm.check(false) )
{
cerr << "DelayTimer: TEST4 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST4 OK!" << endl;
msleep(500);
if( dtm.check(false) )
{
cerr << "DelayTimer: TEST5 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST5 OK!" << endl;
dtm.check(true);
msleep(800);
if( dtm.check(true) )
{
cerr << "DelayTimer: TEST6 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST6 OK!" << endl;
dtm.check(false);
msleep(600);
if( dtm.check(false) )
{
cerr << "DelayTimer: TEST7 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST7 OK!" << endl;
dtm.check(true);
msleep(1100);
if( !dtm.check(true) )
{
cerr << "DelayTimer: TEST8 FAILED! " << endl;
return 1;
}
cout << "DelayTimer: TEST8 OK!" << endl;
DelayTimer dtm2(200,0);
dtm2.check(true);
msleep(250);
if( !dtm2.check(true) )
{
cerr << "DelayTimer: TEST9 FAILED! " << endl;
return 1;
}
cerr << "DelayTimer: TEST9 OK! " << endl;
if( dtm2.check(false) )
{
cerr << "DelayTimer: TEST10 FAILED! " << endl;
return 1;
}
cerr << "DelayTimer: TEST10 OK! " << endl;
DelayTimer dtm3(200,100);
dtm3.check(true);
msleep(190);
dtm3.check(false);
dtm3.check(true);
msleep(50);
if( dtm3.check(true) )
{
cerr << "DelayTimer: TEST11 FAILED! " << endl;
return 1;
}
cerr << "DelayTimer: TEST11 OK! " << endl;
msleep(200);
if( !dtm3.check(true) )
{
cerr << "DelayTimer: TEST12 FAILED! " << endl;
return 1;
}
cerr << "DelayTimer: TEST12 OK! " << endl;
dtm3.check(false);
msleep(90);
dtm3.check(true);
msleep(50);
if( !dtm3.check(false) )
{
cerr << "DelayTimer: TEST13 FAILED! " << endl;
return 1;
}
cerr << "DelayTimer: TEST13 OK! " << endl;
msleep(150);
if( dtm3.check(false) )
{
cerr << "DelayTimer: TEST14 FAILED! " << endl;
return 1;
}
cerr << "DelayTimer: TEST14 OK! " << endl;
return 0;
}
#include <iostream>
using namespace std;
#include "HourGlass.h"
#include "DelayTimer.h"
#include "UniSetTypes.h"
int main()
{
HourGlass hg;
hg.run(1000);
hg.rotate(true);
msleep(200);
if( hg.check() )
{
cerr << "HourGlass: TEST1 FAILED! " << endl;
return 1;
}
msleep(1000);
if( !hg.check() )
{
cerr << "HourGlass: TEST1 FAILED! " << endl;
return 1;
}
cout << "HourGlass: TEST1 OK!" << endl;
hg.rotate(false);
msleep(1000);
if( hg.check() )
{
cerr << "HourGlass: TEST2 FAILED! " << endl;
return 1;
}
cout << "HourGlass: TEST2 OK!" << endl;
hg.rotate(true);
msleep(500);
if( hg.check() )
{
cerr << "HourGlass: TEST3 FAILED! " << endl;
return 1;
}
cout << "HourGlass: TEST3 OK!" << endl;
hg.rotate(false);
msleep(200);
hg.rotate(true);
msleep(200);
if( hg.check() )
{
cerr << "HourGlass: TEST4 FAILED! " << endl;
return 1;
}
msleep(820);
if( !hg.check() )
{
cerr << "HourGlass: TEST5 FAILED! " << endl;
return 1;
}
cout << "HourGlass: TEST4 OK!" << endl;
return 0;
}
......@@ -32,6 +32,10 @@ int main()
}
PassiveTimer pt0(0);
cout << "pt0: check msec=0: " << ( pt0.checkTime() ? "OK" : "FAILED" ) << endl;
PassiveTimer pt4(350);
for( int i=0;i<12; i++ )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment