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