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