Commit 1f108ba5 authored by Arturo Espinosa's avatar Arturo Espinosa

Ok, finally got recalculation working as it is supposed to work.



Ok, finally got recalculation working as it is supposed to work.

This piece of code is so clean that it was actually a clean fix :-)
parent dfb8a858
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
is a char. Everytime we are about to overflow the char, we walk
the list of formulas and reset the generation flag.
1998-08-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): Queue computation for cells that
......
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
is a char. Everytime we are about to overflow the char, we walk
the list of formulas and reset the generation flag.
1998-08-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): Queue computation for cells that
......
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
is a char. Everytime we are about to overflow the char, we walk
the list of formulas and reset the generation flag.
1998-08-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): Queue computation for cells that
......
1998-08-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): New recomputation strategy: We
now keep a generation flag for determining whenever a cell value
has been recomputed for this generation. The generation variable
is a char. Everytime we are about to overflow the char, we walk
the list of formulas and reset the generation flag.
1998-08-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* src/eval.c (workbook_recalc): Queue computation for cells that
......
......@@ -48,12 +48,11 @@ typedef struct {
int height; /* Height of text */
int flags;
int iteration;
char generation;
} Cell;
#define CELL_TEXT_GET(cell) ((cell)->text ? cell->text->str : cell->entered_text->str)
#define CELL_IS_FORMULA(cell) (cell->entered_text->str [0] == '=')
#define MAX_ITERATIONS(cell) 1
void cell_set_text (Cell *cell, char *text);
void cell_set_formula (Cell *cell, char *text);
......
......@@ -23,11 +23,6 @@ cell_eval (Cell *cell)
g_return_if_fail (cell != NULL);
if (cell->iteration == MAX_ITERATIONS(cell))
return;
cell->iteration++;
if (cell->text)
string_unref (cell->text);
......@@ -56,7 +51,6 @@ cell_eval (Cell *cell)
sheet_redraw_cell_region (cell->sheet,
cell->col->pos, cell->row->pos,
cell->col->pos, cell->row->pos);
cell->iteration--;
}
/*
......@@ -322,7 +316,6 @@ search_cell_deps (gpointer key, gpointer value, gpointer closure)
for (l = range->cell_list; l; l = l->next){
Cell *cell = l->data;
printf ("Found dependenat: %d, %d\n", cell->col->pos, cell->row->pos);
c->list = g_list_prepend (c->list, cell);
}
}
......@@ -384,16 +377,48 @@ pick_next_cell_from_queue (Workbook *wb)
return cell;
}
/*
* Increments the generation. Every time the generation is
* about to wrap around, we reset all of the cell counters to zero
*/
void
workbook_next_generation (Workbook *wb)
{
if (wb->generation == 255){
GList *cell_list = wb->formula_cell_list;
for (; cell_list; cell_list = cell_list->next){
Cell *cell = cell_list->data;
cell->generation = 0;
}
wb->generation = 1;
} else
wb->generation++;
}
void
workbook_recalc (Workbook *wb)
{
int generation;
Cell *cell;
GList *deps;
GList *deps, *l;
workbook_next_generation (wb);
generation = wb->generation;
while ((cell = pick_next_cell_from_queue (wb))){
cell->generation = generation;
cell_eval (cell);
deps = cell_get_dependencies (cell->sheet, cell->col->pos, cell->row->pos);
if (deps)
cell_queue_recalc_list (deps);
for (l = deps ; l; l = l->next){
Cell *one_cell;
one_cell = l->data;
if (one_cell->generation != generation)
cell_queue_recalc (one_cell);
}
g_list_free (deps);
}
}
......@@ -23,11 +23,6 @@ cell_eval (Cell *cell)
g_return_if_fail (cell != NULL);
if (cell->iteration == MAX_ITERATIONS(cell))
return;
cell->iteration++;
if (cell->text)
string_unref (cell->text);
......@@ -56,7 +51,6 @@ cell_eval (Cell *cell)
sheet_redraw_cell_region (cell->sheet,
cell->col->pos, cell->row->pos,
cell->col->pos, cell->row->pos);
cell->iteration--;
}
/*
......@@ -322,7 +316,6 @@ search_cell_deps (gpointer key, gpointer value, gpointer closure)
for (l = range->cell_list; l; l = l->next){
Cell *cell = l->data;
printf ("Found dependenat: %d, %d\n", cell->col->pos, cell->row->pos);
c->list = g_list_prepend (c->list, cell);
}
}
......@@ -384,16 +377,48 @@ pick_next_cell_from_queue (Workbook *wb)
return cell;
}
/*
* Increments the generation. Every time the generation is
* about to wrap around, we reset all of the cell counters to zero
*/
void
workbook_next_generation (Workbook *wb)
{
if (wb->generation == 255){
GList *cell_list = wb->formula_cell_list;
for (; cell_list; cell_list = cell_list->next){
Cell *cell = cell_list->data;
cell->generation = 0;
}
wb->generation = 1;
} else
wb->generation++;
}
void
workbook_recalc (Workbook *wb)
{
int generation;
Cell *cell;
GList *deps;
GList *deps, *l;
workbook_next_generation (wb);
generation = wb->generation;
while ((cell = pick_next_cell_from_queue (wb))){
cell->generation = generation;
cell_eval (cell);
deps = cell_get_dependencies (cell->sheet, cell->col->pos, cell->row->pos);
if (deps)
cell_queue_recalc_list (deps);
for (l = deps ; l; l = l->next){
Cell *one_cell;
one_cell = l->data;
if (one_cell->generation != generation)
cell_queue_recalc (one_cell);
}
g_list_free (deps);
}
}
......@@ -240,7 +240,7 @@ static Value *
eval_cell_value (Sheet *sheet, Value *value)
{
Value *res;
res = g_new (Value, 1);
res->type = value->type;
......@@ -251,13 +251,11 @@ eval_cell_value (Sheet *sheet, Value *value)
break;
case VALUE_INTEGER:
mpz_init (res->v.v_int);
mpz_set (res->v.v_int, value->v.v_int);
res->v.v_int = value->v.v_int;
break;
case VALUE_FLOAT:
mpf_init (res->v.v_float);
mpf_set (res->v.v_float, value->v.v_float);
res->v.v_float = value->v.v_float;
break;
case VALUE_ARRAY:
......@@ -646,15 +644,20 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro
cell_get_abs_col_row (&tree->u.constant->v.cell, eval_col, eval_row, &col, &row);
cell = sheet_cell_get (sheet, col, row);
if (!cell || !cell->value){
res = g_new (Value, 1);
if (cell && cell->value){
if (cell->parsed_node && cell->generation != sheet->workbook->generation){
cell->generation = sheet->workbook->generation;
cell_eval (cell);
}
res->type = VALUE_INTEGER;
res->v.v_int = 0;
} else {
return eval_cell_value (sheet, cell->value);
if (cell->value)
return eval_cell_value (sheet, cell->value);
}
res = g_new (Value, 1);
res->type = VALUE_INTEGER;
res->v.v_int = 0;
return res;
}
case OP_NEG:
......@@ -668,6 +671,7 @@ eval_expr (void *asheet, ExprTree *tree, int eval_col, int eval_row, char **erro
return NULL;
}
res = g_new (Value, 1);
res->type = a->type;
if (a->type == VALUE_INTEGER){
res->v.v_int = -a->v.v_int;
} else {
......
......@@ -33,6 +33,7 @@ typedef struct {
/* A queue with the cells to be evaluated */
GList *eval_queue;
int max_iterations;
guchar generation;
} Workbook;
typedef struct {
......@@ -168,6 +169,7 @@ void workbook_attach_sheet (Workbook *, Sheet *);
Sheet *workbook_focus_current_sheet (Workbook *wb);
Sheet *workbook_get_current_sheet (Workbook *wb);
void workbook_auto_expr_label_set (Workbook *wb, char *text);
void workbook_next_generation (Workbook *wb);
/*
* Does any pending recalculations
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment