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:
peri4
2013-03-18 12:07:44 +04:00
parent cfc5eed75e
commit 66c53a27fc
72 changed files with 4407 additions and 960 deletions

160
pitimer.h
View File

@@ -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