mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-27 15:32:59 +02:00
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:
@@ -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);
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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)){
|
||||
|
@@ -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;}
|
||||
|
||||
@@ -136,6 +137,8 @@ class CComponentsFrmClock : public CComponentsForm, public CCTextScreen
|
||||
///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
|
||||
void setClockFormat(const char* prformat_str, const char* secformat_str = NULL);
|
||||
@@ -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; }
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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) {
|
||||
|
@@ -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();
|
||||
|
@@ -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)){
|
||||
|
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user