optimize text list view
when too much data has been sent to the text list view, way too much GUI processing is done, let's batch-process the changes and then tell the GUI that something has changed
This commit is contained in:
@@ -35,12 +35,16 @@ void xy_plot_set_points(gui *gui, widget *this,
|
|||||||
void text_list_add(gui *gui, widget *this, const char *text, int position,
|
void text_list_add(gui *gui, widget *this, const char *text, int position,
|
||||||
int color);
|
int color);
|
||||||
void text_list_del(gui *gui, widget *this, int position);
|
void text_list_del(gui *gui, widget *this, int position);
|
||||||
|
void text_list_add_silent(gui *gui, widget *this, const char *text,
|
||||||
|
int position, int color);
|
||||||
|
void text_list_del_silent(gui *gui, widget *this, int position);
|
||||||
void text_list_state(gui *_gui, widget *_this,
|
void text_list_state(gui *_gui, widget *_this,
|
||||||
int *visible_lines, int *start_line, int *number_of_lines);
|
int *visible_lines, int *start_line, int *number_of_lines);
|
||||||
void text_list_set_start_line(gui *gui, widget *this, int line);
|
void text_list_set_start_line(gui *gui, widget *this, int line);
|
||||||
void text_list_get_line(gui *gui, widget *this, int line,
|
void text_list_get_line(gui *gui, widget *this, int line,
|
||||||
char **text, int *color);
|
char **text, int *color);
|
||||||
void text_list_set_color(gui *gui, widget *this, int line, int color);
|
void text_list_set_color(gui *gui, widget *this, int line, int color);
|
||||||
|
void text_list_dirty(gui *_gui, widget *_this);
|
||||||
|
|
||||||
void gui_loop(gui *gui);
|
void gui_loop(gui *gui);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ static void paint(gui *_gui, widget *_this)
|
|||||||
struct gui *g = _gui;
|
struct gui *g = _gui;
|
||||||
struct text_list_widget *this = _this;
|
struct text_list_widget *this = _this;
|
||||||
int i, j;
|
int i, j;
|
||||||
LOGD("PAINT text_list %p xywh %d %d %d %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height);
|
LOGD("PAINT text_list %p xywh %d %d %d %d starting line %d allocated nlines %d text_count %d\n", _this, this->common.x, this->common.y, this->common.width, this->common.height, this->starting_line, this->allocated_nlines, this->text_count);
|
||||||
x_fill_rectangle(g->x, g->xwin, this->background_color,
|
x_fill_rectangle(g->x, g->xwin, this->background_color,
|
||||||
this->common.x, this->common.y,
|
this->common.x, this->common.y,
|
||||||
this->common.width, this->common.height);
|
this->common.width, this->common.height);
|
||||||
@@ -95,8 +95,8 @@ widget *new_text_list(gui *_gui, int width, int nlines, int bgcol)
|
|||||||
/* public functions */
|
/* public functions */
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
void text_list_add(gui *_gui, widget *_this, const char *text, int position,
|
static void _text_list_add(gui *_gui, widget *_this, const char *text,
|
||||||
int color)
|
int position, int color, int silent)
|
||||||
{
|
{
|
||||||
struct gui *g = _gui;
|
struct gui *g = _gui;
|
||||||
struct text_list_widget *this = _this;
|
struct text_list_widget *this = _this;
|
||||||
@@ -120,12 +120,12 @@ void text_list_add(gui *_gui, widget *_this, const char *text, int position,
|
|||||||
this->text[position] = strdup(text); if (this->text[position] == NULL) OOM;
|
this->text[position] = strdup(text); if (this->text[position] == NULL) OOM;
|
||||||
this->color[position] = color;
|
this->color[position] = color;
|
||||||
|
|
||||||
send_event(g, DIRTY, this->common.id);
|
if (!silent) send_event(g, DIRTY, this->common.id);
|
||||||
|
|
||||||
gunlock(g);
|
gunlock(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_list_del(gui *_gui, widget *_this, int position)
|
static void _text_list_del(gui *_gui, widget *_this, int position, int silent)
|
||||||
{
|
{
|
||||||
struct gui *g = _gui;
|
struct gui *g = _gui;
|
||||||
struct text_list_widget *this = _this;
|
struct text_list_widget *this = _this;
|
||||||
@@ -151,12 +151,34 @@ void text_list_del(gui *_gui, widget *_this, int position)
|
|||||||
this->color = realloc(this->color, this->text_count * sizeof(int));
|
this->color = realloc(this->color, this->text_count * sizeof(int));
|
||||||
if (this->color == NULL) OOM;
|
if (this->color == NULL) OOM;
|
||||||
|
|
||||||
send_event(g, DIRTY, this->common.id);
|
if (!silent) send_event(g, DIRTY, this->common.id);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
gunlock(g);
|
gunlock(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void text_list_add(gui *gui, widget *this, const char *text, int position,
|
||||||
|
int color)
|
||||||
|
{
|
||||||
|
_text_list_add(gui, this, text, position, color, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_list_del(gui *gui, widget *this, int position)
|
||||||
|
{
|
||||||
|
_text_list_del(gui, this, position, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_list_add_silent(gui *gui, widget *this, const char *text,
|
||||||
|
int position, int color)
|
||||||
|
{
|
||||||
|
_text_list_add(gui, this, text, position, color, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_list_del_silent(gui *gui, widget *this, int position)
|
||||||
|
{
|
||||||
|
_text_list_del(gui, this, position, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void text_list_state(gui *_gui, widget *_this,
|
void text_list_state(gui *_gui, widget *_this,
|
||||||
int *visible_lines, int *start_line, int *number_of_lines)
|
int *visible_lines, int *start_line, int *number_of_lines)
|
||||||
{
|
{
|
||||||
@@ -220,3 +242,12 @@ void text_list_set_color(gui *_gui, widget *_this, int line, int color)
|
|||||||
|
|
||||||
gunlock(g);
|
gunlock(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void text_list_dirty(gui *_gui, widget *_this)
|
||||||
|
{
|
||||||
|
struct gui *g = _gui;
|
||||||
|
struct text_list_widget *this = _this;
|
||||||
|
glock(g);
|
||||||
|
send_event(g, DIRTY, this->common.id);
|
||||||
|
gunlock(g);
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,19 +20,21 @@ struct textlist {
|
|||||||
static void _append(struct textlist *this, char *s)
|
static void _append(struct textlist *this, char *s)
|
||||||
{
|
{
|
||||||
if (this->cursize == this->maxsize) {
|
if (this->cursize == this->maxsize) {
|
||||||
text_list_del(this->g, this->w, 0);
|
text_list_del_silent(this->g, this->w, 0);
|
||||||
this->cursize--;
|
this->cursize--;
|
||||||
}
|
}
|
||||||
text_list_add(this->g, this->w, s, -1, FOREGROUND_COLOR);
|
text_list_add_silent(this->g, this->w, s, -1, FOREGROUND_COLOR);
|
||||||
this->cursize++;
|
this->cursize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *textlist_thread(void *_this)
|
static void *textlist_thread(void *_this)
|
||||||
{
|
{
|
||||||
struct textlist *this = _this;
|
struct textlist *this = _this;
|
||||||
|
int dirty;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (pthread_mutex_lock(&this->lock)) abort();
|
if (pthread_mutex_lock(&this->lock)) abort();
|
||||||
|
dirty = this->to_append == NULL ? 0 : 1;
|
||||||
while (this->to_append != NULL) {
|
while (this->to_append != NULL) {
|
||||||
char *s = this->to_append->data;
|
char *s = this->to_append->data;
|
||||||
this->to_append = list_remove_head(this->to_append);
|
this->to_append = list_remove_head(this->to_append);
|
||||||
@@ -40,6 +42,7 @@ static void *textlist_thread(void *_this)
|
|||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
if (pthread_mutex_unlock(&this->lock)) abort();
|
if (pthread_mutex_unlock(&this->lock)) abort();
|
||||||
|
if (dirty) text_list_dirty(this->g, this->w);
|
||||||
sleepms(1000/this->refresh_rate);
|
sleepms(1000/this->refresh_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user