8
* maintain buffers of pending requests (in callback subgraphs)
9
* note that certain sequences of operations can reduce:
11
* [ins mod] del => (empty)
14
ilbool il_batch_delete_node(ILview_t *view, ILnode_t *spec);
15
ilbool il_batch_delete_edge(ILview_t *view, ILedge_t *spec);
17
ilbool il_batch_insert_node(ILview_t *view, ILnode_t *spec)
23
ev = (engview_t*)(view->pvt);
24
if (il_find_node(ev,spec) == NILnode) {
25
n = il_open_node(ev,spec);
26
agsubnode(ev->model.v[IL_INS],n,TRUE);
29
else rv = FALSE; /* can't insert pre-existing nodes */
33
ilbool il_batch_modify_node(ILview_t *view, ILnode_t *spec)
36
Agnode_t *n, *subnode;
39
ev = (engview_t*)(view->pvt);
40
if ((n = il_find_node(ev,spec))) {
41
if ((agsubnode(ev->model.v[IL_INS],n,FALSE)) == NILnode) {
42
subnode = agsubnode(ev->model.v[IL_MOD],n,TRUE);
43
if (spec->update & IL_UPD_SHAPE)
44
il_nd(subnode)->bb.valid = FALSE;
46
/* else fold ins mode -> mod */
49
else rv = FALSE; /* can't modify non-existent nodes */
53
ilbool il_batch_delete_node(ILview_t *view, ILnode_t *spec)
56
Agnode_t *n, *subnode;
60
ev = (engview_t*)(view->pvt);
61
if ((n = il_find_node(ev,spec))) {
62
/* implies deletion of adjacent edges */
63
for (e = agfstedge(n); e; e = agnxtedge(e,n))
64
il_batch_delete_edge(view, il_edge(e));
66
if ((subnode = agsubnode(ev->model.v[IL_INS],n,FALSE))) {
67
/* fold ins [mod] del => (empty), i.e. cancel in buffer */
68
il_close_node(ev, spec);
71
/* fold mod del => del */
72
if ((subnode = agsubnode(ev->model.v[IL_MOD],n,FALSE)))
74
/* else no mods are pending */
75
agsubnode(ev->model.v[IL_DEL],n,TRUE);
79
else rv = FALSE; /*can't delete non-existent nodes */
83
/* edges are the same. if we adoped a cleaner/more functional
84
* coding style, we could just merge all this code.
86
ilbool il_batch_insert_edge(ILview_t *view, ILedge_t *spec)
92
ev = (engview_t*)(view->pvt);
93
if (il_find_edge(ev,spec) == NILedge) {
94
e = il_open_edge(ev,spec);
96
agsubedge(ev->model.e[IL_INS],e,TRUE);
97
assert(agnedges(ev->model.e[IL_INS]) > 0);
102
else rv = FALSE; /* can't insert pre-existing edges */
106
ilbool il_batch_modify_edge(ILview_t *view, ILedge_t *spec)
109
Agedge_t *e, *subedge;
112
ev = (engview_t*)(view->pvt);
113
if ((e = il_find_edge(ev,spec))) {
114
if (agsubedge(ev->model.e[IL_INS],e,FALSE) == NILedge)
115
subedge = agsubedge(ev->model.e[IL_MOD],e,TRUE);
116
/* else fold ins mod => ins */
119
else rv = FALSE; /* can't modify non-existent edges */
123
ilbool il_batch_delete_edge(ILview_t *view, ILedge_t *spec)
126
Agedge_t *e, *subedge;
129
ev = (engview_t*)(view->pvt);
130
if ((e = il_find_edge(ev,spec))) {
131
if ((subedge = agsubedge(ev->model.e[IL_INS],e,FALSE))) {
132
/* fold ins [mod] del => (empty), i.e. cancel in buffer */
133
il_close_edge(ev, spec);
136
/* fold mod del => del */
137
if ((subedge = agsubedge(ev->model.e[IL_MOD],e,FALSE)))
139
/* else no mods are pending */
140
agsubedge(ev->model.e[IL_DEL],e,TRUE);
144
else rv = FALSE; /* can't delete non-existent edges */
148
static void cbcheck(ILview_t *view)
150
if (view->enable_immediate_callbacks)
151
((engview_t*)(view->pvt))->engine->callback(view);
154
ilbool il_batch_ins(ILview_t *view, ILobj_t *spec)
156
static ILfnlist_t f = {
157
(ILnodefn_t)il_batch_insert_node,
158
(ILedgefn_t)il_batch_insert_edge,
163
rv = ildispatch(view,spec,&f);
168
ilbool il_batch_mod(ILview_t *view, ILobj_t *spec)
170
static ILfnlist_t f = {
171
(ILnodefn_t)il_batch_modify_node,
172
(ILedgefn_t)il_batch_modify_edge,
177
rv = ildispatch(view,spec,&f);
182
ilbool il_batch_del(ILview_t *view, ILobj_t *spec)
184
static ILfnlist_t f = {
185
(ILnodefn_t)il_batch_delete_node,
186
(ILedgefn_t)il_batch_delete_edge,
191
rv = ildispatch(view,spec,&f);