code format
This commit is contained in:
@@ -1,25 +1,26 @@
|
||||
/*
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
PIP - Platform Independent Primitives
|
||||
Timer
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pitimer.h"
|
||||
#include "piincludes_p.h"
|
||||
|
||||
#include "piconditionvar.h"
|
||||
#include "piincludes_p.h"
|
||||
#ifdef PIP_TIMER_RT
|
||||
# include <csignal>
|
||||
#endif
|
||||
@@ -50,7 +51,8 @@
|
||||
//! \~russian \section PITimer_sec1 Варианты уведомления
|
||||
//! \~english
|
||||
//! Notify variants:
|
||||
//! * "slot" - static function with format void func(void * data, int delimiter) or [lambda expression](https://en.cppreference.com/w/cpp/language/lambda);
|
||||
//! * "slot" - static function with format void func(void * data, int delimiter) or [lambda
|
||||
//! expression](https://en.cppreference.com/w/cpp/language/lambda);
|
||||
//! * event - \a tickEvent();
|
||||
//! * virtual function - \a tick().
|
||||
//!
|
||||
@@ -59,7 +61,8 @@
|
||||
//! All these variants are equivalent, use most applicable.
|
||||
//! \~russian
|
||||
//! Варианты уведомления:
|
||||
//! * "slot" - статический метод в формате void func(void * data, int delimiter) или [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda);
|
||||
//! * "slot" - статический метод в формате void func(void * data, int delimiter) или
|
||||
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda);
|
||||
//! * event - \a tickEvent();
|
||||
//! * виртуальный метод - \a tick().
|
||||
//!
|
||||
@@ -116,18 +119,18 @@
|
||||
|
||||
|
||||
_PITimerBase::_PITimerBase() {
|
||||
interval_ = 1000;
|
||||
interval_ = 1000;
|
||||
deferred_delay = 0.;
|
||||
running_ = deferred_ = deferred_mode = false;
|
||||
tfunc = 0;
|
||||
parent = 0;
|
||||
tfunc = 0;
|
||||
parent = 0;
|
||||
}
|
||||
|
||||
|
||||
void _PITimerBase::setInterval(double i) {
|
||||
interval_ = i;
|
||||
if (isRunning()) {
|
||||
//piCout << "change interval runtime";
|
||||
// piCout << "change interval runtime";
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
@@ -138,7 +141,7 @@ bool _PITimerBase::start(double interval_ms) {
|
||||
if (isRunning()) stop();
|
||||
deferred_ = false;
|
||||
setInterval(interval_ms);
|
||||
//piCout << "_PITimerBase::startTimer"<<interval_ms<<"...";
|
||||
// piCout << "_PITimerBase::startTimer"<<interval_ms<<"...";
|
||||
running_ = startTimer(interval_ms);
|
||||
return running_;
|
||||
}
|
||||
@@ -146,8 +149,8 @@ bool _PITimerBase::start(double interval_ms) {
|
||||
|
||||
void _PITimerBase::startDeferred(double interval_ms, PIDateTime start_datetime) {
|
||||
if (isRunning()) stop();
|
||||
deferred_ = true;
|
||||
deferred_mode = true;
|
||||
deferred_ = true;
|
||||
deferred_mode = true;
|
||||
deferred_datetime = start_datetime;
|
||||
setInterval(interval_ms);
|
||||
running_ = startTimer(interval_ms);
|
||||
@@ -156,8 +159,8 @@ void _PITimerBase::startDeferred(double interval_ms, PIDateTime start_datetime)
|
||||
|
||||
void _PITimerBase::startDeferred(double interval_ms, double delay_ms) {
|
||||
if (isRunning()) stop();
|
||||
deferred_ = true;
|
||||
deferred_mode = false;
|
||||
deferred_ = true;
|
||||
deferred_mode = false;
|
||||
deferred_delay = delay_ms;
|
||||
setInterval(interval_ms);
|
||||
running_ = startTimer(interval_ms);
|
||||
@@ -165,28 +168,28 @@ void _PITimerBase::startDeferred(double interval_ms, double delay_ms) {
|
||||
|
||||
|
||||
bool _PITimerBase::stop() {
|
||||
//piCout << GetCurrentThreadId() << "_PITimerBase::stop" << wait << isRunning();
|
||||
// piCout << GetCurrentThreadId() << "_PITimerBase::stop" << wait << isRunning();
|
||||
if (!isRunning()) return true;
|
||||
//piCout << "_PITimerBase::stopTimer ...";
|
||||
// piCout << "_PITimerBase::stopTimer ...";
|
||||
running_ = !stopTimer();
|
||||
return !running_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class _PITimerImp_Thread: public _PITimerBase {
|
||||
public:
|
||||
_PITimerImp_Thread();
|
||||
virtual ~_PITimerImp_Thread() {stop();}
|
||||
virtual ~_PITimerImp_Thread() { stop(); }
|
||||
|
||||
protected:
|
||||
void prepareStart(double interval_ms);
|
||||
bool threadFunc(); // returns true if repeat is needed
|
||||
int wait_dt, wait_dd, wait_tick;
|
||||
|
||||
private:
|
||||
bool startTimer(double interval_ms) override;
|
||||
bool stopTimer() override;
|
||||
static void threadFuncS(void * d) {((_PITimerImp_Thread*)d)->threadFunc();}
|
||||
static void threadFuncS(void * d) { ((_PITimerImp_Thread *)d)->threadFunc(); }
|
||||
void adjustTimes();
|
||||
bool smallWait(int ms);
|
||||
|
||||
@@ -202,7 +205,9 @@ class _PITimerImp_RT: public _PITimerBase {
|
||||
public:
|
||||
_PITimerImp_RT();
|
||||
virtual ~_PITimerImp_RT();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
bool startTimer(double interval_ms) override;
|
||||
bool stopTimer() override;
|
||||
@@ -216,7 +221,8 @@ private:
|
||||
class _PITimerImp_Pool: public _PITimerImp_Thread {
|
||||
public:
|
||||
_PITimerImp_Pool();
|
||||
virtual ~_PITimerImp_Pool() {stop();}
|
||||
virtual ~_PITimerImp_Pool() { stop(); }
|
||||
|
||||
private:
|
||||
class Pool: public PIThread {
|
||||
public:
|
||||
@@ -224,7 +230,8 @@ private:
|
||||
void add(_PITimerImp_Pool * t);
|
||||
void remove(_PITimerImp_Pool * t);
|
||||
void run() override;
|
||||
PIVector<_PITimerImp_Pool * > timers, to_remove;
|
||||
PIVector<_PITimerImp_Pool *> timers, to_remove;
|
||||
|
||||
private:
|
||||
explicit Pool();
|
||||
virtual ~Pool();
|
||||
@@ -234,15 +241,13 @@ private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
_PITimerImp_Thread::_PITimerImp_Thread() {
|
||||
thread_.setName("__S__PITimerImp_Thread::thread");
|
||||
wait_dt = 1000;
|
||||
wait_dd = 2000;
|
||||
wait_dt = 1000;
|
||||
wait_dd = 2000;
|
||||
wait_tick = 1000;
|
||||
//piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_;
|
||||
//piCout << "new _PITimerImp_Thread";
|
||||
// piCout << "_PITimerImp_Thread" << this << ", thread& =" << &thread_;
|
||||
// piCout << "new _PITimerImp_Thread";
|
||||
}
|
||||
|
||||
|
||||
@@ -256,8 +261,7 @@ void _PITimerImp_Thread::prepareStart(double interval_ms) {
|
||||
st_odt = st_inc * 5;
|
||||
if (st_odt.toSeconds() < 1.) st_odt = PISystemTime::fromSeconds(1.);
|
||||
if (deferred_) {
|
||||
if (!deferred_mode)
|
||||
st_time = PISystemTime::current(true) + PISystemTime::fromMilliseconds(deferred_delay);
|
||||
if (!deferred_mode) st_time = PISystemTime::current(true) + PISystemTime::fromMilliseconds(deferred_delay);
|
||||
st_time -= st_inc;
|
||||
} else
|
||||
st_time = PISystemTime::current(true) + st_inc;
|
||||
@@ -275,10 +279,10 @@ bool _PITimerImp_Thread::stopTimer() {
|
||||
thread_.stop();
|
||||
event.notifyAll();
|
||||
thread_.waitForFinish();
|
||||
// if (wait)
|
||||
// if (!thread_.waitForFinish(10))
|
||||
// if (thread_.isRunning())
|
||||
// thread_.terminate();
|
||||
// if (wait)
|
||||
// if (!thread_.waitForFinish(10))
|
||||
// if (thread_.isRunning())
|
||||
// thread_.terminate();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -300,19 +304,18 @@ bool _PITimerImp_Thread::threadFunc() {
|
||||
} else {
|
||||
if (!smallWait(dwt.toMilliseconds())) return false;
|
||||
deferred_ = false;
|
||||
st_time = PISystemTime::current(true);
|
||||
st_time = PISystemTime::current(true);
|
||||
}
|
||||
} else {
|
||||
if (dwt.toMilliseconds() > 0.1)
|
||||
return false;
|
||||
if (dwt.toMilliseconds() > 0.1) return false;
|
||||
}
|
||||
}
|
||||
st_wait = st_time - PISystemTime::current(true);
|
||||
//piCout << "wait" << this << st_wait;
|
||||
// piCout << "wait" << this << st_wait;
|
||||
if (st_wait.abs() > st_odt || st_wait.seconds <= -5) {
|
||||
//piCout << &thread_ << "adjust" << "...";
|
||||
// piCout << &thread_ << "adjust" << "...";
|
||||
adjustTimes();
|
||||
//piCout << &thread_ << "adjust" << "ok";
|
||||
// piCout << &thread_ << "adjust" << "ok";
|
||||
return true;
|
||||
}
|
||||
if (wait_tick > 0) {
|
||||
@@ -320,21 +323,20 @@ bool _PITimerImp_Thread::threadFunc() {
|
||||
smallWait(wait_tick);
|
||||
return false;
|
||||
} else {
|
||||
//piCout << &thread_ << "sleep for" << st_wait;
|
||||
// piCout << &thread_ << "sleep for" << st_wait;
|
||||
if (!smallWait(st_wait.toMilliseconds())) return false;
|
||||
}
|
||||
} else {
|
||||
if (st_wait.toMilliseconds() > 0.1)
|
||||
return false;
|
||||
if (st_wait.toMilliseconds() > 0.1) return false;
|
||||
}
|
||||
st_time += st_inc;
|
||||
if (!parent->isPIObject()) {
|
||||
piCout << "Achtung! PITimer \"parent\" is not PIObject!";
|
||||
return false;
|
||||
}
|
||||
//piCout << &thread_ << "tfunc" << "...";
|
||||
// piCout << &thread_ << "tfunc" << "...";
|
||||
tfunc(parent);
|
||||
//piCout << &thread_ << "tfunc" << "ok";
|
||||
// piCout << &thread_ << "tfunc" << "ok";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -373,11 +375,11 @@ bool _PITimerImp_Thread::smallWait(int ms) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef PIP_TIMER_RT
|
||||
|
||||
void threadFuncS(sigval sv) {((_PITimerImp_RT * )sv.sival_ptr)->tfunc(((_PITimerImp_RT * )sv.sival_ptr)->parent);}
|
||||
void threadFuncS(sigval sv) {
|
||||
((_PITimerImp_RT *)sv.sival_ptr)->tfunc(((_PITimerImp_RT *)sv.sival_ptr)->parent);
|
||||
}
|
||||
|
||||
struct _PITimerImp_RT_Private_ {
|
||||
itimerspec spec;
|
||||
@@ -386,14 +388,14 @@ struct _PITimerImp_RT_Private_ {
|
||||
};
|
||||
|
||||
_PITimerImp_RT::_PITimerImp_RT() {
|
||||
//piCout << "new _PITimerImp_RT";
|
||||
priv = new _PITimerImp_RT_Private_();
|
||||
// piCout << "new _PITimerImp_RT";
|
||||
priv = new _PITimerImp_RT_Private_();
|
||||
priv->tt = 0;
|
||||
ti = -1;
|
||||
ti = -1;
|
||||
memset(&(priv->se), 0, sizeof(priv->se));
|
||||
priv->se.sigev_notify = SIGEV_THREAD;
|
||||
priv->se.sigev_value.sival_ptr = this;
|
||||
priv->se.sigev_notify_function = threadFuncS;
|
||||
priv->se.sigev_notify = SIGEV_THREAD;
|
||||
priv->se.sigev_value.sival_ptr = this;
|
||||
priv->se.sigev_notify_function = threadFuncS;
|
||||
priv->se.sigev_notify_attributes = 0;
|
||||
}
|
||||
|
||||
@@ -407,22 +409,22 @@ _PITimerImp_RT::~_PITimerImp_RT() {
|
||||
bool _PITimerImp_RT::startTimer(double interval_ms) {
|
||||
int flags(0);
|
||||
priv->spec.it_interval.tv_nsec = ((int)(interval_ms * 1000) % 1000000) * 1000;
|
||||
priv->spec.it_interval.tv_sec = (time_t)(interval_ms / 1000);
|
||||
priv->spec.it_interval.tv_sec = (time_t)(interval_ms / 1000);
|
||||
if (deferred_) {
|
||||
if (deferred_mode) {
|
||||
PISystemTime dtm = deferred_datetime.toSystemTime();
|
||||
PISystemTime dtm = deferred_datetime.toSystemTime();
|
||||
priv->spec.it_value.tv_nsec = dtm.nanoseconds;
|
||||
priv->spec.it_value.tv_sec = dtm.seconds;
|
||||
flags = TIMER_ABSTIME;
|
||||
priv->spec.it_value.tv_sec = dtm.seconds;
|
||||
flags = TIMER_ABSTIME;
|
||||
} else {
|
||||
priv->spec.it_value.tv_nsec = ((int)(deferred_delay * 1000) % 1000000) * 1000;
|
||||
priv->spec.it_value.tv_sec = (time_t)(deferred_delay / 1000);
|
||||
priv->spec.it_value.tv_sec = (time_t)(deferred_delay / 1000);
|
||||
}
|
||||
} else {
|
||||
priv->spec.it_value = priv->spec.it_interval;
|
||||
}
|
||||
ti = timer_create(CLOCK_REALTIME, &(priv->se), &(priv->tt));
|
||||
//cout << "***create timer " << msecs << " msecs\n";
|
||||
// cout << "***create timer " << msecs << " msecs\n";
|
||||
if (ti == -1) {
|
||||
piCout << "Can`t create RT timer for " << interval_ms << " msecs: " << errorString();
|
||||
return false;
|
||||
@@ -435,7 +437,7 @@ bool _PITimerImp_RT::startTimer(double interval_ms) {
|
||||
bool _PITimerImp_RT::stopTimer() {
|
||||
if (ti < 0) return true;
|
||||
timer_delete(priv->tt);
|
||||
ti = -1;
|
||||
ti = -1;
|
||||
priv->tt = 0;
|
||||
return true;
|
||||
}
|
||||
@@ -443,11 +445,9 @@ bool _PITimerImp_RT::stopTimer() {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
_PITimerImp_Pool::_PITimerImp_Pool(): _PITimerImp_Thread() {
|
||||
wait_dt = wait_dd = wait_tick = 0;
|
||||
//piCout << "new _PITimerImp_Pool";
|
||||
// piCout << "new _PITimerImp_Pool";
|
||||
}
|
||||
|
||||
|
||||
@@ -456,7 +456,7 @@ _PITimerImp_Pool::Pool::Pool(): PIThread() {
|
||||
needLockRun(true);
|
||||
#ifndef FREERTOS
|
||||
timers.reserve(64);
|
||||
start(PIP_MIN_MSLEEP*5);
|
||||
start(PIP_MIN_MSLEEP * 5);
|
||||
#else
|
||||
start(PIP_MIN_MSLEEP);
|
||||
#endif
|
||||
@@ -465,8 +465,7 @@ _PITimerImp_Pool::Pool::Pool(): PIThread() {
|
||||
|
||||
_PITimerImp_Pool::Pool::~Pool() {
|
||||
stop();
|
||||
if (!waitForFinish(500))
|
||||
terminate();
|
||||
if (!waitForFinish(500)) terminate();
|
||||
unlock();
|
||||
timers.clear();
|
||||
}
|
||||
@@ -479,32 +478,31 @@ _PITimerImp_Pool::Pool * _PITimerImp_Pool::Pool::instance() {
|
||||
|
||||
|
||||
void _PITimerImp_Pool::Pool::add(_PITimerImp_Pool * t) {
|
||||
//piCout << "add ...";
|
||||
// piCout << "add ...";
|
||||
lock();
|
||||
to_remove.removeAll(t);
|
||||
if (!timers.contains(t))
|
||||
timers << t;
|
||||
if (!timers.contains(t)) timers << t;
|
||||
unlock();
|
||||
//piCout << "add done";
|
||||
// piCout << "add done";
|
||||
}
|
||||
|
||||
|
||||
void _PITimerImp_Pool::Pool::remove(_PITimerImp_Pool * t) {
|
||||
//piCout << "remove ...";
|
||||
// piCout << "remove ...";
|
||||
lock();
|
||||
to_remove << t;
|
||||
unlock();
|
||||
//piCout << "remove done";
|
||||
// piCout << "remove done";
|
||||
}
|
||||
|
||||
|
||||
void _PITimerImp_Pool::Pool::run() {
|
||||
if (!to_remove.isEmpty()) {
|
||||
piForeach (_PITimerImp_Pool * t, to_remove)
|
||||
piForeach(_PITimerImp_Pool * t, to_remove)
|
||||
timers.removeAll(t);
|
||||
to_remove.clear();
|
||||
}
|
||||
piForeach (_PITimerImp_Pool * t, timers)
|
||||
piForeach(_PITimerImp_Pool * t, timers)
|
||||
t->threadFunc();
|
||||
}
|
||||
|
||||
@@ -522,9 +520,6 @@ bool _PITimerImp_Pool::stopTimer() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
PITimer::PITimer(): PIObject() {
|
||||
#ifdef FREERTOS
|
||||
imp_mode = PITimer::Thread;
|
||||
@@ -544,23 +539,23 @@ PITimer::PITimer(PITimer::TimerImplementation ti): PIObject() {
|
||||
PITimer::PITimer(TimerEvent slot, void * data, PITimer::TimerImplementation ti): PIObject() {
|
||||
imp_mode = ti;
|
||||
initFirst();
|
||||
data_t = data;
|
||||
data_t = data;
|
||||
ret_func = slot;
|
||||
}
|
||||
|
||||
|
||||
PITimer::PITimer(std::function<void ()> slot, PITimer::TimerImplementation ti) {
|
||||
PITimer::PITimer(std::function<void()> slot, PITimer::TimerImplementation ti) {
|
||||
imp_mode = ti;
|
||||
initFirst();
|
||||
ret_func = [slot](void *, int){slot();};
|
||||
ret_func = [slot](void *, int) { slot(); };
|
||||
}
|
||||
|
||||
|
||||
PITimer::PITimer(std::function<void (void *)> slot, void * data, PITimer::TimerImplementation ti) {
|
||||
PITimer::PITimer(std::function<void(void *)> slot, void * data, PITimer::TimerImplementation ti) {
|
||||
imp_mode = ti;
|
||||
initFirst();
|
||||
data_t = data;
|
||||
ret_func = [slot](void *d, int){slot(d);};
|
||||
data_t = data;
|
||||
ret_func = [slot](void * d, int) { slot(d); };
|
||||
}
|
||||
|
||||
|
||||
@@ -595,11 +590,11 @@ bool PITimer::isStopped() const {
|
||||
|
||||
|
||||
void PITimer::initFirst() {
|
||||
lockRun = false;
|
||||
lockRun = false;
|
||||
callEvents = true;
|
||||
data_t = 0;
|
||||
ret_func = 0;
|
||||
imp = 0;
|
||||
data_t = 0;
|
||||
ret_func = 0;
|
||||
imp = 0;
|
||||
setProperty("interval", 0.);
|
||||
}
|
||||
|
||||
@@ -619,15 +614,15 @@ void PITimer::init() const {
|
||||
default: piCout << "Fatal: invalid implementation() of" << this << "!"; assert(0);
|
||||
}
|
||||
if (!imp) return;
|
||||
//piCout << this << "init" << imp;
|
||||
imp->tfunc = tickImpS;
|
||||
imp->parent = const_cast<PITimer*>(this);
|
||||
// piCout << this << "init" << imp;
|
||||
imp->tfunc = tickImpS;
|
||||
imp->parent = const_cast<PITimer *>(this);
|
||||
}
|
||||
|
||||
|
||||
void PITimer::destroy() {
|
||||
if (!imp) return;
|
||||
//piCout << this << "destroy" << imp;
|
||||
// piCout << this << "destroy" << imp;
|
||||
imp->stop();
|
||||
delete imp;
|
||||
imp = 0;
|
||||
@@ -641,11 +636,13 @@ void PITimer::tickImp() {
|
||||
tick(data_t, 1);
|
||||
tickEvent(data_t, 1);
|
||||
if (callEvents) maybeCallQueuedEvents();
|
||||
piForeach (Delimiter & i, delims) {
|
||||
piForeach(Delimiter & i, delims) {
|
||||
if (i.delim > ++(i.tick)) continue;
|
||||
i.tick = 0;
|
||||
if (i.slot) i.slot(data_t, i.delim);
|
||||
else if (ret_func) ret_func(data_t, i.delim);
|
||||
if (i.slot)
|
||||
i.slot(data_t, i.delim);
|
||||
else if (ret_func)
|
||||
ret_func(data_t, i.delim);
|
||||
tick(data_t, i.delim);
|
||||
tickEvent(data_t, i.delim);
|
||||
}
|
||||
@@ -655,14 +652,14 @@ void PITimer::tickImp() {
|
||||
|
||||
bool PITimer::start() {
|
||||
init();
|
||||
//piCout << this << "start" << imp;
|
||||
// piCout << this << "start" << imp;
|
||||
return imp->start();
|
||||
}
|
||||
|
||||
|
||||
bool PITimer::start(double interval_ms_d) {
|
||||
init();
|
||||
//piCout << this << "start" << imp << interval_ms_d;
|
||||
// piCout << this << "start" << imp << interval_ms_d;
|
||||
setProperty("interval", interval_ms_d);
|
||||
return imp->start(interval_ms_d);
|
||||
}
|
||||
@@ -725,7 +722,6 @@ bool PITimer::restart() {
|
||||
|
||||
bool PITimer::stop() {
|
||||
init();
|
||||
//piCout << this << "stop" << imp << wait;
|
||||
// piCout << this << "stop" << imp << wait;
|
||||
return imp->stop();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user