Tulip  4.1.0
Better Visualization Through Research
 All Classes 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 set of added sub graphs per graph
142  TLP_HASH_MAP<Graph*, std::set<Graph*> > addedSubGraphs;
143  // one set of deleted sub graphs per graph
144  TLP_HASH_MAP<Graph*, std::set<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  // record new values for all updated properties
215  // restartAllowed must be true
216  void recordNewValues(GraphImpl*);
217  void recordNewNodeValues(PropertyInterface* p);
218  void recordNewEdgeValues(PropertyInterface* p);
219 
220  // start of recording (push)
221  void startRecording(GraphImpl*);
222  // end of recording
223  // push an other recorder or pop this one
224  void stopRecording(Graph*);
225  // restart of recording (unpop)
226  void restartRecording(Graph*);
227  // perform undo/redo updates
228  void doUpdates(GraphImpl*, bool undo);
229  // remove a property from the observed ones
230  // only if nothing is yet recorded for that property
231  bool dontObserveProperty(PropertyInterface *);
232  // check if the property is newly added or deleted
233  bool isAddedOrDeletedProperty(Graph*, PropertyInterface *);
234 
235 public:
236  GraphUpdatesRecorder(bool allowRestart = true);
237  ~GraphUpdatesRecorder();
238 
239  // GraphObserver interface
240  // graphAddedNodes
241  void addNode(Graph* g, const node n);
242 
243  // graphAddedEdges
244  void addEdge(Graph* g, const edge e);
245 
246  // graphDeletedNodes
247  void delNode(Graph* g, const node n);
248 
249  // graphDeletedEdges
250  void delEdge(Graph* g, const edge e);
251 
252  // revertedEdges
253  void reverseEdge(Graph* g, const edge e);
254 
255  // oldEdgesEnds
256  void beforeSetEnds(Graph* g, const edge e);
257 
258  // newEdgesEnds
259  void afterSetEnds(Graph* g, const edge e);
260 
261  // addedSubGraphs
262  void addSubGraph(Graph* g, Graph* sg);
263 
264  // deletedSubGraphs
265  void delSubGraph(Graph* g, Graph* sg);
266 
267  // addedProperties
268  void addLocalProperty(Graph* g, const std::string& name);
269 
270  // deletedProperties
271  void delLocalProperty(Graph* g, const std::string& name);
272 
273  // PropertyObserver Interface
274  // oldValues
275  void beforeSetNodeValue(PropertyInterface* p, const node n);
276 
277  // oldNodeDefaultValues
278  void beforeSetAllNodeValue(PropertyInterface* p);
279 
280  // oldValues
281  void beforeSetEdgeValue(PropertyInterface* p, const edge e);
282 
283  // oldEdgeDefaultValues
284  void beforeSetAllEdgeValue(PropertyInterface* p);
285 
286  // beforeSetAttribute
287  void beforeSetAttribute(Graph* g, const std::string& name);
288 
289  // removeAttribute
290  void removeAttribute(Graph* g, const std::string& name);
291 
292 protected:
293  // override Observable::treatEvent
294  virtual void treatEvent(const Event& ev);
295 };
296 }
297 
298 
299 #endif // TLPGRAPHRECORDER_H
300 #endif // DOXYGEN_NOTFOR_DEVEL
301 ///@endcond