Tulip  4.2.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
GraphUpdatesRecorder.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 #ifndef DOXYGEN_NOTFOR_DEVEL
22 #ifndef TLPGRAPHRECORDER_H
23 #define TLPGRAPHRECORDER_H
24 
25 
26 #include <string>
27 #include <set>
28 #include <vector>
29 
30 #include <tulip/tuliphash.h>
31 #include <tulip/Node.h>
32 #include <tulip/Edge.h>
33 #include <tulip/Graph.h>
34 #include <tulip/Observable.h>
35 #include <tulip/ObservableGraph.h>
36 #include <tulip/ObservableProperty.h>
37 #include <tulip/MutableContainer.h>
38 
39 namespace std {
40 template<>
41 struct less<tlp::Graph*> {
42  size_t operator()(const tlp::Graph* g1, const tlp::Graph* g2) const {
43  // the id order corresponds to the creation order
44  // so when dealing with a set<Graph*> this will ensure that
45  // we encounter a supergraph before its subgraphs
46  return g1->getId() < g2->getId();
47  }
48 };
49 }
50 
51 namespace tlp {
52 
53 struct EdgeRecord {
54  node source;
55  node target;
56  std::set<tlp::Graph*> graphs;
57 
58  EdgeRecord() {}
59  EdgeRecord(Graph* g, node s, node t) : source(s), target(t) {
60  graphs.insert(g);
61  }
62 };
63 
64 struct PropertyRecord {
65  PropertyInterface* prop;
66  std::string name;
67 
68  PropertyRecord(PropertyInterface* p, std::string str)
69  :prop(p), name(str) {}
70 };
71 
72 struct GraphEltsRecord {
73  Graph* graph;
74  MutableContainer<bool> elts;
75 
76  GraphEltsRecord(Graph* g): graph(g) {}
77 };
78 
79 } // end of namespace tlp
80 
81 namespace std {
82 template<>
83 struct less<tlp::PropertyRecord> {
84  size_t operator()(const tlp::PropertyRecord& rp1, const tlp::PropertyRecord& rp2) const {
85  return rp1.name < rp2.name;
86  }
87 };
88 
89 template<>
90 struct less<tlp::GraphEltsRecord*> {
91  size_t operator()(const tlp::GraphEltsRecord* g1, const tlp::GraphEltsRecord* g2) const {
92  return g1->graph->getId() < g2->graph->getId();
93  }
94 };
95 }
96 
97 namespace tlp {
98 class GraphImpl;
99 class GraphStorageIdsMemento;
100 
101 class GraphUpdatesRecorder :public GraphObserver, public PropertyObserver, public Observable {
102  friend class GraphImpl;
103  //
104 #if !defined(NDEBUG)
105  bool recordingStopped;
106 #endif
107  bool updatesReverted;
108  bool restartAllowed;
109  bool newValuesRecorded;
110 
111  // one 'set' of added nodes per graph
112  MutableContainer<GraphEltsRecord*> graphAddedNodes;
113  // the whole 'set' of added nodes
114  MutableContainer<bool> addedNodes;
115  // one 'set' of deleted nodes per graph
116  MutableContainer<GraphEltsRecord*> graphDeletedNodes;
117  // one 'set' of added edges per graph
118  MutableContainer<GraphEltsRecord*> graphAddedEdges;
119  // ends of all added edges
120  MutableContainer<std::pair<node, node>*> addedEdgesEnds;
121  // one 'set' of deleted edges per graph
122  MutableContainer<GraphEltsRecord*> graphDeletedEdges;
123  // ends of all deleted edges
124  MutableContainer<std::pair<node, node>*> deletedEdgesEnds;
125  // one set of reverted edges
126  std::set<edge> revertedEdges;
127  // source + target per updated edge
128  TLP_HASH_MAP<edge, std::pair<node, node> > oldEdgesEnds;
129  // source + target per updated edge
130  TLP_HASH_MAP<edge, std::pair<node, node> > newEdgesEnds;
131  // one set for old edge containers
132  MutableContainer<std::vector<edge>*> oldContainers;
133  // one set for new edge containers
134  MutableContainer<std::vector<edge>*> newContainers;
135 
136  // copy of nodes/edges id manager state at start time
137  const GraphStorageIdsMemento* oldIdsState;
138  // copy of nodes/edges id manager state at stop time
139  const GraphStorageIdsMemento* newIdsState;
140 
141  // one list of (parent graph, added sub-graph)
142  std::list<std::pair<Graph*, Graph*> > addedSubGraphs;
143  // one list of (parent graph, deleted sub-graph)
144  std::list<std::pair<Graph*, Graph*> > deletedSubGraphs;
145 
146  // one set of added properties per graph
147  TLP_HASH_MAP<Graph*, std::set<PropertyRecord> > addedProperties;
148  // one set of deleted properties per graph
149  TLP_HASH_MAP<Graph*, std::set<PropertyRecord> > deletedProperties;
150  // one set of old attribute values per graph
151  TLP_HASH_MAP<Graph*, DataSet> oldAttributeValues;
152  // one set of new attribute values per graph
153  TLP_HASH_MAP<Graph*, DataSet> newAttributeValues;
154 
155  // one set of updated addNodes per property
156  TLP_HASH_MAP<PropertyInterface*, std::set<node> > updatedPropsAddedNodes;
157 
158  // one set of updated addEdges per property
159  TLP_HASH_MAP<PropertyInterface*, std::set<edge> > updatedPropsAddedEdges;
160 
161  // the old default node value for each updated property
162  TLP_HASH_MAP<PropertyInterface*, DataMem*> oldNodeDefaultValues;
163  // the new default node value for each updated property
164  TLP_HASH_MAP<PropertyInterface*, DataMem*> newNodeDefaultValues;
165  // the old default edge value for each updated property
166  TLP_HASH_MAP<PropertyInterface*, DataMem*> oldEdgeDefaultValues;
167  // the new default edge value for each updated property
168  TLP_HASH_MAP<PropertyInterface*, DataMem*> newEdgeDefaultValues;
169 
170  struct RecordedValues {
171  PropertyInterface* values;
172  MutableContainer<bool>* recordedNodes;
173  MutableContainer<bool>* recordedEdges;
174 
175  RecordedValues(PropertyInterface* prop = NULL,
176  MutableContainer<bool>* rn = NULL,
177  MutableContainer<bool>* re = NULL):
178  values(prop), recordedNodes(rn), recordedEdges(re) {}
179  };
180 
181  // the old nodes/edges values for each updated property
182  TLP_HASH_MAP<PropertyInterface*, RecordedValues> oldValues;
183  // the new node value for each updated property
184  TLP_HASH_MAP<PropertyInterface*, RecordedValues> newValues;
185 
186  // real deletion of deleted objects (properties, sub graphs)
187  // during the recording of updates thes objects are removed from graph
188  // structures but not really 'deleted'
189  void deleteDeletedObjects();
190  // deletion of recorded values
191  void deleteValues(TLP_HASH_MAP<PropertyInterface*, RecordedValues>& values);
192  // deletion of DataMem default values
193  void deleteDefaultValues(TLP_HASH_MAP<PropertyInterface*, DataMem*>& values);
194  // deletion of various containers
195  template<typename T>
196  void deleteContainerValues(MutableContainer<T>& ctnr) {
197  IteratorValue* it = ctnr.findAllValues(NULL, false);
198 
199  while(it->hasNext()) {
200  TypedValueContainer<T> tvc;
201  it->nextValue(tvc);
202  delete tvc.value;
203  }
204 
205  delete it;
206  }
207  // record of a node's edges container before/after modification
208  void recordEdgeContainer(MutableContainer<std::vector<edge>*>&,
209  GraphImpl*, node);
210  // remove an edge from a node's edges container
211  void removeFromEdgeContainer(MutableContainer<std::vector<edge>*>& containers,
212  edge e, node n);
213 
214  void removeGraphData(Graph *);
215 
216  // record new values for all updated properties
217  // restartAllowed must be true
218  void recordNewValues(GraphImpl*);
219  void recordNewNodeValues(PropertyInterface* p);
220  void recordNewEdgeValues(PropertyInterface* p);
221 
222  // start of recording (push)
223  void startRecording(GraphImpl*);
224  // end of recording
225  // push an other recorder or pop this one
226  void stopRecording(Graph*);
227  // restart of recording (unpop)
228  void restartRecording(Graph*);
229  // perform undo/redo updates
230  void doUpdates(GraphImpl*, bool undo);
231  // remove a property from the observed ones
232  // only if nothing is yet recorded for that property
233  bool dontObserveProperty(PropertyInterface *);
234  // check if the property is newly added or deleted
235  bool isAddedOrDeletedProperty(Graph*, PropertyInterface *);
236 
237 public:
238  GraphUpdatesRecorder(bool allowRestart = true);
239  ~GraphUpdatesRecorder();
240 
241  // GraphObserver interface
242  // graphAddedNodes
243  void addNode(Graph* g, const node n);
244 
245  // graphAddedEdges
246  void addEdge(Graph* g, const edge e);
247 
248  // graphDeletedNodes
249  void delNode(Graph* g, const node n);
250 
251  // graphDeletedEdges
252  void delEdge(Graph* g, const edge e);
253 
254  // revertedEdges
255  void reverseEdge(Graph* g, const edge e);
256 
257  // oldEdgesEnds
258  void beforeSetEnds(Graph* g, const edge e);
259 
260  // newEdgesEnds
261  void afterSetEnds(Graph* g, const edge e);
262 
263  // addedSubGraphs
264  void addSubGraph(Graph* g, Graph* sg);
265 
266  // deletedSubGraphs
267  void delSubGraph(Graph* g, Graph* sg);
268 
269  // addedProperties
270  void addLocalProperty(Graph* g, const std::string& name);
271 
272  // deletedProperties
273  void delLocalProperty(Graph* g, const std::string& name);
274 
275  // PropertyObserver Interface
276  // oldValues
277  void beforeSetNodeValue(PropertyInterface* p, const node n);
278 
279  // oldNodeDefaultValues
280  void beforeSetAllNodeValue(PropertyInterface* p);
281 
282  // oldValues
283  void beforeSetEdgeValue(PropertyInterface* p, const edge e);
284 
285  // oldEdgeDefaultValues
286  void beforeSetAllEdgeValue(PropertyInterface* p);
287 
288  // beforeSetAttribute
289  void beforeSetAttribute(Graph* g, const std::string& name);
290 
291  // removeAttribute
292  void removeAttribute(Graph* g, const std::string& name);
293 
294 protected:
295  // override Observable::treatEvent
296  virtual void treatEvent(const Event& ev);
297 };
298 }
299 
300 
301 #endif // TLPGRAPHRECORDER_H
302 #endif // DOXYGEN_NOTFOR_DEVEL
303 ///@endcond