Tulip  4.3.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 PropertyRecord {
63  PropertyInterface* prop;
64  std::string name;
65 
66  PropertyRecord(PropertyInterface* p, std::string str)
67  :prop(p), name(str) {}
68 };
69 
70 struct GraphEltsRecord {
71  Graph* graph;
72  MutableContainer<bool> elts;
73 
74  GraphEltsRecord(Graph* g): graph(g) {}
75 };
76 
77 } // end of namespace tlp
78 
79 namespace std {
80 template<>
81 struct less<tlp::PropertyRecord> {
82  size_t operator()(const tlp::PropertyRecord& rp1, const tlp::PropertyRecord& rp2) const {
83  return rp1.name < rp2.name;
84  }
85 };
86 
87 template<>
88 struct less<tlp::GraphEltsRecord*> {
89  size_t operator()(const tlp::GraphEltsRecord* g1, const tlp::GraphEltsRecord* g2) const {
90  return g1->graph->getId() < g2->graph->getId();
91  }
92 };
93 }
94 
95 namespace tlp {
96 class GraphImpl;
97 class GraphStorageIdsMemento;
98 
99 class GraphUpdatesRecorder :public Observable {
100  friend class GraphImpl;
101  //
102 #if !defined(NDEBUG)
103  bool recordingStopped;
104 #endif
105  bool updatesReverted;
106  bool restartAllowed;
107  bool newValuesRecorded;
108 
109  // one 'set' of added nodes per graph
110  MutableContainer<GraphEltsRecord*> graphAddedNodes;
111  // the whole 'set' of added nodes
112  MutableContainer<bool> addedNodes;
113  // one 'set' of deleted nodes per graph
114  MutableContainer<GraphEltsRecord*> graphDeletedNodes;
115  // one 'set' of added edges per graph
116  MutableContainer<GraphEltsRecord*> graphAddedEdges;
117  // ends of all added edges
118  MutableContainer<std::pair<node, node>*> addedEdgesEnds;
119  // one 'set' of deleted edges per graph
120  MutableContainer<GraphEltsRecord*> graphDeletedEdges;
121  // ends of all deleted edges
122  MutableContainer<std::pair<node, node>*> deletedEdgesEnds;
123  // one set of reverted edges
124  std::set<edge> revertedEdges;
125  // source + target per updated edge
126  TLP_HASH_MAP<edge, std::pair<node, node> > oldEdgesEnds;
127  // source + target per updated edge
128  TLP_HASH_MAP<edge, std::pair<node, node> > newEdgesEnds;
129  // one set for old edge containers
130  MutableContainer<std::vector<edge>*> oldContainers;
131  // one set for new edge containers
132  MutableContainer<std::vector<edge>*> newContainers;
133 
134  // copy of nodes/edges id manager state at start time
135  const GraphStorageIdsMemento* oldIdsState;
136  // copy of nodes/edges id manager state at stop time
137  const GraphStorageIdsMemento* newIdsState;
138 
139  // one list of (parent graph, added sub-graph)
140  std::list<std::pair<Graph*, Graph*> > addedSubGraphs;
141  // one list of (parent graph, deleted sub-graph)
142  std::list<std::pair<Graph*, Graph*> > deletedSubGraphs;
143 
144  // one set of added properties per graph
145  TLP_HASH_MAP<Graph*, std::set<PropertyRecord> > addedProperties;
146  // one set of deleted properties per graph
147  TLP_HASH_MAP<Graph*, std::set<PropertyRecord> > deletedProperties;
148  // one set of old attribute values per graph
149  TLP_HASH_MAP<Graph*, DataSet> oldAttributeValues;
150  // one set of new attribute values per graph
151  TLP_HASH_MAP<Graph*, DataSet> newAttributeValues;
152 
153  // one set of updated addNodes per property
154  TLP_HASH_MAP<PropertyInterface*, std::set<node> > updatedPropsAddedNodes;
155 
156  // one set of updated addEdges per property
157  TLP_HASH_MAP<PropertyInterface*, std::set<edge> > updatedPropsAddedEdges;
158 
159  // the old default node value for each updated property
160  TLP_HASH_MAP<PropertyInterface*, DataMem*> oldNodeDefaultValues;
161  // the new default node value for each updated property
162  TLP_HASH_MAP<PropertyInterface*, DataMem*> newNodeDefaultValues;
163  // the old default edge value for each updated property
164  TLP_HASH_MAP<PropertyInterface*, DataMem*> oldEdgeDefaultValues;
165  // the new default edge value for each updated property
166  TLP_HASH_MAP<PropertyInterface*, DataMem*> newEdgeDefaultValues;
167 
168  struct RecordedValues {
169  PropertyInterface* values;
170  MutableContainer<bool>* recordedNodes;
171  MutableContainer<bool>* recordedEdges;
172 
173  RecordedValues(PropertyInterface* prop = NULL,
174  MutableContainer<bool>* rn = NULL,
175  MutableContainer<bool>* re = NULL):
176  values(prop), recordedNodes(rn), recordedEdges(re) {}
177  };
178 
179  // the old nodes/edges values for each updated property
180  TLP_HASH_MAP<PropertyInterface*, RecordedValues> oldValues;
181  // the new node value for each updated property
182  TLP_HASH_MAP<PropertyInterface*, RecordedValues> newValues;
183 
184  // real deletion of deleted objects (properties, sub graphs)
185  // during the recording of updates thes objects are removed from graph
186  // structures but not really 'deleted'
187  void deleteDeletedObjects();
188  // deletion of recorded values
189  void deleteValues(TLP_HASH_MAP<PropertyInterface*, RecordedValues>& values);
190  // deletion of DataMem default values
191  void deleteDefaultValues(TLP_HASH_MAP<PropertyInterface*, DataMem*>& values);
192  // deletion of various containers
193  template<typename T>
194  void deleteContainerValues(MutableContainer<T>& ctnr) {
195  IteratorValue* it = ctnr.findAllValues(NULL, false);
196 
197  while(it->hasNext()) {
198  TypedValueContainer<T> tvc;
199  it->nextValue(tvc);
200  delete tvc.value;
201  }
202 
203  delete it;
204  }
205  // record of a node's edges container before/after modification
206  void recordEdgeContainer(MutableContainer<std::vector<edge>*>&,
207  GraphImpl*, node);
208  // remove an edge from a node's edges container
209  void removeFromEdgeContainer(MutableContainer<std::vector<edge>*>& containers,
210  edge e, node n);
211 
212  void removeGraphData(Graph *);
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