dependent.h 5.34 KB
Newer Older
1 2 3
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
#ifndef _GNM_DEPENDENT_H_
# define _GNM_DEPENDENT_H_
Arturo Espinosa's avatar
Arturo Espinosa committed
4

5
#include "gnumeric.h"
6
#include <goffice/goffice.h>
7

8 9
G_BEGIN_DECLS

10
struct _GnmDependent {
Jody Goldberg's avatar
Jody Goldberg committed
11 12
	guint	  flags;
	Sheet	 *sheet;
13
	GnmExprTop const *texpr;
14 15

	/* Double-linked list.  */
Morten Welinder's avatar
Morten Welinder committed
16
	GnmDependent *next_dep, *prev_dep;
Jody Goldberg's avatar
Jody Goldberg committed
17 18 19
};

typedef struct {
20 21
	void (*eval)	   (GnmDependent *dep);
	void (*set_expr)   (GnmDependent *dep, GnmExprTop const *new_texpr);
22
	GSList* (*changed) (GnmDependent *dep);
23
	GnmCellPos* (*pos) (GnmDependent const *dep);
24
	void (*debug_name) (GnmDependent const *dep, GString *target);
25
} GnmDependentClass;
Jody Goldberg's avatar
Jody Goldberg committed
26 27

typedef enum {
28 29 30
	DEPENDENT_NO_FLAG	   = 0,

	/* Types */
31
	DEPENDENT_CELL		   = 0x00000001,	/* builtin type */
Jody Goldberg's avatar
Jody Goldberg committed
32
	DEPENDENT_DYNAMIC_DEP	   = 0x00000002,	/* builtin type */
33
	DEPENDENT_NAME		   = 0x00000003,	/* builtin pseudo type */
34
	DEPENDENT_MANAGED	   = 0x00000004,	/* builtin type */
35
	DEPENDENT_STYLE		   = 0x00000005,	/* builtin type */
36 37
	DEPENDENT_TYPE_MASK	   = 0x00000fff,

Jody Goldberg's avatar
Jody Goldberg committed
38
	/* Linked into the workbook wide expression list */
Jody Goldberg's avatar
Jody Goldberg committed
39
	DEPENDENT_IS_LINKED	   = 0x00001000,
Jody Goldberg's avatar
Jody Goldberg committed
40
	DEPENDENT_NEEDS_RECALC	   = 0x00002000,
41
	DEPENDENT_BEING_CALCULATED = 0x00004000,
42
	/* GnmDependent is in the midst of a cyclic calculation */
43 44 45 46
	DEPENDENT_BEING_ITERATED   = 0x00008000,

	DEPENDENT_GOES_INTERSHEET  = 0x00010000,
	DEPENDENT_GOES_INTERBOOK   = 0x00020000,
47 48 49
	DEPENDENT_USES_NAME	   = 0x00040000,
	DEPENDENT_HAS_3D	   = 0x00080000,
	DEPENDENT_HAS_DYNAMIC_DEPS = 0x00200000,
50 51
	DEPENDENT_IGNORE_ARGS	   = 0x00400000,
	DEPENDENT_LINK_FLAGS	   = 0x007ff000,
52 53

	/* An internal utility flag */
Jody Goldberg's avatar
Jody Goldberg committed
54 55
	DEPENDENT_FLAGGED	   = 0x01000000,
	DEPENDENT_CAN_RELOCATE	   = 0x02000000
Morten Welinder's avatar
Morten Welinder committed
56
} GnmDependentFlags;
Jody Goldberg's avatar
Jody Goldberg committed
57

58 59
#define dependent_type(dep)		((dep)->flags & DEPENDENT_TYPE_MASK)
#define dependent_is_cell(dep)		(dependent_type (dep) == DEPENDENT_CELL)
Jody Goldberg's avatar
Jody Goldberg committed
60
#define dependent_needs_recalc(dep)	((dep)->flags & DEPENDENT_NEEDS_RECALC)
Jody Goldberg's avatar
Jody Goldberg committed
61
#define dependent_is_linked(dep)	((dep)->flags & DEPENDENT_IS_LINKED)
62

63
struct _GnmDepContainer {
64
	GnmDependent *head, *tail;
65

66
	/* Large ranges hashed on 'range' to accelerate duplicate culling. This
67
	 * is traversed by g_hash_table_foreach mostly.
68
	 */
69
	int buckets;
70
	GHashTable **range_hash;
71
	GOMemChunk *range_pool;
72

Morten Welinder's avatar
Morten Welinder committed
73
	/* Single ranges, this maps an GnmEvalPos * to a GSList of its
74 75 76
	 * dependencies.
	 */
	GHashTable *single_hash;
77
	GOMemChunk *single_pool;
78

Jody Goldberg's avatar
Jody Goldberg committed
79 80 81 82 83
	/* All of the ExprNames that refer to this container */
	GHashTable *referencing_names;

	/* Dynamic Deps */
	GHashTable *dynamic_deps;
84
};
85

Morten Welinder's avatar
Morten Welinder committed
86
typedef void (*GnmDepFunc) (GnmDependent *dep, gpointer user);
Jody Goldberg's avatar
Jody Goldberg committed
87

88
guint32	 dependent_type_register   (GnmDependentClass const *klass);
Jody Goldberg's avatar
Jody Goldberg committed
89 90
void	 dependent_types_init	   (void);
void	 dependent_types_shutdown  (void);
91

92
void	 dependent_set_expr	   (GnmDependent *dep, GnmExprTop const *new_texpr);
93
void	 dependent_set_sheet	   (GnmDependent *dep, Sheet *sheet);
94 95
void	 dependent_link		   (GnmDependent *dep);
void	 dependent_unlink	   (GnmDependent *dep);
96
void	 dependent_queue_recalc	   (GnmDependent *dep);
97
void	 dependent_add_dynamic_dep (GnmDependent *dep, GnmRangeRef const *rr);
98

99 100
gboolean dependent_is_volatile     (GnmDependent *dep);

101
gboolean dependent_has_pos (GnmDependent const *dep);
Morten Welinder's avatar
Morten Welinder committed
102
GnmCellPos const *dependent_pos (GnmDependent const *dep);
103
void dependent_move (GnmDependent *dep, int dx, int dy);
Morten Welinder's avatar
Morten Welinder committed
104

Morten Welinder's avatar
Morten Welinder committed
105
GOUndo  *dependents_relocate	    (GnmExprRelocateInfo const *info);
106
void	 dependents_link	    (GSList *deps);
Jody Goldberg's avatar
Jody Goldberg committed
107

Morten Welinder's avatar
Morten Welinder committed
108
void	 gnm_cell_eval		    (GnmCell *cell);
Morten Welinder's avatar
Morten Welinder committed
109
void	 cell_queue_recalc	    (GnmCell *cell);
Morten Welinder's avatar
Morten Welinder committed
110
void	 cell_foreach_dep	    (GnmCell const *cell, GnmDepFunc func, gpointer user);
111

112
void sheet_region_queue_recalc	  (Sheet const *sheet, GnmRange const *range);
113
void dependents_invalidate_sheet  (Sheet *sheet, gboolean destroy);
114
void dependents_workbook_destroy  (Workbook *wb);
115
void dependents_revive_sheet      (Sheet *sheet);
116
void workbook_queue_all_recalc	  (Workbook *wb);
117
void workbook_queue_volatile_recalc (Workbook *wb);
Jody Goldberg's avatar
Jody Goldberg committed
118

119 120 121 122
void gnm_dep_style_dependency (Sheet *sheet,
			       GnmExprTop const *texpr,
			       GnmRange const *r,
			       GPtrArray *accum);
123

124
GnmDepContainer *gnm_dep_container_new  (Sheet *sheet);
125 126
void		 gnm_dep_container_dump	(GnmDepContainer const *deps,
					 Sheet *sheet);
127
void dependents_dump (Workbook *wb);
128
void             gnm_dep_container_sanity_check (GnmDepContainer const *deps);
129
void             gnm_dep_container_resize (GnmDepContainer *deps, int rows);
Arturo Espinosa's avatar
Arturo Espinosa committed
130

Morten Welinder's avatar
Morten Welinder committed
131 132
void dependent_managed_init (GnmDependent *dep, Sheet *sheet);
void dependent_managed_set_expr (GnmDependent *dep, GnmExprTop const *texpr);
133
void dependent_managed_set_sheet (GnmDependent *dep, Sheet *sheet);
134

135 136
#define DEPENDENT_CONTAINER_FOREACH_DEPENDENT(dc, dep, code)	\
  do {								\
137
	GnmDependent *dep = (dc)->head;				\
138
	while (dep) {						\
139
		GnmDependent *_next = dep->next_dep;		\
140 141 142 143 144
		code;						\
		dep = _next;					\
	}							\
  } while (0)

145 146 147 148 149 150
#define DEPENDENT_MAKE_TYPE(t, set_expr_handler)		\
guint								\
t ## _get_dep_type (void)					\
{								\
	static guint32 type = 0;				\
	if (type == 0) {					\
151
		static GnmDependentClass klass;			\
152 153
		klass.eval	 = &t ## _eval;			\
		klass.set_expr	 = set_expr_handler;		\
154 155
		klass.changed	 = NULL;			\
		klass.pos	 = NULL;			\
156 157 158 159 160 161
		klass.debug_name = &t ## _debug_name;		\
		type = dependent_type_register (&klass);	\
	}							\
	return type;						\
}

162
void dependent_debug_name (GnmDependent const *dep, GString *target);
163

164 165 166
G_END_DECLS

#endif /* _GNM_DEPENDENT_H_ */