cc_timer/cc_frm_clock: allow use of milisecond intervals

Should be easier and more flexible to handle without nano parameter,
some reworkes in other classes and thread handlings are required.
This commit is contained in:
2020-01-05 21:17:59 +01:00
parent 06aec40a25
commit b1f9c3c7f3
10 changed files with 233 additions and 239 deletions

View File

@@ -841,11 +841,12 @@ bool CCDraw::paintBlink(CComponentsTimer* Timer)
return false;
}
bool CCDraw::paintBlink(const int& interval, bool is_nano)
bool CCDraw::paintBlink(const int64_t& interval)
{
if (cc_draw_timer == NULL){
cc_draw_timer = new CComponentsTimer(interval, is_nano);
cc_draw_timer = new CComponentsTimer(interval);
cc_draw_timer->setThreadName(__func__);
cc_draw_timer->startTimer();
}
return paintBlink(cc_draw_timer);

View File

@@ -328,8 +328,7 @@ class CCDraw : public COSDFader, public CComponentsSignals, public CCTypes
*
* @return bool returns true if effect is successful started
*
* @param[in] interval optional, interval time as int, default = 1
* @param[in] is_nano optional, time mode as bool, default = false means as seconds, true means nano seconds.
* @param[in] interval optional, interval time as int64_t in miliseconds, default = 1000 (1 sec)
*
* @see take a look into test menu class for examples.
* cancelBlink()
@@ -340,7 +339,7 @@ class CCDraw : public COSDFader, public CComponentsSignals, public CCTypes
* and it's possible you must remove from screen before e.g.:
* item->kill();
*/
bool paintBlink(const int& interval = 1, bool is_nano = false);
bool paintBlink(const int64_t& interval = 1000);
/**Cancel blink effect
*

View File

@@ -3,7 +3,7 @@
Copyright (C) 2001 by Steffen Hehn 'McClean'
Generic GUI-related component.
Copyright (C) 2013-2015 Thilo Graf 'dbt'
Copyright (C) 2013-2019 Thilo Graf 'dbt'
License: GPL
@@ -47,7 +47,7 @@ CComponentsFrmClock::CComponentsFrmClock( const int& x_pos,
const char* prformat_str,
const char* secformat_str,
bool activ,
const int& interval_seconds,
const int64_t& interval_seconds,
CComponentsForm* parent,
int shadow_mode,
fb_pixel_t color_frame,
@@ -86,15 +86,14 @@ CComponentsFrmClock::CComponentsFrmClock( const int& x_pos,
//init general clock dimensions
height = height_old= cl_font->getHeight();
width = width_old = cl_font->getRenderWidth(cl_format_str);
width = width_old = 0;//cl_font->getRenderWidth(cl_format_str);
//set default text background behavior
cc_txt_save_screen = false;
//set default running clock properties
cl_interval = interval_seconds;
cl_interval = interval_seconds * 1000;
cl_timer = NULL;
cl_blocked = true;
#if 0
may_blit = true;
#endif
@@ -216,7 +215,7 @@ void CComponentsFrmClock::initCCLockItems()
minSepWidth = max(cl_font->getRenderWidth(sep[i]), minSepWidth);
//get minimal required dimensions for segements from current format string
int w_text_min = max(cl_font->getRenderWidth(s_time), width);
cl_width = 0; //summary of all segments (labels)
int h_text_min = max(cl_font->getHeight(), height);
//init some temporary variables
@@ -224,18 +223,19 @@ void CComponentsFrmClock::initCCLockItems()
int h_tmp = h_text_min;
int y_tmp = y;
//summary of all segments (labels)
int w_segments = 0;
const bool force_repaint = cl_force_repaint;
// dprintf(DEBUG_NORMAL, "\033[33m[CComponentsFrmClock][%s - %d], clock width width %d \033[0m\n", __func__, __LINE__, width);
/* modify available label items with current segment chars
* we are using segments with only one char per segment,
* these chars are predefined via format string
*/
for (size_t i = 0; i < v_cc_items.size(); i++)
{
std::lock_guard<std::mutex> g(cc_frm_mutex);
//v_cc_items are only available as CComponent-items here, so we must cast them before
if (!v_cc_items[i])
continue;
CComponentsLabel *lbl = static_cast <CComponentsLabel*> (v_cc_items[i]);
//add rounded corners only to 1st and last segment
@@ -261,6 +261,7 @@ void CComponentsFrmClock::initCCLockItems()
//set size, text, color of current item
lbl->setDimensionsAll(x_tmp, y_tmp, w_tmp, h_tmp);
lbl->setFrameThickness(0);
lbl->setColorAll(col_frame, col_body, col_shadow);
lbl->forceTextPaint(force_repaint);
lbl->setText(stmp, CTextBox::CENTER, cl_font, cl_col_text, cl_font_style);
@@ -278,33 +279,43 @@ void CComponentsFrmClock::initCCLockItems()
ctb->setFontUseDigitHeight();
//ensure paint of text and label bg on changed text or painted form background
bool force_txt_and_bg = (lbl->textChanged() || this->paint_bg);
bool force_txt_and_bg = (lbl->textChanged() || paint_bg);
lbl->forceTextPaint(force_txt_and_bg);
#endif
//set xpos and width of item (segment)
lbl->setWidth(w_tmp);
x_tmp += w_tmp;
x_tmp += lbl->getWidth();//w_tmp;
//sum required width for clock (this)
w_segments += w_tmp;
cl_width += lbl->getWidth();//w_tmp;
h_text_min = max(lbl->getHeight(), height);
height = max(lbl->getHeight(), height);
// dprintf(DEBUG_NORMAL, "\033[33m[CComponentsFrmClock][%s - %d], clock width width %d cl_width = %d\033[0m\n", __func__, __LINE__, width, cl_width);
}
//set required width for clock (this)
width = max(w_text_min, w_segments);
int w_std = width;
if (cl_width > width){
width = cl_width;
}
// dprintf(DEBUG_NORMAL, "\033[33m[CComponentsFrmClock][%s - %d], clock width width %d w_std %d cl_width = %d\033[0m\n", __func__, __LINE__, width, w_std, cl_width);
//use first item as reference and set x and y position to the 1st segement item with definied alignment
int x_lbl = width/2-w_segments/2;
v_cc_items[0]->setXPos(x_lbl);
//ensure unsigned position values
int x_lbl = max(0, width/2-cl_width/2);
int y_lbl = max(0, height/2-h_text_min/2);
int y_lbl = height/2-h_text_min/2;
v_cc_items[0]->setYPos(y_lbl);
if (v_cc_items.front())
v_cc_items.front()->setPos(x_lbl, y_lbl);
//set all evaluated position values to all other segement items
for (size_t i = 1; i < v_cc_items.size(); i++){
x_lbl += v_cc_items[i-1]->getWidth();
v_cc_items[i]->setPos(x_lbl, y_lbl);
if (v_cc_items.at(i)){
if (v_cc_items.at(i-1)){
x_lbl += v_cc_items.at(i-1)->getWidth();
v_cc_items.at(i)->setPos(x_lbl, y_lbl);
}
}
}
}
@@ -312,60 +323,57 @@ void CComponentsFrmClock::initCCLockItems()
//this member is provided for slot with timer event "OnTimer"
void CComponentsFrmClock::ShowTime()
{
if (!cl_blocked) {
//paint segements, but wihtout saved backgrounds
paint(CC_SAVE_SCREEN_NO);
}
//paint segements, but wihtout saved backgrounds
this->CComponentsFrmClock::paint(CC_SAVE_SCREEN_NO);
}
//start up ticking clock controled by timer with signal/slot, return true on succses
bool CComponentsFrmClock::startClock()
{
if (cl_interval <= 0){
dprintf(DEBUG_NORMAL, "[CComponentsFrmClock] [%s] clock is set to active, but interval is initialized with value %d ...\n", __func__, cl_interval);
return false;
if (stopClock()){
if (cl_interval <= 0){
dprintf(DEBUG_NORMAL, "[CComponentsFrmClock] [%s] clock is set to active, but interval is initialized with value %l ...\n", __func__, cl_interval);
return false;
}
if (!cl_timer){
cl_timer = new CComponentsTimer(0);
cl_timer->setThreadName(getItemName());
cl_timer->OnTimer.connect(cl_sl_show);
force_paint_bg = true;
cl_timer->setTimerInterval(cl_interval);
cl_timer->startTimer();
}
}
if (cl_timer == NULL)
cl_timer = new CComponentsTimer(0);
cl_timer->setThreadName(getItemName());
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_show);
force_paint_bg = true;
}
cl_timer->setTimerInterval(cl_interval);
if (cl_timer->startTimer())
return true;
return false;
return isRun();
}
//stop ticking clock and internal timer, return true on succses
bool CComponentsFrmClock::stopClock()
{
if (cl_timer){
if (cl_timer->stopTimer()){
dprintf(DEBUG_INFO, "[CComponentsFrmClock] [%s] stopping clock...\n", __func__);
clear();
delete cl_timer;
cl_timer = NULL;
return true;
}
else
dprintf(DEBUG_NORMAL, "[CComponentsFrmClock] [%s] stopping timer failed...\n", __func__);
if (!cl_timer){
return true;
}else{
delete cl_timer;
cl_timer = NULL;
clear();
cc_allow_paint = true;
return true;
}
return false;
return isRun();
}
bool CComponentsFrmClock::Start()
{
if (startClock()) {
cl_blocked = !cc_allow_paint;
if (cl_timer){
if (!cc_allow_paint)
cl_timer->OnTimer.block();
else
cl_timer->OnTimer.unblock();
}
return true;
}
return false;
@@ -373,10 +381,8 @@ bool CComponentsFrmClock::Start()
bool CComponentsFrmClock::Stop()
{
if (stopClock()){
cl_blocked = true;
if (stopClock())
return true;
}
return false;
}
@@ -391,7 +397,6 @@ void CComponentsFrmClock::paint(const bool &do_save_bg)
//paint form contents
CComponentsForm::paint(do_save_bg);
}
void CComponentsFrmClock::setClockFont(Font *font, const int& style)
@@ -420,6 +425,9 @@ void CComponentsFrmClock::enableTboxSaveScreen(bool mode)
{
if (cc_txt_save_screen == mode || v_cc_items.empty())
return;
std::lock_guard<std::mutex> g(cl_mutex);
cc_txt_save_screen = mode;
for (size_t i = 0; i < v_cc_items.size(); i++){
CComponentsLabel *seg = static_cast <CComponentsLabel*>(v_cc_items[i]);
@@ -429,6 +437,8 @@ void CComponentsFrmClock::enableTboxSaveScreen(bool mode)
void CComponentsFrmClock::setHeight(const int& h)
{
std::lock_guard<std::mutex> g(cl_mutex);
if (h == height)
return;
@@ -443,18 +453,31 @@ void CComponentsFrmClock::setHeight(const int& h)
void CComponentsFrmClock::setWidth(const int& w)
{
std::lock_guard<std::mutex> g(cl_mutex);
if (w == width)
return;
else
CComponentsItem::setWidth(w);
#if 0
int f_width = cl_font->getRenderWidth(cl_format_str);
if (w != f_width){
dprintf(DEBUG_NORMAL, "\033[33m[CComponentsFrmClock]\t[%s - %d], font width is different than current width [%d], using [%d] ...\033[0m\n", __func__, __LINE__, w, f_width);
CComponentsItem::setWidth(f_width);
}else
CComponentsItem::setWidth(w);
#endif
initCCLockItems();
}
int CComponentsFrmClock::getWidth() const
{
if (width > cl_width)
return width;
return cl_width;
}
bool CComponentsFrmClock::enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color)
{
if (CCDraw::enableColBodyGradient(enable_mode, sec_color)){

View File

@@ -3,7 +3,7 @@
Copyright (C) 2001 by Steffen Hehn 'McClean'
Classes for generic GUI-related components.
Copyright (C) 2012-2015, Thilo Graf 'dbt'
Copyright (C) 2012-2019, Thilo Graf 'dbt'
License: GPL
@@ -36,6 +36,7 @@
#include "cc_frm.h"
#include "cc_text_screen.h"
#include "cc_timer.h"
//! Sub class of CComponents. Show clock with digits on screen.
/*!
Usable as simple fixed display or as ticking clock.
@@ -49,22 +50,17 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
#if 0
bool may_blit;
#endif
protected:
CComponentsTimer *cl_timer;
///slot for timer event, reserved for ShowTime()
sigc::slot0<void> cl_sl_show;
std::mutex cl_mutex;
///refresh interval in seconds
int cl_interval;
int64_t cl_interval;
///raw time chars
char cl_timestr[32];
///handle paint clock within thread and is not similar to cc_allow_paint
bool cl_blocked;
///object: font render object
Font *cl_font;
int cl_font_style;
@@ -82,10 +78,12 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
///secondary time format for blink
std::string cl_blink_str;
int cl_width;
///initialize clock contents
void initCCLockItems();
///initialize timestring, called in initCCLockItems()
virtual void initTimeString();
void initTimeString();
///start ticking clock, returns true on success, if false causes log output
bool startClock();
@@ -103,7 +101,7 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
const char* format_str = "%H:%M",
const char* secformat_str = NULL,
bool activ=false,
const int& interval_seconds = 1,
const int64_t& interval_seconds = 1,
CComponentsForm *parent = NULL,
int shadow_mode = CC_SHADOW_OFF,
fb_pixel_t color_frame = COL_FRAME_PLUS_0,
@@ -128,6 +126,9 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
///return pointer of font object
Font* getClockFont();
///return pointer of timer object
CComponentsTimer* getTimer(){return cl_timer;}
///set text color
void setTextColor(fb_pixel_t color_text){ cl_col_text = color_text;}
@@ -135,6 +136,8 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
void setHeight(const int& h);
///set width of clock on screen
void setWidth(const int& w);
int getWidth() const;
///use string expession: "%H:%M" = 12:22, "%H:%M:%S" = 12:22:12
///set current time format string, 1st parameter set the default format, 2nd parameter sets an alternatively format for use as blink effect
@@ -145,18 +148,18 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
///start and paint ticking clock
bool Start();
///same like Start() but for usage as simple call without return value
void unblock(){Start();}
void unblock(){if (cl_timer) cl_timer->OnTimer.unblock();}
///stop ticking clock, but don't hide, use kill() or hide() to remove from screen
bool Stop();
///same like Stop() but for usage as simple call without return value
void block(){Stop();}
void block(){if (cl_timer) cl_timer->OnTimer.block();}
///return true on blocked status, blocked means clock can be initalized but would be not paint, to unblock use unblock()
bool isBlocked(void) {return cl_blocked;}
bool isBlocked(void) const {return cl_timer ? cl_timer->OnTimer.blocked() : true;}
///returns true, if clock is running
bool isRun() const {return cl_timer ? cl_timer->isRun() : false;}
///set refresh interval in seconds, default value=1 (=1 sec)
void setClockInterval(const int& seconds){cl_interval = seconds;}
void setClockInterval(const int64_t& seconds){cl_interval = seconds*1000;}
///show clock on screen
void paint(const bool &do_save_bg = CC_SAVE_SCREEN_YES);
@@ -187,6 +190,9 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
///set color gradient on/off, returns true if gradient mode was changed
bool enableColBodyGradient(const int& enable_mode, const fb_pixel_t& sec_color = 255 /*=COL_BACKGROUND*/);
///slot for timer event, reserved for ShowTime()
sigc::slot0<void> cl_sl_show;
#if 0
///enable/disable automatic blitting
void setBlit(bool _may_blit = true) { may_blit = _may_blit; }

View File

@@ -3,7 +3,7 @@
Copyright (C) 2001 by Steffen Hehn 'McClean'
Generic Timer.
Copyright (C) 2013-2016, Thilo Graf 'dbt'
Copyright (C) 2013-2019, Thilo Graf 'dbt'
License: GPL
@@ -29,154 +29,127 @@
#include <neutrino.h>
#include "cc_timer.h"
#include <pthread.h>
#include "cc_types.h"
#include <errno.h>
#include <system/helpers.h>
#include <system/debug.h>
#include <system/set_threadname.h>
#include <mutex>
#include <chrono>
using namespace std;
CComponentsTimer::CComponentsTimer(const int& interval, bool is_nano)
{
name = "unnamed";
tm_thread = 0;
tm_interval = interval;
tm_enable_nano = is_nano;
tm_enable = false;
sl_stop_timer = sigc::mem_fun(*this, &CComponentsTimer::stopTimer);
if (interval > 0)
tm_enable = startTimer();
CComponentsTimer::CComponentsTimer(const int64_t& interval)
{
tm_thread_name = string();
tm_interval = interval;
tm_enable = false;
sl_cleanup_timer = sigc::mem_fun(*this, &CComponentsTimer::stopThread);
CNeutrinoApp::getInstance()->OnBeforeRestart.connect(sl_cleanup_timer);
CNeutrinoApp::getInstance()->OnShutDown.connect(sl_cleanup_timer);
tm_thread = NULL;
}
CComponentsTimer::~CComponentsTimer()
{
stopTimer();
stopThread();
}
int CComponentsTimer::getSleep(long miliseconds)
void CComponentsTimer::threadCallback(CComponentsTimer *tm)
{
struct timespec req, rem;
if (!tm)
return;
if(miliseconds > 999){
req.tv_sec = (time_t)(miliseconds / 1000);
req.tv_nsec = (miliseconds - ((long)req.tv_sec * 1000)) * 1000000;
}else{
req.tv_sec = 0;
req.tv_nsec = miliseconds * 1000000;
}
if (tm->OnTimer.empty())
dprintf(DEBUG_NORMAL," \033[36m[CComponentsTimer] [%s - %d] Signal OnTimer is empty, no callback defined \033[0m\n", __func__, __LINE__);
return nanosleep(&req , &rem);
}
tm->tn = "cc.timer:" + tm->tm_thread_name;
set_threadname(tm->tn.c_str());
void CComponentsTimer::runSharedTimerAction()
{
//start loop
tn = "cc:"+name;
set_threadname(tn.c_str());
while(tm_enable && tm_interval > 0 && !OnTimer.empty()) {
tm_mutex.lock();
OnTimer();
if (!tm_enable_nano){
sleep(tm_interval);
}else{
//behavior is different on cst hardware
long corr_factor = 1;
#if ! HAVE_COOL_HARDWARE
corr_factor = 10;
dprintf(DEBUG_DEBUG,"\033[32m[CComponentsTimer] thread [%p] [%s] [%s - %d] loop start \033[0m\n", tm->tm_thread, tm->tn.c_str(), __func__, __LINE__);
#if HAVE_COOL_HARDWARE //time offset
const int64_t MAX_COUNT = tm->tm_interval / 10;
#else
const int64_t MAX_COUNT = tm->tm_interval;
#endif
int res = getSleep(tm_interval * corr_factor);
if (res != 0)
dprintf(DEBUG_NORMAL,"\033[33m[CComponentsTimer] [%s - %d] ERROR: returns [%d] \033[0m\n", __func__, __LINE__, res);
int64_t i = 0;
TIMER_START();
while(tm->tm_enable) //exit loop handled in destructor
{
if (tm->tm_interval > 0)
{
for (i = 0; i < MAX_COUNT; i++)
i += tm->tm_interval;
i = 0;
if (!tm->OnTimer.blocked())
{
tm->OnTimer();
while (i < MAX_COUNT)
{
if (tm->tm_enable)
this_thread::sleep_for(std::chrono::milliseconds(1));
i++;
}
}
}
tm_mutex.unlock();
}
if (tm_thread)
stopThread();
dprintf(DEBUG_DEBUG,"\033[32m[CComponentsTimer] thread [%p] [%s] [%s - %d] loop/callback finished\033[0m\n ", tm->tm_thread, tm->tn.c_str(), __func__, __LINE__);
}
//thread handle
void* CComponentsTimer::initThreadAction(void *arg)
{
CComponentsTimer *timer = static_cast<CComponentsTimer*>(arg);
timer->runSharedTimerAction();
return 0;
}
//start up running timer with own thread, return true on succses
//start up running timer with own thread
void CComponentsTimer::initThread()
{
if(!tm_thread) {
void *ptr = static_cast<void*>(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;
}else
dprintf(DEBUG_DEBUG,"\033[33m[CComponentsTimer] [%s - %d] started thread ID:%ld \033[0m\n", __func__, __LINE__, pthread_self());
if (res == 0)
CNeutrinoApp::getInstance()->OnBeforeRestart.connect(sigc::retype_return<void>(sl_stop_timer));
if (!tm_thread)
{
tm_enable = true;
tm_thread = new std::thread (threadCallback, this);
tm_mutex.lock();
}
}
void CComponentsTimer::stopThread()
{
//ensure disconnecting possible slots
while (!sl_stop_timer.empty())
sl_stop_timer.disconnect();
if (tm_thread) {
tm_enable = false;
tm_mutex.unlock();
tm_thread->join();
dprintf(DEBUG_DEBUG,"\033[32m[CComponentsTimer] thread [%p] [%s] [%s - %d] joined\033[0m\n", tm_thread, tn.c_str(), __func__, __LINE__);
while(tm_thread) {
int thres = pthread_cancel(tm_thread);
if (thres != 0)
dprintf(DEBUG_NORMAL,"\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_cancel, error [%d] %s\033[0m\n", __func__, __LINE__, thres, strerror(thres));
void* res;
thres = pthread_join(tm_thread, &res);
if (res != PTHREAD_CANCELED)
dprintf(DEBUG_NORMAL, "\033[33m[CComponentsTimer] [%s - %d] ERROR! pthread_join, thread ID:%ld, error [%d] %s\033[0m\n", __func__, __LINE__, pthread_self(), thres, strerror(thres));
else
tm_thread = 0;
delete tm_thread;
tm_thread = NULL;
tn.clear();
dprintf(DEBUG_DEBUG,"\033[32m[CComponentsTimer] thread [%p] [%s] [%s - %d] thread object terminated\033[0m\n", tm_thread, tn.c_str(), __func__, __LINE__);
}
}
bool CComponentsTimer::startTimer()
void CComponentsTimer::startTimer()
{
initThread();
if(tm_thread)
tm_enable = true;
return tm_enable;
}
bool CComponentsTimer::stopTimer()
void CComponentsTimer::stopTimer()
{
tm_enable = false;
stopThread();
if(tm_thread == 0){
if (!OnTimer.empty())
OnTimer.clear();
return true;
}
return false;
}
void CComponentsTimer::setTimerInterval(const int& interval, bool is_nano)
bool CComponentsTimer::isRun() const
{
if (tm_interval == interval && tm_enable_nano == is_nano)
bool ret = tm_enable && tm_thread;
return ret;
}
void CComponentsTimer::setTimerInterval(const int64_t& interval)
{
if (tm_interval == interval)
return;
tm_enable_nano = is_nano;
stopTimer();
tm_interval = interval;
startTimer();
}

View File

@@ -3,7 +3,7 @@
Copyright (C) 2001 by Steffen Hehn 'McClean'
Classes for generic GUI-related components.
Copyright (C) 2013-2015, Thilo Graf 'dbt'
Copyright (C) 2013-2019, Thilo Graf 'dbt'
License: GPL
@@ -31,9 +31,8 @@
#include <sigc++/signal.h>
#include <sigc++/adaptors/retype_return.h>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Thread>
#include <OpenThreads/Condition>
#include <thread>
#include <mutex>
/**CComponentsTimer
* Member of CComponents. Provides a generic timer class
@@ -44,95 +43,83 @@ class CComponentsTimer : public sigc::trackable
{
private:
///thread
pthread_t tm_thread;
std::thread *tm_thread;
std::mutex tm_mutex;
///flag to control thread state
bool tm_enable;
///refresh interval in seconds
int tm_interval;
bool tm_enable_nano;
///init function to init shared timer action
static void* initThreadAction(void *arg);
int64_t tm_interval;
///init function to start/stop timer in own thread
void initThread();
void stopThread();
///runs shared timer action provided inside OnTimer() signal
void runSharedTimerAction();
static void threadCallback(CComponentsTimer *tm);
///flag to control thread state
bool tm_enable;
sigc::slot<void> sl_cleanup_timer;
///name for the thread
std::string name;
std::string tm_thread_name;
std::string tn;
///mutex for timer
OpenThreads::Mutex tm_mutex;
///slot for restart signals
sigc::slot0<bool> sl_stop_timer;
///sleep generated with nanosleep
int getSleep(long miliseconds);
public:
/**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
* @li bool default = false as seconds mode, true = nano seconds mode
* @li int64_t interval in miliseconds, default value=1000 ms (1 sec)
* @see
* setTimerInterval();
*/
CComponentsTimer(const int& interval = 1, bool is_nano = false);
CComponentsTimer(const int64_t& interval = 1000);
~CComponentsTimer();
/**Starts timer thread
* @return
* bool
* returns true, if timer is running in thread
/**Acivate timer
* @see
* stopTimer()
*/
bool startTimer();
void startTimer();
/**Stops timer thread
* @return
* bool
* returns true, if timer thread stopped
/**Disable timer
* @see
* startTimer()
*/
bool stopTimer();
void stopTimer();
/**Cancel timer thread
* @see
* stopTimer()
*/
void cancelTimerThread(){stopThread();}
/**get current timer status
* @return
* bool
* returns true, if timer is running in thread
* returns true, if timer is active
* @see
* startTimer()
* stopTimer()
*/
bool isRun() const {return tm_thread;};
bool isRun() const;
/**set timer interval
* @param[in] interval
* @li int default interval in seconds, if second parameter = true interval is used as nano seconds
* @li bool default = false as seconds mode, true = nano seconds mode
* @li int64_t default interval in miliseconds
* @return
* void
* @see
* tm_interval
*/
void setTimerInterval(const int& interval, bool is_nano = false);
void setTimerInterval(const int64_t& interval);
/**set thread name
* @param[in] thread name
* @return
* void
*/
void setThreadName(const std::string& n) { name = tn = n; }
void setThreadName(const std::string& n) { tm_thread_name = tn = n; }
/**Provides a signal handler to receive any function or methode.
* Use this in your class where ever you need time controled actions.

View File

@@ -90,8 +90,8 @@ void CInfoClock::ClearDisplay()
{
bool run = isRun();
this->kill();
clearSavedScreen();
initCCLockItems();
if (clearSavedScreen())
initCCLockItems();
//provokes full repaint for next activation, otherwise clock segments only repaints on changed content
clear();
if (run)
@@ -104,9 +104,12 @@ bool CInfoClock::StartInfoClock()
return Start();
}
bool CInfoClock::StopInfoClock()
bool CInfoClock::StopInfoClock(bool exit_thread)
{
bool ret = Stop();
if (exit_thread)
if (cl_timer)
cl_timer->cancelTimerThread();
kill();
clear();
@@ -115,6 +118,8 @@ bool CInfoClock::StopInfoClock()
bool CInfoClock::enableInfoClock(bool enable)
{
std::lock_guard<std::mutex> g(cl_mutex);
bool ret = false;
if (g_settings.mode_clock) {
if (enable) {

View File

@@ -38,11 +38,11 @@ class CInfoClock : public CComponentsFrmClock
void initCCLockItems();
public:
CInfoClock();
// ~CInfoClock(); // inherited from CComponentsFrmClock
virtual ~CInfoClock(){}; // inherited from CComponentsFrmClock
static CInfoClock* getInstance();
bool StartInfoClock();
bool StopInfoClock();
bool StopInfoClock(bool exit_thread = false);
bool enableInfoClock(bool enable = true);
bool disableInfoClock() {return enableInfoClock(false);}
void ClearDisplay();

View File

@@ -438,7 +438,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
if (sq == NULL)
sq = new CComponentsShapeSquare (0, 0, 100, 100, NULL, CC_SHADOW_ON, COL_OLIVE, COL_LIGHT_GRAY, COL_RED);
sq->paintBlink(50, true);
sq->paintBlink(500);
sleep(10);
if (sq->cancelBlink())
@@ -450,7 +450,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
if (pic == NULL)
pic = new CComponentsPicture (50, 50, 50, 50, ICONSDIR "/btn_pause.png");
pic->paintBlink(50, true);
pic->paintBlink(500);
sleep(10);
if (pic->cancelBlink())
@@ -529,7 +529,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
ptmp->kill();
}
if (static_cast<CComponentsPicture*>(form->getCCItem(0))-> paintBlink(50, true)){
if (static_cast<CComponentsPicture*>(form->getCCItem(0))-> paintBlink(500)){
ShowHint("Testmenu: Blink","Testmenu: Blinking embedded image ...", 700, 10);
}
if (form->getCCItem(0)->cancelBlink()){
@@ -560,7 +560,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
txt->setText("This is a text for testing textbox", CTextBox::NO_AUTO_LINEBREAK);
}
if (txt->paintBlink(50, true)){
if (txt->paintBlink(50)){
ShowHint("Testmenu: Blink","Testmenu: Blinking text is running ...", 700, 10);
}
if (txt->cancelBlink()){
@@ -591,7 +591,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
text_ext->setFrameThickness(2);
}
if (text_ext->paintBlink(50, true)){
if (text_ext->paintBlink(500)){
ShowHint("Testmenu: Blink","Testmenu: Blinking extended text is running ...", 700, 10);
}
if (text_ext->cancelBlink()){
@@ -738,7 +738,7 @@ int CTestMenu::exec(CMenuTarget* parent, const std::string &actionKey)
CComponentsPicture* img = static_cast<CComponentsPicture*>(iconform->getCCItem(2));
img->kill();
if (img->paintBlink(50, true)){
if (img->paintBlink(500)){
ShowHint("Testmenu: Blink","Testmenu: Blinking image is running ...", 700, 10);
}
if (img->cancelBlink(true)){

View File

@@ -218,14 +218,14 @@ void CHintBox::enableTimeOutBar(bool enable)
if(timeout_pb){
timeout_pb->paint0();
timeout_pb->setValues(timeout_pb->getValue()+1, 100*timeout);
timeout_pb->setValues(timeout_pb->getValue()+1, 10*timeout);
}else{
timeout_pb = new CProgressBar();
timeout_pb->setType(CProgressBar::PB_TIMESCALE);
timeout_pb->setDimensionsAll(ccw_body->getRealXPos(), ccw_body->getRealYPos(), ccw_body->getWidth(), TIMEOUT_BAR_HEIGHT);
timeout_pb->setValues(0, 100*timeout);
timeout_pb->setValues(0, timeout);
if (!timeout_pb_timer) {
timeout_pb_timer = new CComponentsTimer(1, true);
timeout_pb_timer = new CComponentsTimer(100);
const string tn = cc_item_type.name + ":timeout_bar:";
timeout_pb_timer->setThreadName(tn);
}