diff --git a/src/gui/components/cc_frm_clock.cpp b/src/gui/components/cc_frm_clock.cpp index 391823c3e..7a36db280 100644 --- a/src/gui/components/cc_frm_clock.cpp +++ b/src/gui/components/cc_frm_clock.cpp @@ -316,15 +316,15 @@ bool CComponentsFrmClock::startClock() } if (cl_timer == NULL){ - cl_timer = new CComponentsTimer(); + cl_timer = new CComponentsTimer(0); if (cl_timer->OnTimer.empty()){ dprintf(DEBUG_INFO,"\033[33m[CComponentsFrmClock]\t[%s] init slot...\033[0m\n", __func__); cl_timer->OnTimer.connect(cl_sl); } } - cl_timer->setTimerIntervall(cl_interval); + cl_timer->setTimerInterval(cl_interval); - if (cl_timer->isRun()) + if (cl_timer->startTimer()) return true; return false; diff --git a/src/gui/components/cc_frm_clock.h b/src/gui/components/cc_frm_clock.h index bb9ca186e..b91d2454b 100644 --- a/src/gui/components/cc_frm_clock.h +++ b/src/gui/components/cc_frm_clock.h @@ -147,7 +147,7 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen ///returns true, if clock is running virtual bool isRun() const {return cl_timer ? true : false;}; ///set refresh interval in seconds, default value=1 (=1 sec) - virtual void setClockIntervall(const int& seconds){cl_interval = seconds;}; + virtual void setClockInterval(const int& seconds){cl_interval = seconds;}; ///show clock on screen virtual void paint(bool do_save_bg = CC_SAVE_SCREEN_YES); diff --git a/src/gui/components/cc_timer.cpp b/src/gui/components/cc_timer.cpp index 129f19dbc..966d0bcc2 100644 --- a/src/gui/components/cc_timer.cpp +++ b/src/gui/components/cc_timer.cpp @@ -3,7 +3,7 @@ Copyright (C) 2001 by Steffen Hehn 'McClean' Generic Timer. - Copyright (C) 2013, Thilo Graf 'dbt' + Copyright (C) 2013-2016, Thilo Graf 'dbt' License: GPL @@ -36,66 +36,72 @@ using namespace std; -CComponentsTimer::CComponentsTimer( const int& interval) +CComponentsTimer::CComponentsTimer(const int& interval) { tm_thread = 0; - tm_interval = interval; + tm_interval = interval; + + sl_stop_timer = sigc::mem_fun(*this, &CComponentsTimer::stopTimer); - sl = sigc::mem_fun(*this, &CComponentsTimer::stopTimer); if (interval > 0) startTimer(); } CComponentsTimer::~CComponentsTimer() { - if (stopTimer()) - dprintf(DEBUG_INFO,"[CComponentsTimer] [%s] timer stopped\n", __func__); + stopTimer(); +} + +void CComponentsTimer::runSharedTimerAction() +{ + //start loop + + while(tm_enable && tm_interval > 0) { + tm_mutex.lock(); + OnTimer(); + mySleep(tm_interval); + tm_mutex.unlock(); + } + + if (tm_thread) + stopThread(); } //thread handle -void* CComponentsTimer::initTimerThread(void *arg) +void* CComponentsTimer::initThreadAction(void *arg) { CComponentsTimer *timer = static_cast(arg); - //start loop - while(timer) { - timer->mutex.lock(); - timer->OnTimer(); - timer->mutex.unlock(); - mySleep(timer->tm_interval); - } + timer->runSharedTimerAction(); return 0; } //start up running timer with own thread, return true on succses -bool CComponentsTimer::startTimer() +void CComponentsTimer::initThread() { - void *ptr = static_cast(this); - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); - pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,0); + if (!tm_enable) + return; if(!tm_thread) { - int res = pthread_create (&tm_thread, NULL, initTimerThread, ptr) ; + void *ptr = static_cast(this); + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0); + pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS,0); + + int res = pthread_create (&tm_thread, NULL, initThreadAction, ptr); + if (res != 0){ dprintf(DEBUG_NORMAL,"\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_create\033[0m\n", __func__, __LINE__); - return false; - } - if (res == 0){ - if (!sl.empty()){ - dprintf(DEBUG_INFO,"\033[33m[CComponentsTimer] [%s - %d] timer thread [%lu] created with interval = %d\033[0m\n", __func__, __LINE__, pthread_self(), tm_interval); - CNeutrinoApp::getInstance()->OnBeforeRestart.connect(sl); - } - }else{ - dprintf(DEBUG_NORMAL, "\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_create\033[0m\n", __func__, __LINE__); + return; } + + if (res == 0) + CNeutrinoApp::getInstance()->OnBeforeRestart.connect(sl_stop_timer); } - return true; } -//stop ticking timer and kill thread, return true on succses -bool CComponentsTimer::stopTimer() +void CComponentsTimer::stopThread() { if(tm_thread) { int thres = pthread_cancel(tm_thread); @@ -109,14 +115,37 @@ bool CComponentsTimer::stopTimer() if (thres == 0){ tm_thread = 0; - dprintf(DEBUG_INFO,"\033[33m[CComponentsTimer] [%s] timer thread terminated ...\033[0m\n", __func__); //ensure disconnect of unused slot - if (!sl.empty()){ - dprintf(DEBUG_INFO,"\033[33m[CComponentsTimer][%s] disconnect timer slot ...\033[0m\n", __func__); - sl.disconnect(); - } - return true; + while (!sl_stop_timer.empty()) + sl_stop_timer.disconnect(); } } +} + +bool CComponentsTimer::startTimer() +{ + tm_enable = true; + initThread(); + if(tm_thread) + return true; + return false; } + +bool CComponentsTimer::stopTimer() +{ + tm_enable = false; + stopThread(); + if(tm_thread == 0) + return true; + + return false; +} + +void CComponentsTimer::setTimerInterval(const int& seconds) +{ + if (tm_interval == seconds) + return; + + tm_interval = seconds; +} diff --git a/src/gui/components/cc_timer.h b/src/gui/components/cc_timer.h index 321a0b184..a653889c3 100644 --- a/src/gui/components/cc_timer.h +++ b/src/gui/components/cc_timer.h @@ -34,42 +34,96 @@ #include #include -//! Member of CComponents. Provides a generic timer class -/*! - +/**CComponentsTimer +* Member of CComponents. Provides a generic timer class +* @see +* CComponentsTimer() */ - class CComponentsTimer : public sigc::trackable { private: ///thread pthread_t tm_thread; + ///refresh interval in seconds int tm_interval; - ///init function to start timer in own thread - static void* initTimerThread(void *arg); - ///mutex for timer - OpenThreads::Mutex mutex; - ///slot for signals - sigc::slot0 sl; + ///init function to init shared timer action + static void* initThreadAction(void *arg); + + ///init function to start/stop timer in own thread + void initThread(); + void stopThread(); + + ///runs shared timer action provided inside OnTimer() signal + void runSharedTimerAction(); + + ///flag to control thread state + bool tm_enable; + + ///mutex for timer + OpenThreads::Mutex tm_mutex; + ///slot for restart signals + sigc::slot0 sl_stop_timer; public: - ///class constructor, parameter interval sets the interval in seconds, default value=1 (1 sec) + /**Constructor for timer class + * + * @param[in] interval + * @li int interval in seconds, default value=1 (1 sec) + * If init value for interval > 0, timer starts immediately + * @see + * setTimerInterval(); + */ CComponentsTimer(const int& interval = 1); ~CComponentsTimer(); - ///start timer thread, returns true on success, if false causes log output + /**Starts timer thread + * @return + * bool + * returns true, if timer is running in thread + * @see + * stopTimer() + */ bool startTimer(); - ///stop timer thread, returns true on success, if false causes log output + + /**Stops timer thread + * @return + * bool + * returns true, if timer thread stopped + * @see + * startTimer() + */ bool stopTimer(); - ///returns true, if timer is running in thread + /**get current timer status + * @return + * bool + * returns true, if timer is running in thread + * @see + * startTimer() + * stopTimer() + */ bool isRun() const {return tm_thread;}; - ///set another interval in seconds - void setTimerIntervall(const int& seconds){tm_interval = seconds;}; - ///signal for timer event, use this in your class where ever you need time controled actions - ///for more details see also CComponentsSignals for similar handlings + /**set interval in seconds + * @param[in] seconds + * @li int + * @return + * void + * @see + * tm_interval + */ + void setTimerInterval(const int& seconds); + + /**Provides a signal handler to receive any function or methode. + * Use this in your class where ever you need time controled actions. + * + * @param[in] seconds + * @li int + * @see + * CComponentsSignals for similar handlings. + * CComponentsFrmClock::startClock() + */ sigc::signal OnTimer; }; diff --git a/src/gui/test_menu.cpp b/src/gui/test_menu.cpp index e3690d791..b9116d6f2 100644 --- a/src/gui/test_menu.cpp +++ b/src/gui/test_menu.cpp @@ -679,7 +679,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey) if (clock_r == NULL){ clock_r = new CComponentsFrmClock(100, 50, NULL, "%H.%M:%S", NULL, true); clock_r->setClockFont(g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_CHANNAME]); - clock_r->setClockIntervall(1); + clock_r->setClockInterval(1); // clock_r->doPaintBg(false); }