18.03.2013 - Bug fixes, add in/out speed diagnostic to PIProtocol, fixed PIConsole tab switch segfault, PIObject EVENT / EVENT_HANDLER mechanism update - new EVENT macros that use EVENT_HANDLER with raiseEvent implementation.
This allow compile check event for CONNECT and use EVENT as CONNECT target, also raise event now is simple execute EVENT function.
This commit is contained in:
160
pitimer.h
160
pitimer.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
||||
Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com
|
||||
|
||||
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
|
||||
@@ -28,6 +28,45 @@
|
||||
|
||||
typedef void (*TimerEvent)(void * , int );
|
||||
|
||||
class PISystemTime {
|
||||
public:
|
||||
PISystemTime() {seconds = nanoseconds = 0;}
|
||||
PISystemTime(long s, long ns) {seconds = s; nanoseconds = ns; checkOverflows();}
|
||||
PISystemTime(const PISystemTime & t) {seconds = t.seconds; nanoseconds = t.nanoseconds;}
|
||||
|
||||
double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;}
|
||||
double toMilliseconds() const {return seconds * 1.e+3 + nanoseconds / 1.e+6;}
|
||||
double toMicroseconds() const {return seconds * 1.e+6 + nanoseconds / 1.e+3;}
|
||||
double toNanoseconds() const {return seconds * 1.e+9 + double(nanoseconds);}
|
||||
void sleep() {piUSleep(piFloord(toMicroseconds()));} // wait self value, useful to wait some dT = (t1 - t0)
|
||||
PISystemTime abs() const {return PISystemTime(piAbsl(seconds), piAbsl(nanoseconds));}
|
||||
PISystemTime operator +(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds += t.seconds; tt.nanoseconds += t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||
PISystemTime operator -(const PISystemTime & t) {PISystemTime tt(*this); tt.seconds -= t.seconds; tt.nanoseconds -= t.nanoseconds; tt.checkOverflows(); return tt;}
|
||||
PISystemTime & operator +=(const PISystemTime & t) {seconds += t.seconds; nanoseconds += t.nanoseconds; checkOverflows(); return *this;}
|
||||
PISystemTime & operator -=(const PISystemTime & t) {seconds -= t.seconds; nanoseconds -= t.nanoseconds; checkOverflows(); return *this;}
|
||||
bool operator ==(const PISystemTime & t) {return ((seconds == t.seconds) && (nanoseconds == t.nanoseconds));}
|
||||
bool operator !=(const PISystemTime & t) {return ((seconds != t.seconds) || (nanoseconds != t.nanoseconds));}
|
||||
bool operator >(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds > t.nanoseconds; return seconds > t.seconds;}
|
||||
bool operator <(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds < t.nanoseconds; return seconds < t.seconds;}
|
||||
bool operator >=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds >= t.nanoseconds; return seconds >= t.seconds;}
|
||||
bool operator <=(const PISystemTime & t) {if (seconds == t.seconds) return nanoseconds <= t.nanoseconds; return seconds <= t.seconds;}
|
||||
|
||||
static PISystemTime fromSeconds(double v) {long s = piFloord(v); return PISystemTime(s, (v - s) * 1000000000);}
|
||||
static PISystemTime fromMilliseconds(double v) {long s = piFloord(v / 1000.); return PISystemTime(s, (v / 1000. - s) * 1000000000);}
|
||||
static PISystemTime fromMicroseconds(double v) {long s = piFloord(v / 1000000.); return PISystemTime(s, (v / 1000000. - s) * 1000000000);}
|
||||
static PISystemTime fromNanoseconds(double v) {long s = piFloord(v / 1000000000.); return PISystemTime(s, (v / 1000000000. - s) * 1000000000);}
|
||||
|
||||
long seconds;
|
||||
long nanoseconds;
|
||||
|
||||
private:
|
||||
void checkOverflows() {while (nanoseconds >= 1000000000) {nanoseconds -= 1000000000; seconds++;} while (nanoseconds < 0) {nanoseconds += 1000000000; seconds--;}}
|
||||
|
||||
};
|
||||
|
||||
inline PIByteArray & operator <<(PIByteArray & s, const PISystemTime & v) {s << v.seconds << v.nanoseconds; return s;}
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PISystemTime & v) {s >> v.seconds >> v.nanoseconds; return s;}
|
||||
|
||||
struct PITime {
|
||||
int seconds;
|
||||
int minutes;
|
||||
@@ -38,29 +77,67 @@ struct PITime {
|
||||
struct PIDate {
|
||||
int day;
|
||||
int month;
|
||||
int year; // since 1900
|
||||
PIString toString(const PIString & format = "d.mm.yyyy");
|
||||
int year;
|
||||
PIString toString(const PIString & format = "d.MM.yyyy");
|
||||
};
|
||||
|
||||
struct PIDateTime {
|
||||
int seconds;
|
||||
int minutes;
|
||||
int hours;
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
PIString toString(const PIString & format = "h:mm:ss d.MM.yyyy");
|
||||
};
|
||||
|
||||
/// events:
|
||||
/// void timeout(void * data, int delimiter)
|
||||
///
|
||||
/// handlers:
|
||||
/// void start(double msecs)
|
||||
/// void deferredStart(double interval_msecs, double delay_msecs)
|
||||
/// void deferredStart(double interval_msecs, const PIDateTime & start_datetime)
|
||||
/// void stop()
|
||||
/// bool waitForFinish(int timeout_msecs = -1)
|
||||
/// void reset()
|
||||
/// void clearDelimiters()
|
||||
/// void lock()
|
||||
/// void unlock()
|
||||
class PITimer
|
||||
#ifdef WINDOWS
|
||||
#ifndef PIP_TIMER_RT
|
||||
: public PIThread
|
||||
#else
|
||||
: public PIObject
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
PITimer(TimerEvent slot = 0, void * data = 0);
|
||||
~PITimer();
|
||||
PITimer(TimerEvent slot = 0, void * data = 0, bool threaded = true);
|
||||
PITimer(bool threaded);
|
||||
virtual ~PITimer();
|
||||
|
||||
void setData(void * data_) {data = data_;}
|
||||
void setSlot(TimerEvent slot) {ret_func = slot;}
|
||||
#ifdef WINDOWS
|
||||
void reset() {t_st = GetCurrentTime();}
|
||||
#ifndef PIP_TIMER_RT
|
||||
# ifdef WINDOWS
|
||||
EVENT_HANDLER0(PITimer, void, reset) {t_st = GetCurrentTime();}
|
||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
||||
# elif defined(MAC_OS)
|
||||
EVENT_HANDLER0(PITimer, void, reset) {clock_get_time(__pi_mac_clock, &t_st);}
|
||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
||||
# else
|
||||
EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);}
|
||||
EVENT_HANDLER1(PIThread, bool, start, int, timer_delay) {start(double(timer_delay)); return true;}
|
||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
||||
# endif
|
||||
#else
|
||||
EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);}
|
||||
EVENT_HANDLER1(PITimer, void, start, double, msecs);
|
||||
EVENT_HANDLER0(PITimer, void, stop) {if (ti == 0) timer_delete(timer); ti = -1; running = false;}
|
||||
EVENT_HANDLER2(PITimer, void, deferredStart, double, interval_msecs, double, delay_msecs);
|
||||
EVENT_HANDLER2(PITimer, void, deferredStart, double, interval_msecs, const PIDateTime &, start_datetime);
|
||||
EVENT_HANDLER0(PITimer, void, stop);
|
||||
EVENT_HANDLER0(PITimer, bool, waitForFinish) {return waitForFinish(-1);}
|
||||
EVENT_HANDLER1(PITimer, bool, waitForFinish, int, timeout_msecs);
|
||||
bool isRunning() const {return running;}
|
||||
@@ -83,29 +160,71 @@ public:
|
||||
double reset_time_u(); // microseconds
|
||||
double reset_time_m(); // miliseconds
|
||||
double reset_time_s(); // seconds
|
||||
PISystemTime reset_time();
|
||||
|
||||
static double elapsed_system_n(); // nanoseconds
|
||||
static double elapsed_system_u(); // microseconds
|
||||
static double elapsed_system_m(); // miliseconds
|
||||
static double elapsed_system_s(); // seconds
|
||||
|
||||
private:
|
||||
#ifdef WINDOWS
|
||||
void run();
|
||||
|
||||
long t_st, t_cur;
|
||||
#else
|
||||
#ifdef PIP_TIMER_RT
|
||||
class TimerPool: public PIThread {
|
||||
public:
|
||||
TimerPool(): PIThread() {/*cout << "+++++new pool\n"; */ti = -1;}
|
||||
~TimerPool() {stop();}
|
||||
void add(PITimer * t) {mutex.lock(); timers << TimerPair(t, 0); mutex.unlock();}
|
||||
void remove(PITimer * t);
|
||||
bool isEmpty() const {return timers.isEmpty();}
|
||||
typedef PIPair<PITimer * , int> TimerPair;
|
||||
private:
|
||||
static void empty_handler(int) {}
|
||||
void begin();
|
||||
void run();
|
||||
void end() {/*cout << "pool end\n"; */if (ti != -1) timer_delete(timer); ti = -1;}
|
||||
int ti, si;
|
||||
sigset_t ss;
|
||||
sigevent se;
|
||||
sigval sv;
|
||||
itimerspec spec;
|
||||
|
||||
timer_t timer;
|
||||
PIVector<TimerPair> timers;
|
||||
PIMutex mutex;
|
||||
};
|
||||
static void timer_event(sigval e);
|
||||
int ticks;
|
||||
#endif
|
||||
|
||||
EVENT2(PITimer, timeout, void * , data, int, delimiter)
|
||||
|
||||
protected:
|
||||
virtual void tick(void * data, int delimiter) {;}
|
||||
|
||||
bool running;
|
||||
private:
|
||||
#ifndef PIP_TIMER_RT
|
||||
void run();
|
||||
|
||||
PISystemTime st_time, inc_time;
|
||||
#else
|
||||
bool running, threaded;
|
||||
volatile bool lockRun;
|
||||
PIMutex mutex_;
|
||||
int ti;
|
||||
itimerspec spec;
|
||||
timespec t_st, t_cur;
|
||||
timer_t timer;
|
||||
sigevent se;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
long
|
||||
#elif defined(MAC_OS)
|
||||
mach_timespec_t
|
||||
#else
|
||||
timespec
|
||||
#endif
|
||||
t_st, t_cur;
|
||||
|
||||
struct TimerSlot {
|
||||
TimerSlot(TimerEvent slot_ = 0, int delim_ = 1) {slot = slot_; delim = delim_; tick = 0;}
|
||||
TimerEvent slot;
|
||||
@@ -119,9 +238,16 @@ private:
|
||||
|
||||
};
|
||||
|
||||
#ifdef PIP_TIMER_RT
|
||||
extern PITimer::TimerPool * pool;
|
||||
#endif
|
||||
|
||||
PITime currentTime();
|
||||
PIDate currentDate();
|
||||
PIDateTime currentDateTime();
|
||||
PISystemTime currentSystemTime();
|
||||
PIString time2string(const PITime & time, const PIString & format = "h:mm:ss"); // obsolete, use PITime.toString() instead
|
||||
PIString date2string(const PIDate & date, const PIString & format = "d.mm.yyyy"); // obsolete, use PITime.toString() instead
|
||||
PIString date2string(const PIDate & date, const PIString & format = "d.MM.yyyy"); // obsolete, use PITime.toString() instead
|
||||
PIString datetime2string(const PIDateTime & datetime, const PIString & format = "h:mm:ss d.MM.yyyy"); // obsolete, use PIDateTime.toString() instead
|
||||
|
||||
#endif // PITIMER_H
|
||||
|
||||
Reference in New Issue
Block a user