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.


Origin commit data
------------------
Commit: 5afe92e526
Author: Thilo Graf <dbt@novatux.de>
Date: 2020-01-05 (Sun, 05 Jan 2020)
This commit is contained in:
2020-01-05 22:22:22 +01:00
committed by vanhofen
parent c30711c4ef
commit de56424c45
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

@@ -93,8 +93,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)
@@ -107,9 +107,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();
@@ -118,6 +121,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);
}