ui: create a generic cache API.

Reduce code duplication, create:

evisum_ui_item_cache_... functions.
This commit is contained in:
Alastair Poole 2020-05-18 12:16:35 +01:00
parent b88601ba7d
commit 914f97e086
7 changed files with 174 additions and 175 deletions

View File

@ -2,6 +2,8 @@ src += files([
'gettext.h',
'ui.h',
'ui.c',
'ui_cache.c',
'ui_cache.h',
'ui_misc.c',
'ui_misc.h',
'ui_disk.c',

View File

@ -303,35 +303,21 @@ _proc_pid_cpu_usage_get(Ui *ui, Proc_Info *proc)
_proc_pid_cpu_time_save(ui, proc);
}
#define ITEM_CACHE_INIT_SIZE 50
typedef struct _Item_Cache {
Evas_Object *obj;
Eina_Bool used;
} Item_Cache;
static void
_item_unrealized_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Ui *ui;
Item_Cache *it;
Evas_Object *o;
Eina_List *l, *contents = NULL;
Eina_List *contents = NULL;
ui = data;
elm_genlist_item_all_contents_unset(event_info, &contents);
EINA_LIST_FREE(contents, o)
{
EINA_LIST_FOREACH(ui->item_cache, l, it)
{
if (it->obj == o)
{
it->used = EINA_FALSE;
break;
}
}
}
{
evisum_ui_item_cache_item_release(ui->cache, o);
}
}
static void
@ -389,45 +375,6 @@ _item_create(Evas_Object *parent)
return table;
}
static void
_item_cache_init(Ui *ui)
{
for (int i = 0; i < ITEM_CACHE_INIT_SIZE; i++)
{
Item_Cache *it = calloc(1, sizeof(Item_Cache));
if (it)
{
it->obj = _item_create(ui->genlist_procs);
ui->item_cache = eina_list_append(ui->item_cache, it);
}
}
}
static Item_Cache *
_item_cache_get(Ui *ui)
{
Eina_List *l;
Item_Cache *it;
EINA_LIST_FOREACH(ui->item_cache, l, it)
{
if (it->used == 0)
{
it->used = 1;
return it;
}
}
it = calloc(1, sizeof(Item_Cache));
if (it)
{
it->obj = _item_create(ui->genlist_procs);
it->used = 1;
ui->item_cache = eina_list_append(ui->item_cache, it);
}
return it;
}
static Evas_Object *
_content_get(void *data, Evas_Object *obj, const char *source)
{
@ -444,7 +391,7 @@ _content_get(void *data, Evas_Object *obj, const char *source)
if (!proc) return NULL;
if (!ui->ready) return NULL;
Item_Cache *it = _item_cache_get(ui);
Item_Cache *it = evisum_ui_item_cache_item_get(ui->cache);
if (!it)
{
fprintf(stderr, "Error: Object cache creation failed.\n");
@ -1560,8 +1507,6 @@ evisum_icon_path_get(const char *name)
void
evisum_ui_shutdown(Ui *ui)
{
Item_Cache *it;
evas_object_del(ui->win);
if (ui->timer_pid)
@ -1581,16 +1526,10 @@ evisum_ui_shutdown(Ui *ui)
_proc_pid_cpu_times_free(ui);
EINA_LIST_FREE(ui->item_cache, it)
{
free(it);
}
if (ui->cpu_list)
eina_list_free(ui->cpu_list);
if (ui->item_cache)
eina_list_free(ui->item_cache);
evisum_ui_item_cache_free(ui->cache);
eina_lock_free(&_lock);
}
@ -1713,7 +1652,6 @@ _ui_init(Evas_Object *parent)
ui->mem_visible = ui->misc_visible = EINA_TRUE;
ui->cpu_times = NULL;
ui->cpu_list = NULL;
ui->item_cache = NULL;
_ui = NULL;
_evisum_config = NULL;
@ -1729,7 +1667,7 @@ _ui_init(Evas_Object *parent)
ui_tab_disk_add(ui);
ui_tab_misc_add(ui);
_item_cache_init(ui);
ui->cache = evisum_ui_item_cache_new(ui->genlist_procs, _item_create, 50);
return ui;
}

View File

@ -5,6 +5,7 @@
#include "gettext.h"
#include "system/process.h"
#include "../evisum_config.h"
#include "ui/ui_cache.h"
#define _(STR) gettext(STR)
@ -106,9 +107,9 @@ typedef struct Ui
Evas_Object *btn_state;
Evas_Object *btn_cpu_usage;
Eina_List *item_cache;
Evas_Object *genlist_procs;
Evas_Object *entry_search;
Evisum_Ui_Cache *cache;
Evas_Object *genlist_procs;
Evas_Object *entry_search;
Ecore_Thread *thread_system;
Ecore_Thread *thread_process;

87
src/bin/ui/ui_cache.c Normal file
View File

@ -0,0 +1,87 @@
#include "ui_cache.h"
Evisum_Ui_Cache *
evisum_ui_item_cache_new(Evas_Object *parent, Evas_Object *(create_cb)(Evas_Object *), int size)
{
Evisum_Ui_Cache *cache = malloc(sizeof(Evisum_Ui_Cache));
if (!cache) return NULL;
cache->parent = parent;
cache->item_create_cb = create_cb;
cache->items = NULL;
for (int i = 0; i < size; i++)
{
Item_Cache *it = calloc(1, sizeof(Item_Cache));
if (it)
{
it->obj = cache->item_create_cb(parent);
cache->items = eina_list_append(cache->items, it);
}
}
return cache;
}
Item_Cache *
evisum_ui_item_cache_item_get(Evisum_Ui_Cache *cache)
{
Eina_List *l;
Item_Cache *it;
EINA_LIST_FOREACH(cache->items, l, it)
{
if (it->used == 0)
{
it->used = 1;
return it;
}
}
it = calloc(1, sizeof(Item_Cache));
if (it)
{
it->obj = cache->item_create_cb(cache->parent);
it->used = 1;
cache->items = eina_list_append(cache->items, it);
}
return it;
}
Eina_Bool
evisum_ui_item_cache_item_release(Evisum_Ui_Cache *cache, Evas_Object *obj)
{
Item_Cache *it;
Eina_List *l;
Eina_Bool released = EINA_FALSE;
EINA_LIST_FOREACH(cache->items, l, it)
{
if (it->obj == obj)
{
it->used = 0;
released = EINA_TRUE;
break;
}
}
return released;
}
void
evisum_ui_item_cache_free(Evisum_Ui_Cache *cache)
{
Item_Cache *it;
evas_object_del(cache->parent);
EINA_LIST_FREE(cache->items, it)
{
free(it);
}
eina_list_free(cache->items);
free(cache);
}

31
src/bin/ui/ui_cache.h Normal file
View File

@ -0,0 +1,31 @@
#ifndef __UI_CACHE_H__
#define __UI_CACHE_H__
#include <Eina.h>
#include <Evas.h>
typedef struct _Evisum_Ui_Cache {
Eina_List *items;
Evas_Object *parent;
Evas_Object *(*item_create_cb)(Evas_Object *);
} Evisum_Ui_Cache;
typedef struct _Item_Cache {
Evas_Object *obj;
Eina_Bool used;
} Item_Cache;
Evisum_Ui_Cache *
evisum_ui_item_cache_new(Evas_Object *parent, Evas_Object *(create_cb)(Evas_Object *), int size);
Item_Cache *
evisum_ui_item_cache_item_get(Evisum_Ui_Cache *cache);
Eina_Bool
evisum_ui_item_cache_item_release(Evisum_Ui_Cache *cache, Evas_Object *obj);
void
evisum_ui_item_cache_free(Evisum_Ui_Cache *cache);
#endif

View File

@ -1,6 +1,29 @@
#include "ui_process_view.h"
#include "../system/process.h"
typedef struct {
int tid;
char *name;
char *state;
int cpu_id;
double cpu_usage;
} Thread_Info;
static Thread_Info *
_thread_info_new(Proc_Info *thr, double cpu_usage)
{
Thread_Info *t = calloc(1, sizeof(Thread_Info));
if (!t) return NULL;
t->tid = thr->tid;
t->name = strdup(thr->thread_name);
t->state = strdup(thr->state);
t->cpu_id = thr->cpu_id;
t->cpu_usage = cpu_usage;
return t;
}
Eina_List *
_exe_response(const char *command)
{
@ -24,65 +47,32 @@ _exe_response(const char *command)
return lines;
}
#define ITEM_CACHE_INIT_SIZE 25
typedef struct _Item_Cache {
Evas_Object *obj;
Eina_Bool used;
} Item_Cache;
static void
_item_unrealized_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Ui_Process *ui;
Item_Cache *it;
Evas_Object *o;
Eina_List *l, *contents = NULL;
Eina_List *contents = NULL;
ui = data;
elm_genlist_item_all_contents_unset(event_info, &contents);
EINA_LIST_FREE(contents, o)
{
EINA_LIST_FOREACH(ui->item_cache, l, it)
{
if (it->obj == o)
{
it->used = 0;
break;
}
}
evisum_ui_item_cache_item_release(ui->cache, o);
}
}
typedef struct {
int tid;
char *name;
char *state;
int cpu_id;
double cpu_usage;
} Thread_Info;
static Thread_Info *
_thread_info_new(Proc_Info *thr, double cpu_usage)
{
Thread_Info *t = calloc(1, sizeof(Thread_Info));
t->tid = thr->tid;
t->name = strdup(thr->thread_name);
t->state = strdup(thr->state);
t->cpu_id = thr->cpu_id;
t->cpu_usage = cpu_usage;
return t;
}
static void
_item_del(void *data, Evas_Object *obj EINA_UNUSED)
{
Thread_Info *t = data;
if (t->name) free(t->name);
if (t->state) free(t->state);
if (t->name)
free(t->name);
if (t->state)
free(t->state);
free(t);
}
@ -129,57 +119,6 @@ _item_create(Evas_Object *parent)
return table;
}
static void
_cache_free(Eina_List *cache)
{
Item_Cache *it;
EINA_LIST_FREE(cache, it)
{
free(it);
}
eina_list_free(cache);
}
static void
_cache_init(Ui_Process *ui)
{
for (int i = 0; i < ITEM_CACHE_INIT_SIZE; i++)
{
Item_Cache *it = calloc(1, sizeof(Item_Cache));
if (it)
{
it->obj = _item_create(ui->genlist_threads);
ui->item_cache = eina_list_append(ui->item_cache, it);
}
}
}
static Item_Cache *
_cache_get(Ui_Process *ui)
{
Eina_List *l;
Item_Cache *it;
EINA_LIST_FOREACH(ui->item_cache, l, it)
{
if (it->used == 0)
{
it->used = 1;
return it;
}
}
it = calloc(1, sizeof(Item_Cache));
if (it)
{
it->obj = _item_create(ui->genlist_threads);
it->used = 1;
ui->item_cache = eina_list_append(ui->item_cache, it);
}
return it;
}
static Evas_Object *
_content_get(void *data, Evas_Object *obj, const char *source)
{
@ -196,7 +135,7 @@ _content_get(void *data, Evas_Object *obj, const char *source)
if (!ui) return NULL;
if (!ui->threads_ready) return NULL;
Item_Cache *it = _cache_get(ui);
Item_Cache *it = evisum_ui_item_cache_item_get(ui->cache);
if (!it)
{
fprintf(stderr, "Error: Object cache creation failed.\n");
@ -382,9 +321,9 @@ _thread_info_set(Ui_Process *ui, Proc_Info *proc)
EINA_LIST_FOREACH(threads, l, t)
{
Thread_Info *prev = elm_object_item_data_get(it);
if (prev) _item_del(prev, NULL);
if (prev) _item_del(prev, NULL);
elm_object_item_data_set(it, t);
elm_genlist_item_update(it);
elm_genlist_item_update(it);
it = elm_genlist_item_next_get(it);
}
eina_list_free(threads);
@ -988,8 +927,8 @@ _win_del_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUS
ecore_timer_del(ui->timer_pid);
if (ui->selected_cmd)
free(ui->selected_cmd);
if (ui->item_cache)
_cache_free(ui->item_cache);
if (ui->cache)
evisum_ui_item_cache_free(ui->cache);
evas_object_del(win);
@ -1012,7 +951,7 @@ ui_process_win_add(int pid, const char *cmd)
ui->selected_pid = pid;
ui->selected_cmd = strdup(cmd);
ui->poll_delay = 3;
ui->item_cache = NULL;
ui->cache = NULL;
ui->sort_reverse = EINA_TRUE;
ui->sort_cb = _sort_by_cpu_usage;
@ -1050,7 +989,8 @@ ui_process_win_add(int pid, const char *cmd)
evas_object_resize(win, 540 * elm_config_scale_get(), 480 * elm_config_scale_get());
evas_object_show(win);
_cache_init(ui);
ui->cache = evisum_ui_item_cache_new(ui->genlist_threads, _item_create, 10);
_proc_info_update(ui);
}

View File

@ -2,6 +2,7 @@
#define __UI_PROCESS_H__
#include "ui.h"
#include "ui_cache.h"
typedef struct _Ui_Process {
Evas_Object *win;
@ -15,8 +16,9 @@ typedef struct _Ui_Process {
Evas_Object *btn_info;
Evas_Object *btn_thread;
Evas_Object *entry_info;
Evas_Object *genlist_threads;
Evas_Object *entry_info;
Evas_Object *genlist_threads;
Evisum_Ui_Cache *cache;
Evas_Object *entry_pid_cmd;
Evas_Object *entry_pid_cmd_args;
@ -42,8 +44,6 @@ typedef struct _Ui_Process {
Eina_Hash *hash_cpu_times;
Eina_List *item_cache;
int poll_delay;
char *selected_cmd;
int selected_pid;