Rework generic item container

Instead of copying all members of the individual item structures to a
generic structure containing all fields, create compulsory fields only
and set up a pointer to the actual item. This results in lower memory
footprint and lets us clean up some code.

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
Lukas Fleischer 2012-06-25 11:51:59 +02:00
parent cbc5d46880
commit 52bfc54333
3 changed files with 134 additions and 90 deletions

View File

@ -308,18 +308,6 @@ struct day_items_nb {
unsigned nb_apoints; unsigned nb_apoints;
}; };
/* Generic item description (to hold appointments, events...). */
struct day_item {
long start; /* seconds since 1 jan 1970 */
long appt_dur; /* appointment duration in seconds */
int type; /* (recursive or normal) event or appointment */
int evnt_id; /* event identifier */
int appt_pos; /* real position in recurrent list */
char state; /* appointment state */
char *mesg; /* item description */
char *note; /* note attached to item */
};
struct excp { struct excp {
long st; /* beggining of the considered day, in seconds */ long st; /* beggining of the considered day, in seconds */
}; };
@ -361,6 +349,22 @@ struct recur_event {
char *note; /* note attached to event */ char *note; /* note attached to event */
}; };
/* Generic pointer data type for appointments and events. */
union aptev_ptr {
struct apoint *apt;
struct event *ev;
struct recur_apoint *rapt;
struct recur_event *rev;
};
/* Generic item description (to hold appointments, events...). */
struct day_item {
int type; /* (recursive or normal) event or appointment */
long start; /* start time of the repetition occurrence */
union aptev_ptr item; /* pointer to the actual item */
int appt_pos; /* real position in recurrent list */
};
/* Available view for the calendar panel. */ /* Available view for the calendar panel. */
enum { enum {
CAL_MONTH_VIEW, CAL_MONTH_VIEW,

186
src/day.c
View File

@ -74,26 +74,6 @@ void day_free_list(void)
LLIST_FREE(&day_items); LLIST_FREE(&day_items);
} }
/* Add an event in the current day list */
static struct day_item *day_add_event(int type, char *mesg, char *note,
long nday, int id)
{
struct day_item *day;
day = mem_malloc(sizeof(struct day_item));
day->mesg = mesg;
day->note = note;
day->type = type;
day->appt_dur = 0;
day->appt_pos = 0;
day->start = nday;
day->evnt_id = id;
LLIST_ADD(&day_items, day);
return day;
}
static int day_cmp_start(struct day_item *a, struct day_item *b) static int day_cmp_start(struct day_item *a, struct day_item *b)
{ {
if (a->type <= EVNT) { if (a->type <= EVNT) {
@ -107,26 +87,77 @@ static int day_cmp_start(struct day_item *a, struct day_item *b)
return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1); return a->start < b->start ? -1 : (a->start == b->start ? 0 : 1);
} }
/* Add an appointment in the current day list. */ /* Add an item to the current day list. */
static struct day_item *day_add_apoint(int type, char *mesg, char *note, static void day_add_item(int type, long start, union aptev_ptr item,
long start, long dur, char state, int appt_pos)
int real_pos)
{ {
struct day_item *day; struct day_item *day = mem_malloc(sizeof(struct day_item));
day = mem_malloc(sizeof(struct day_item));
day->mesg = mesg;
day->note = note;
day->start = start;
day->appt_dur = dur;
day->appt_pos = real_pos;
day->state = state;
day->type = type; day->type = type;
day->evnt_id = 0; day->start = start;
day->item = item;
day->appt_pos = appt_pos;
LLIST_ADD_SORTED(&day_items, day, day_cmp_start); LLIST_ADD_SORTED(&day_items, day, day_cmp_start);
}
return day; /* Get the message of an item. */
static char *day_item_get_mesg(struct day_item *day)
{
switch (day->type) {
case APPT:
return day->item.apt->mesg;
case EVNT:
return day->item.ev->mesg;
case RECUR_APPT:
return day->item.rapt->mesg;
case RECUR_EVNT:
return day->item.rev->mesg;
default:
return NULL;
}
}
/* Get the note attached to an item. */
static char *day_item_get_note(struct day_item *day)
{
switch (day->type) {
case APPT:
return day->item.apt->note;
case EVNT:
return day->item.ev->note;
case RECUR_APPT:
return day->item.rapt->note;
case RECUR_EVNT:
return day->item.rev->note;
default:
return NULL;
}
}
/* Get the duration of an item. */
static long day_item_get_duration(struct day_item *day)
{
switch (day->type) {
case APPT:
return day->item.apt->dur;
case RECUR_APPT:
return day->item.rapt->dur;
default:
return 0;
}
}
/* Get the notification state of an item. */
static int day_item_get_state(struct day_item *day)
{
switch (day->type) {
case APPT:
return day->item.apt->state;
case RECUR_APPT:
return day->item.rapt->state;
default:
return APOINT_NULL;
}
} }
/* /*
@ -139,11 +170,13 @@ static struct day_item *day_add_apoint(int type, char *mesg, char *note,
static int day_store_events(long date) static int day_store_events(long date)
{ {
llist_item_t *i; llist_item_t *i;
union aptev_ptr p;
int e_nb = 0; int e_nb = 0;
LLIST_FIND_FOREACH_CONT(&eventlist, date, event_inday, i) { LLIST_FIND_FOREACH_CONT(&eventlist, date, event_inday, i) {
struct event *ev = LLIST_TS_GET_DATA(i); struct event *ev = LLIST_TS_GET_DATA(i);
day_add_event(EVNT, ev->mesg, ev->note, ev->day, ev->id); p.ev = ev;
day_add_item(EVNT, ev->day, p, 0);
e_nb++; e_nb++;
} }
@ -160,11 +193,13 @@ static int day_store_events(long date)
static int day_store_recur_events(long date) static int day_store_recur_events(long date)
{ {
llist_item_t *i; llist_item_t *i;
union aptev_ptr p;
int e_nb = 0; int e_nb = 0;
LLIST_FIND_FOREACH(&recur_elist, date, recur_event_inday, i) { LLIST_FIND_FOREACH(&recur_elist, date, recur_event_inday, i) {
struct recur_event *rev = LLIST_TS_GET_DATA(i); struct recur_event *rev = LLIST_TS_GET_DATA(i);
day_add_event(RECUR_EVNT, rev->mesg, rev->note, rev->day, rev->id); p.rev = rev;
day_add_item(RECUR_EVNT, rev->day, p, 0);
e_nb++; e_nb++;
} }
@ -181,17 +216,18 @@ static int day_store_recur_events(long date)
static int day_store_apoints(long date) static int day_store_apoints(long date)
{ {
llist_item_t *i; llist_item_t *i;
union aptev_ptr p;
int a_nb = 0; int a_nb = 0;
LLIST_TS_LOCK(&alist_p); LLIST_TS_LOCK(&alist_p);
LLIST_TS_FIND_FOREACH(&alist_p, date, apoint_inday, i) { LLIST_TS_FIND_FOREACH(&alist_p, date, apoint_inday, i) {
struct apoint *apt = LLIST_TS_GET_DATA(i); struct apoint *apt = LLIST_TS_GET_DATA(i);
p.apt = apt;
if (apt->start >= date + DAYINSEC) if (apt->start >= date + DAYINSEC)
break; break;
day_add_apoint(APPT, apt->mesg, apt->note, apt->start, apt->dur, day_add_item(APPT, apt->start, p, 0);
apt->state, 0);
a_nb++; a_nb++;
} }
LLIST_TS_UNLOCK(&alist_p); LLIST_TS_UNLOCK(&alist_p);
@ -209,15 +245,17 @@ static int day_store_apoints(long date)
static int day_store_recur_apoints(long date) static int day_store_recur_apoints(long date)
{ {
llist_item_t *i; llist_item_t *i;
union aptev_ptr p;
int a_nb = 0; int a_nb = 0;
LLIST_TS_LOCK(&recur_alist_p); LLIST_TS_LOCK(&recur_alist_p);
LLIST_TS_FIND_FOREACH(&recur_alist_p, date, recur_apoint_inday, i) { LLIST_TS_FIND_FOREACH(&recur_alist_p, date, recur_apoint_inday, i) {
struct recur_apoint *rapt = LLIST_TS_GET_DATA(i); struct recur_apoint *rapt = LLIST_TS_GET_DATA(i);
p.rapt = rapt;
unsigned real_start; unsigned real_start;
if (recur_apoint_find_occurrence(rapt, date, &real_start)) { if (recur_apoint_find_occurrence(rapt, date, &real_start)) {
day_add_apoint(RECUR_APPT, rapt->mesg, rapt->note, real_start, day_add_item(RECUR_APPT, real_start, p, a_nb);
rapt->dur, rapt->state, a_nb);
a_nb++; a_nb++;
} }
} }
@ -291,38 +329,32 @@ struct day_items_nb *day_process_storage(struct date *slctd_date,
return inday; return inday;
} }
/*
* Returns a structure of type apoint_llist_node_t given a structure of type
* day_item_s
*/
static void day_item_s2apoint_s(struct apoint *a, struct day_item *p)
{
a->state = p->state;
a->start = p->start;
a->dur = p->appt_dur;
a->mesg = p->mesg;
}
/* /*
* Print an item date in the appointment panel. * Print an item date in the appointment panel.
*/ */
static void static void
display_item_date(int incolor, struct apoint *i, int type, long date, display_item_date(int incolor, long start, long dur, int state, int type,
int y, int x) long date, int y, int x)
{ {
WINDOW *win; WINDOW *win;
char a_st[100], a_end[100]; char a_st[100], a_end[100];
/* FIXME: Redesign apoint_sec2str() and remove the need for a temporary
* appointment item here. */
struct apoint apt_tmp;
apt_tmp.start = start;
apt_tmp.dur = dur;
win = apad.ptrwin; win = apad.ptrwin;
apoint_sec2str(i, date, a_st, a_end); apoint_sec2str(&apt_tmp, date, a_st, a_end);
if (incolor == 0) if (incolor == 0)
custom_apply_attr(win, ATTR_HIGHEST); custom_apply_attr(win, ATTR_HIGHEST);
if (type == RECUR_EVNT || type == RECUR_APPT) if (type == RECUR_EVNT || type == RECUR_APPT)
if (i->state & APOINT_NOTIFY) if (state & APOINT_NOTIFY)
mvwprintw(win, y, x, " *!%s -> %s", a_st, a_end); mvwprintw(win, y, x, " *!%s -> %s", a_st, a_end);
else else
mvwprintw(win, y, x, " * %s -> %s", a_st, a_end); mvwprintw(win, y, x, " * %s -> %s", a_st, a_end);
else if (i->state & APOINT_NOTIFY) else if (state & APOINT_NOTIFY)
mvwprintw(win, y, x, " -!%s -> %s", a_st, a_end); mvwprintw(win, y, x, " -!%s -> %s", a_st, a_end);
else else
mvwprintw(win, y, x, " - %s -> %s", a_st, a_end); mvwprintw(win, y, x, " - %s -> %s", a_st, a_end);
@ -387,19 +419,23 @@ void day_write_pad(long date, int width, int length, int incolor)
LLIST_FOREACH(&day_items, i) { LLIST_FOREACH(&day_items, i) {
struct day_item *day = LLIST_TS_GET_DATA(i); struct day_item *day = LLIST_TS_GET_DATA(i);
char *mesg = day_item_get_mesg(day);
char *note = day_item_get_note(day);
if (day->type == RECUR_EVNT || day->type == RECUR_APPT) if (day->type == RECUR_EVNT || day->type == RECUR_APPT)
recur = 1; recur = 1;
else else
recur = 0; recur = 0;
/* First print the events for current day. */ /* First print the events for current day. */
if (day->type < RECUR_APPT) { if (day->type < RECUR_APPT) {
item_number++; item_number++;
if (item_number - incolor == 0) { if (item_number - incolor == 0) {
day_saved_item.type = day->type; day_saved_item.type = day->type;
day_saved_item.mesg = day->mesg; day_saved_item.mesg = mesg;
} }
display_item(item_number - incolor, day->mesg, recur, display_item(item_number - incolor, mesg, recur, (note != NULL) ? 1 : 0,
(day->note != NULL) ? 1 : 0, width - 7, line, x_pos); width - 7, line, x_pos);
line++; line++;
draw_line = 1; draw_line = 1;
} else { } else {
@ -411,16 +447,16 @@ void day_write_pad(long date, int width, int length, int incolor)
} }
/* Last print the appointments for current day. */ /* Last print the appointments for current day. */
item_number++; item_number++;
day_item_s2apoint_s(&a, day);
if (item_number - incolor == 0) { if (item_number - incolor == 0) {
day_saved_item.type = day->type; day_saved_item.type = day->type;
day_saved_item.mesg = day->mesg; day_saved_item.mesg = mesg;
apoint_sec2str(&a, date, day_saved_item.start, day_saved_item.end); apoint_sec2str(&a, date, day_saved_item.start, day_saved_item.end);
} }
display_item_date(item_number - incolor, &a, day->type, display_item_date(item_number - incolor, day->start,
date, line + 1, x_pos); day_item_get_duration(day), day_item_get_state(day),
display_item(item_number - incolor, day->mesg, 0, day->type, date, line + 1, x_pos);
(day->note != NULL) ? 1 : 0, width - 7, line + 2, x_pos); display_item(item_number - incolor, mesg, 0, (note != NULL) ? 1 : 0,
width - 7, line + 2, x_pos);
line += 3; line += 3;
} }
} }
@ -888,7 +924,7 @@ int day_erase_item(long date, int item_number, enum eraseflg flag)
p = day_get_item(item_number); p = day_get_item(item_number);
if (flag == ERASE_DONT_FORCE) { if (flag == ERASE_DONT_FORCE) {
if (p->note == NULL) if (day_item_get_note(p) == NULL)
ans = 1; ans = 1;
else else
ans = status_ask_choice(note_warning, note_choices, nb_note_choices); ans = status_ask_choice(note_warning, note_choices, nb_note_choices);
@ -1025,6 +1061,7 @@ int day_item_nb(long date, int day_num, int type)
void day_edit_note(const char *editor) void day_edit_note(const char *editor)
{ {
struct day_item *p; struct day_item *p;
char *note;
struct recur_apoint *ra; struct recur_apoint *ra;
struct apoint *a; struct apoint *a;
struct recur_event *re; struct recur_event *re;
@ -1034,25 +1071,26 @@ void day_edit_note(const char *editor)
item_num = apoint_hilt(); item_num = apoint_hilt();
p = day_get_item(item_num); p = day_get_item(item_num);
edit_note(&p->note, editor); note = day_item_get_note(p);
edit_note(&note, editor);
date = calendar_get_slctd_day_sec(); date = calendar_get_slctd_day_sec();
switch (p->type) { switch (p->type) {
case RECUR_EVNT: case RECUR_EVNT:
re = recur_get_event(date, day_item_nb(date, item_num, RECUR_EVNT)); re = recur_get_event(date, day_item_nb(date, item_num, RECUR_EVNT));
re->note = p->note; re->note = note;
break; break;
case EVNT: case EVNT:
e = event_get(date, day_item_nb(date, item_num, EVNT)); e = event_get(date, day_item_nb(date, item_num, EVNT));
e->note = p->note; e->note = note;
break; break;
case RECUR_APPT: case RECUR_APPT:
ra = recur_get_apoint(date, day_item_nb(date, item_num, RECUR_APPT)); ra = recur_get_apoint(date, day_item_nb(date, item_num, RECUR_APPT));
ra->note = p->note; ra->note = note;
break; break;
case APPT: case APPT:
a = apoint_get(date, day_item_nb(date, item_num, APPT)); a = apoint_get(date, day_item_nb(date, item_num, APPT));
a->note = p->note; a->note = note;
break; break;
} }
} }
@ -1061,7 +1099,7 @@ void day_edit_note(const char *editor)
void day_view_note(const char *pager) void day_view_note(const char *pager)
{ {
struct day_item *p = day_get_item(apoint_hilt()); struct day_item *p = day_get_item(apoint_hilt());
view_note(p->note, pager); view_note(day_item_get_note(p), pager);
} }
/* Pipe an appointment or event to an external program. */ /* Pipe an appointment or event to an external program. */

View File

@ -902,11 +902,13 @@ void recur_repeat_item(void)
date = calendar_get_slctd_day_sec(); date = calendar_get_slctd_day_sec();
if (p->type == EVNT) { if (p->type == EVNT) {
recur_event_new(p->mesg, p->note, p->start, p->evnt_id, type, freq, struct event *ev = p->item.ev;
until, NULL); recur_event_new(ev->mesg, ev->note, ev->day, ev->id, type, freq, until,
NULL);
} else if (p->type == APPT) { } else if (p->type == APPT) {
ra = recur_apoint_new(p->mesg, p->note, p->start, p->appt_dur, struct apoint *apt = p->item.apt;
p->state, type, freq, until, NULL); ra = recur_apoint_new(apt->mesg, apt->note, apt->start, apt->dur,
apt->state, type, freq, until, NULL);
if (notify_bar()) if (notify_bar())
notify_check_repeated(ra); notify_check_repeated(ra);
} else { } else {