mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-31 09:21:09 +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.
Origin commit data
------------------
Commit: 5afe92e526
Author: Thilo Graf <dbt@novatux.de>
Date: 2020-01-05 (Sun, 05 Jan 2020)
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;}
|
||||
|
||||
@@ -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; }
|
||||
|
@@ -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.
|
||||
|
@@ -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) {
|
||||
|
@@ -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