Tulip  4.4.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/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 
94  // one 'set' of added nodes per graph
95  MutableContainer<GraphEltsRecord*> graphAddedNodes;
96  // the whole 'set' of added nodes
97  MutableContainer<bool> addedNodes;
98  // one 'set' of deleted nodes per graph
99  MutableContainer<GraphEltsRecord*> graphDeletedNodes;
100  // one 'set' of added edges per graph
101  MutableContainer<GraphEltsRecord*> graphAddedEdges;
102  // ends of all added edges
103  MutableContainer<std::pair<node, node>*> addedEdgesEnds;
104  // one 'set' of deleted edges per graph
105  MutableContainer<GraphEltsRecord*> graphDeletedEdges;
106  // ends of all deleted edges
107  MutableContainer<std::pair<node, node>*> deletedEdgesEnds;
108  // one set of reverted edges
109  std::set<edge> revertedEdges;
110  // source + target per updated edge
111  TLP_HASH_MAP<edge, std::pair<node, node> > oldEdgesEnds;
112  // source + target per updated edge
113  TLP_HASH_MAP<edge, std::pair<node, node> > newEdgesEnds;
114  // one set for old edge containers
115  MutableContainer<std::vector<edge>*> oldContainers;
116  // one set for new edge containers
117  MutableContainer<std::vector<edge>*> newContainers;
118 
119  // copy of nodes/edges id manager state at start time
120  const GraphStorageIdsMemento* oldIdsState;
121  // copy of nodes/edges id manager state at stop time
122  const GraphStorageIdsMemento* newIdsState;
123 
124  // one list of (parent graph, added sub-graph)
125  std::list<std::pair<Graph*, Graph*> > addedSubGraphs;
126  // one list of (parent graph, deleted sub-graph)
127  std::list<std::pair<Graph*, Graph*> > deletedSubGraphs;
128 
129  // one set of added properties per graph
130  TLP_HASH_MAP<Graph*, std::set<PropertyInterface*> > addedProperties;
131  // one set of deleted properties per graph
132  TLP_HASH_MAP<Graph*, std::set<PropertyInterface*> > deletedProperties;
133  // one set of old attribute values per graph
134  TLP_HASH_MAP<Graph*, DataSet> oldAttributeValues;
135  // one set of new attribute values per graph
136  TLP_HASH_MAP<Graph*, DataSet> newAttributeValues;
137 
138  // one set of updated addNodes per property
139  TLP_HASH_MAP<PropertyInterface*, std::set<node> > updatedPropsAddedNodes;
140 
141  // one set of updated addEdges per property
142  TLP_HASH_MAP<PropertyInterface*, std::set<edge> > updatedPropsAddedEdges;
143 
144  // the old default node value for each updated property
145  TLP_HASH_MAP<PropertyInterface*, DataMem*> oldNodeDefaultValues;
146  // the new default node value for each updated property
147  TLP_HASH_MAP<PropertyInterface*, DataMem*> newNodeDefaultValues;
148  // the old default edge value for each updated property
149  TLP_HASH_MAP<PropertyInterface*, DataMem*> oldEdgeDefaultValues;
150  // the new default edge value for each updated property
151  TLP_HASH_MAP<PropertyInterface*, DataMem*> newEdgeDefaultValues;
152  // the old name for each renamed property
153  TLP_HASH_MAP<PropertyInterface*, std::string> renamedProperties;
154 
155  struct RecordedValues {
156  PropertyInterface* values;
157  MutableContainer<bool>* recordedNodes;
158  MutableContainer<bool>* recordedEdges;
159 
160  RecordedValues(PropertyInterface* prop = NULL,
161  MutableContainer<bool>* rn = NULL,
162  MutableContainer<bool>* re = NULL):
163  values(prop), recordedNodes(rn), recordedEdges(re) {}
164  };
165 
166  // the old nodes/edges values for each updated property
167  TLP_HASH_MAP<PropertyInterface*, RecordedValues> oldValues;
168  // the new node value for each updated property
169  TLP_HASH_MAP<PropertyInterface*, RecordedValues> newValues;
170 
171  // real deletion of deleted objects (properties, sub graphs)
172  // during the recording of updates these objects are removed from graph
173  // structures but not really 'deleted'
174  void deleteDeletedObjects();
175  // deletion of recorded values
176  void deleteValues(TLP_HASH_MAP<PropertyInterface*, RecordedValues>& values);
177  // deletion of DataMem default values
178  void deleteDefaultValues(TLP_HASH_MAP<PropertyInterface*, DataMem*>& values);
179  // deletion of various containers
180  template<typename T>
181  void deleteContainerValues(MutableContainer<T>& ctnr) {
182  IteratorValue* it = ctnr.findAllValues(NULL, false);
183 
184  while(it->hasNext()) {
185  TypedValueContainer<T> tvc;
186  it->nextValue(tvc);
187  delete tvc.value;
188  }
189 
190  delete it;
191  }
192  // record of a node's edges container before/after modification
193  void recordEdgeContainer(MutableContainer<std::vector<edge>*>&,
194  GraphImpl*, node);
195  // remove an edge from a node's edges container
196  void removeFromEdgeContainer(MutableContainer<std::vector<edge>*>& containers,
197  edge e, node n);
198 
199  void removeGraphData(Graph *);
200 
201  // record new values for all updated properties
202  // restartAllowed must be true
203  void recordNewValues(GraphImpl*);
204  void recordNewNodeValues(PropertyInterface* p);
205  void recordNewEdgeValues(PropertyInterface* p);
206 
207  // start of recording (push)
208  void startRecording(GraphImpl*);
209  // end of recording
210  // push an other recorder or pop this one
211  void stopRecording(Graph*);
212  // restart of recording (unpop)
213  void restartRecording(Graph*);
214  // perform undo/redo updates
215  void doUpdates(GraphImpl*, bool undo);
216  // remove a property from the observed ones
217  // only if nothing is yet recorded for that property
218  bool dontObserveProperty(PropertyInterface *);
219  // check if the property is newly added or deleted
220  bool isAddedOrDeletedProperty(Graph*, PropertyInterface *);
221 
222 public:
223  GraphUpdatesRecorder(bool allowRestart = true);
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 
289 #endif // TLPGRAPHRECORDER_H
290 #endif // DOXYGEN_NOTFOR_DEVEL
291 ///@endcond