1 #ifndef _GNM_DEPENDENT_H_ 2 # define _GNM_DEPENDENT_H_ 3 4 #include <gnumeric.h> 5 #include <goffice/goffice.h> 6 7 G_BEGIN_DECLS 8 9 struct _GnmDependent { 10 guint flags; 11 Sheet *sheet; 12 GnmExprTop const *texpr; 13 14 /* Double-linked list. */ 15 GnmDependent *next_dep, *prev_dep; 16 }; 17 18 typedef struct { 19 void (*eval) (GnmDependent *dep); 20 void (*set_expr) (GnmDependent *dep, GnmExprTop const *new_texpr); 21 GSList* (*changed) (GnmDependent *dep); 22 GnmCellPos* (*pos) (GnmDependent const *dep); 23 void (*debug_name) (GnmDependent const *dep, GString *target); 24 } GnmDependentClass; 25 26 typedef enum { 27 DEPENDENT_NO_FLAG = 0, 28 29 /* Types */ 30 DEPENDENT_CELL = 0x00000001, /* builtin type */ 31 DEPENDENT_DYNAMIC_DEP = 0x00000002, /* builtin type */ 32 DEPENDENT_NAME = 0x00000003, /* builtin pseudo type */ 33 DEPENDENT_MANAGED = 0x00000004, /* builtin type */ 34 DEPENDENT_TYPE_MASK = 0x00000fff, 35 36 /* Linked into the workbook wide expression list */ 37 DEPENDENT_IS_LINKED = 0x00001000, 38 DEPENDENT_NEEDS_RECALC = 0x00002000, 39 DEPENDENT_BEING_CALCULATED = 0x00004000, 40 /* GnmDependent is in the midst of a cyclic calculation */ 41 DEPENDENT_BEING_ITERATED = 0x00008000, 42 43 DEPENDENT_GOES_INTERSHEET = 0x00010000, 44 DEPENDENT_GOES_INTERBOOK = 0x00020000, 45 DEPENDENT_USES_NAME = 0x00040000, 46 DEPENDENT_HAS_3D = 0x00080000, 47 DEPENDENT_HAS_DYNAMIC_DEPS = 0x00200000, 48 DEPENDENT_IGNORE_ARGS = 0x00400000, 49 DEPENDENT_LINK_FLAGS = 0x007ff000, 50 51 /* An internal utility flag */ 52 DEPENDENT_FLAGGED = 0x01000000, 53 DEPENDENT_CAN_RELOCATE = 0x02000000 54 } GnmDependentFlags; 55 56 #define dependent_type(dep) ((dep)->flags & DEPENDENT_TYPE_MASK) 57 #define dependent_is_cell(dep) (dependent_type (dep) == DEPENDENT_CELL) 58 #define dependent_needs_recalc(dep) ((dep)->flags & DEPENDENT_NEEDS_RECALC) 59 #define dependent_is_linked(dep) ((dep)->flags & DEPENDENT_IS_LINKED) 60 61 struct _GnmDepContainer { 62 GnmDependent *head, *tail; 63 64 /* Large ranges hashed on 'range' to accelerate duplicate culling. This 65 * is traversed by g_hash_table_foreach mostly. 66 */ 67 int buckets; 68 GHashTable **range_hash; 69 GOMemChunk *range_pool; 70 71 /* Single ranges, this maps an GnmEvalPos * to a GSList of its 72 * dependencies. 73 */ 74 GHashTable *single_hash; 75 GOMemChunk *single_pool; 76 77 /* All of the ExprNames that refer to this container */ 78 GHashTable *referencing_names; 79 80 /* Dynamic Deps */ 81 GHashTable *dynamic_deps; 82 }; 83 84 typedef void (*GnmDepFunc) (GnmDependent *dep, gpointer user); 85 86 guint32 dependent_type_register (GnmDependentClass const *klass); 87 void dependent_types_init (void); 88 void dependent_types_shutdown (void); 89 90 void dependent_set_expr (GnmDependent *dep, GnmExprTop const *new_texpr); 91 void dependent_set_sheet (GnmDependent *dep, Sheet *sheet); 92 void dependent_link (GnmDependent *dep); 93 void dependent_unlink (GnmDependent *dep); 94 void dependent_queue_recalc (GnmDependent *dep); 95 void dependent_add_dynamic_dep (GnmDependent *dep, GnmRangeRef const *rr); 96 97 gboolean dependent_is_volatile (GnmDependent *dep); 98 99 gboolean dependent_has_pos (GnmDependent const *dep); 100 GnmCellPos const *dependent_pos (GnmDependent const *dep); 101 void dependent_move (GnmDependent *dep, int dx, int dy); 102 103 GOUndo *dependents_relocate (GnmExprRelocateInfo const *info); 104 void dependents_link (GSList *deps); 105 106 void gnm_cell_eval (GnmCell *cell); 107 void cell_queue_recalc (GnmCell *cell); 108 void cell_foreach_dep (GnmCell const *cell, GnmDepFunc func, gpointer user); 109 110 void sheet_region_queue_recalc (Sheet const *sheet, GnmRange const *range); 111 void dependents_invalidate_sheet (Sheet *sheet, gboolean destroy); 112 void dependents_workbook_destroy (Workbook *wb); 113 void dependents_revive_sheet (Sheet *sheet); 114 void workbook_queue_all_recalc (Workbook *wb); 115 void workbook_queue_volatile_recalc (Workbook *wb); 116 117 GnmDepContainer *gnm_dep_container_new (Sheet *sheet); 118 void gnm_dep_container_dump (GnmDepContainer const *deps, 119 Sheet *sheet); 120 void dependents_dump (Workbook *wb); 121 void gnm_dep_container_sanity_check (GnmDepContainer const *deps); 122 void gnm_dep_container_resize (GnmDepContainer *deps, int rows); 123 124 // ---------------------------------------------------------------------------- 125 126 typedef struct { 127 GnmDependent base; 128 } GnmDepManaged; 129 130 void dependent_managed_init (GnmDepManaged *dep, Sheet *sheet); 131 void dependent_managed_set_expr (GnmDepManaged *dep, GnmExprTop const *texpr); 132 GnmExprTop const *dependent_managed_get_expr (GnmDepManaged const *dep); 133 void dependent_managed_set_sheet (GnmDepManaged *dep, Sheet *sheet); 134 135 // ---------------------------------------------------------------------------- 136 137 #define DEPENDENT_CONTAINER_FOREACH_DEPENDENT(dc, dep, code) \ 138 do { \ 139 GnmDependent *dep = (dc)->head; \ 140 while (dep) { \ 141 GnmDependent *_next = dep->next_dep; \ 142 code; \ 143 dep = _next; \ 144 } \ 145 } while (0) 146 147 #define DEPENDENT_MAKE_TYPE(t,...) \ 148 guint \ 149 t ## _get_dep_type (void) \ 150 { \ 151 static guint32 type = 0; \ 152 if (type == 0) { \ 153 static GnmDependentClass klass = { __VA_ARGS__ }; \ 154 klass.eval = &t ## _eval; \ 155 klass.debug_name = &t ## _debug_name; \ 156 type = dependent_type_register (&klass); \ 157 } \ 158 return type; \ 159 } 160 161 void dependent_debug_name (GnmDependent const *dep, GString *target); 162 163 G_END_DECLS 164 165 #endif /* _GNM_DEPENDENT_H_ */ 166