vtkSMProxyPropertyInternals.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ParaView
4  Module: vtkSMProxyPropertyInternals.h
5 
6  Copyright (c) Kitware, Inc.
7  All rights reserved.
8  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #ifndef vtkSMProxyPropertyInternals_h
16 #define vtkSMProxyPropertyInternals_h
17 
18 #include "vtkCommand.h" // for vtkCommand enums
19 #include "vtkSMMessage.h" // for paraview_protobuf
20 #include "vtkSMProxy.h" // for vtkSMProxy
21 #include "vtkSMProxyLocator.h" // for vtkSMProxyLocator
22 #include "vtkSMSession.h" // for vtkSMSession
23 #include "vtkSmartPointer.h" // for vtkSmartPointer
24 #include "vtkWeakPointer.h" // for vtkWeakPointer
25 
26 #include <algorithm> //for std::set_difference
27 #include <map> // for std::map
28 #include <set> // for std::set
29 #include <vector> // for std::vector
30 
31 class vtkSMProxyLocator;
32 
39 {
40 public:
41  typedef std::vector<vtkSmartPointer<vtkSMProxy>> SmartVectorOfProxies;
42  typedef std::vector<vtkWeakPointer<vtkSMProxy>> WeakVectorOfProxies;
43  typedef std::vector<unsigned int> VectorOfUInts;
44 
45 private:
47  SmartVectorOfProxies Proxies;
48  SmartVectorOfProxies PreviousProxies; // < These are used to remove observers
49  // and break producer/consumer links
50  // whenever the value is changed.
51  WeakVectorOfProxies UncheckedProxies;
52 
53  VectorOfUInts Ports;
54  VectorOfUInts PreviousPorts;
55  VectorOfUInts UncheckedPorts;
56 
57  std::map<void*, unsigned long> ObserverIds;
58 
59  void UpdateProducerConsumerLinks()
60  {
61  if (this->Self == nullptr || this->Self->GetParent() == nullptr ||
62  this->PreviousProxies == this->Proxies)
63  {
64  return;
65  }
66 
67  vtkSMProxyProperty* self = this->Self;
68 
69  // create sets for each.
70  typedef std::set<vtkSMProxy*> proxy_set;
71  proxy_set previous_proxies(this->PreviousProxies.begin(), this->PreviousProxies.end());
72  proxy_set proxies(this->Proxies.begin(), this->Proxies.end());
73 
74  proxy_set removed;
75  std::set_difference(previous_proxies.begin(), previous_proxies.end(), proxies.begin(),
76  proxies.end(), std::insert_iterator<proxy_set>(removed, removed.begin()));
77  for (proxy_set::iterator iter = removed.begin(); iter != removed.end(); ++iter)
78  {
79  vtkSMProxy* producer = (*iter);
80  if (producer)
81  {
82  // remove observer.
83  producer->RemoveObserver(this->ObserverIds[producer]);
84  this->ObserverIds.erase(producer);
85 
86  // break producer/consumer link.
87  producer->RemoveConsumer(self, self->GetParent());
88  self->GetParent()->RemoveProducer(self, producer);
89  }
90  }
91  removed.clear();
92 
93  proxy_set added;
94  std::set_difference(proxies.begin(), proxies.end(), previous_proxies.begin(),
95  previous_proxies.end(), std::insert_iterator<proxy_set>(added, added.begin()));
96  for (proxy_set::iterator iter = added.begin(); iter != added.end(); ++iter)
97  {
98  vtkSMProxy* producer = (*iter);
99  if (producer)
100  {
101  // observe UpdateDataEvent, so we can update dependent domains when the
102  // data changes.
103  this->ObserverIds[producer] = producer->AddObserver(
104  vtkCommand::UpdateDataEvent, self, &vtkSMProxyProperty::OnUpdateDataEvent);
105 
106  // add producer/consumer link.
107  producer->AddConsumer(self, self->GetParent());
108  self->GetParent()->AddProducer(self, producer);
109  }
110  }
111  this->PreviousProxies = this->Proxies;
112  }
113 
114  bool CheckedValueChanged()
115  {
116  this->ClearUnchecked();
117  this->UpdateProducerConsumerLinks();
118  return true;
119  }
120 
121 public:
123  : Self(self)
124  {
125  }
126 
127  //====================================================================================
128  // ** All methods return true if the "datastructure" was modified, false otherwise
129  // ** The key thing to keep in mind is whenever the "checked" value is
130  // ** changed, "unchecked" value must be cleared and the producer/consumer
131  // ** links must be corrected.
132  //====================================================================================
133  // Add a proxy/port to the unchecked list. Returns true if value modified.
134  bool AddUnchecked(vtkSMProxy* proxy, unsigned int port = 0)
135  {
136  this->UncheckedProxies.push_back(proxy);
137  this->UncheckedPorts.push_back(port);
138  return true;
139  }
140  //------------------------------------------------------------------------------------
141  // Add a proxy/port to the list and clear any unchecked values. Returns true if value modified.
142  bool Add(vtkSMProxy* proxy, unsigned int port = 0)
143  {
144  this->Proxies.push_back(proxy);
145  this->Ports.push_back(port);
146  return this->CheckedValueChanged();
147  }
148  //------------------------------------------------------------------------------------
149  bool Remove(vtkSMProxy* proxy)
150  {
151  SmartVectorOfProxies::iterator iter = this->Proxies.begin();
152  VectorOfUInts::iterator iter2 = this->Ports.begin();
153  for (; iter != this->Proxies.end() && iter2 != this->Ports.end(); ++iter, ++iter2)
154  {
155  if (iter->GetPointer() == proxy)
156  {
157  this->Proxies.erase(iter);
158  this->Ports.erase(iter2);
159  return this->CheckedValueChanged();
160  }
161  }
162  return false;
163  }
164 
165  //------------------------------------------------------------------------------------
166  bool Resize(unsigned int count)
167  {
168  if (this->Proxies.size() != count)
169  {
170  this->Proxies.resize(count);
171  this->Ports.resize(count);
172  return this->CheckedValueChanged();
173  }
174  return false;
175  }
176  //------------------------------------------------------------------------------------
177  bool ResizeUnchecked(unsigned int count)
178  {
179  if (this->UncheckedProxies.size() != count)
180  {
181  this->UncheckedProxies.resize(count);
182  this->UncheckedPorts.resize(count);
183  return true;
184  }
185  return false;
186  }
187  //------------------------------------------------------------------------------------
188  bool Clear()
189  {
190  if (!this->Proxies.empty())
191  {
192  this->Proxies.clear();
193  this->Ports.clear();
194  return this->CheckedValueChanged();
195  }
196  return false;
197  }
198  //------------------------------------------------------------------------------------
200  {
201  if (!this->UncheckedProxies.empty())
202  {
203  this->UncheckedProxies.clear();
204  this->UncheckedPorts.clear();
205  return true;
206  }
207  return false;
208  }
209 
210  //------------------------------------------------------------------------------------
211  bool Set(unsigned int index, vtkSMProxy* proxy, unsigned int port = 0)
212  {
213  if (static_cast<unsigned int>(this->Proxies.size()) > index && this->Proxies[index] == proxy &&
214  this->Ports[index] == port)
215  {
216  return false;
217  }
218  if (static_cast<unsigned int>(this->Proxies.size()) <= index)
219  {
220  this->Proxies.resize(index + 1);
221  this->Ports.resize(index + 1);
222  }
223  this->Proxies[index] = proxy;
224  this->Ports[index] = port;
225  return this->CheckedValueChanged();
226  }
227  //------------------------------------------------------------------------------------
228  bool SetUnchecked(unsigned int index, vtkSMProxy* proxy, unsigned int port = 0)
229  {
230  if (static_cast<unsigned int>(this->UncheckedProxies.size()) > index &&
231  this->UncheckedProxies[index] == proxy && this->UncheckedPorts[index] == port)
232  {
233  return false;
234  }
235  if (static_cast<unsigned int>(this->UncheckedProxies.size()) <= index)
236  {
237  this->UncheckedProxies.resize(index + 1);
238  this->UncheckedPorts.resize(index + 1);
239  }
240  this->UncheckedProxies[index] = proxy;
241  this->UncheckedPorts[index] = port;
242  return true;
243  }
244 
245  //------------------------------------------------------------------------------------
246  bool Set(unsigned int count, vtkSMProxy** proxies, const unsigned int* ports = nullptr)
247  {
248  SmartVectorOfProxies newValues(proxies, proxies + count);
249  VectorOfUInts newPorts;
250  if (ports)
251  {
252  newPorts.insert(newPorts.end(), ports, ports + count);
253  }
254  else
255  {
256  newPorts.resize(count);
257  }
258  if (this->Proxies != newValues || this->Ports != newPorts)
259  {
260  this->Proxies = newValues;
261  this->Ports = newPorts;
262  return this->CheckedValueChanged();
263  }
264  return false;
265  }
266 
267  //------------------------------------------------------------------------------------
268  bool SetProxies(const SmartVectorOfProxies& otherProxies, const VectorOfUInts& otherPorts)
269  {
270  if (this->Proxies != otherProxies || this->Ports != otherPorts)
271  {
272  this->Proxies = otherProxies;
273  this->Ports = otherPorts;
274  return this->CheckedValueChanged();
275  }
276  return false;
277  }
278 
279  //------------------------------------------------------------------------------------
280  bool SetUncheckedProxies(const WeakVectorOfProxies& otherProxies, const VectorOfUInts& otherPorts)
281  {
282  if (this->UncheckedProxies != otherProxies || this->UncheckedPorts != otherPorts)
283  {
284  this->UncheckedProxies = otherProxies;
285  this->UncheckedPorts = otherPorts;
286  return true;
287  }
288  return false;
289  }
290 
291  //------------------------------------------------------------------------------------
292  // Get methods.
293  //------------------------------------------------------------------------------------
294  bool IsAdded(vtkSMProxy* proxy)
295  {
296  SmartVectorOfProxies::iterator iter =
297  std::find(this->Proxies.begin(), this->Proxies.end(), proxy);
298  return (iter != this->Proxies.end());
299  }
300  //------------------------------------------------------------------------------------
301  const SmartVectorOfProxies& GetProxies() const { return this->Proxies; }
302  const WeakVectorOfProxies& GetUncheckedProxies() const { return this->UncheckedProxies; }
303  const VectorOfUInts& GetPorts() const { return this->Ports; }
304  const VectorOfUInts& GetUncheckedPorts() const { return this->UncheckedPorts; }
305 
306  //------------------------------------------------------------------------------------
307  vtkSMProxy* Get(unsigned int index) const
308  {
309  return (index < static_cast<unsigned int>(this->Proxies.size())
310  ? this->Proxies[index].GetPointer()
311  : nullptr);
312  }
313  //------------------------------------------------------------------------------------
314  vtkSMProxy* GetUnchecked(unsigned int index) const
315  {
316  if (!this->UncheckedProxies.empty())
317  {
318  return (index < static_cast<unsigned int>(this->UncheckedProxies.size())
319  ? this->UncheckedProxies[index].GetPointer()
320  : nullptr);
321  }
322  return this->Get(index);
323  }
324 
325  unsigned int GetPort(unsigned int index) const
326  {
327  return (index < static_cast<unsigned int>(this->Ports.size()) ? this->Ports[index] : 0);
328  }
329  unsigned int GetUncheckedPort(unsigned int index) const
330  {
331  if (!this->UncheckedPorts.empty())
332  {
333  return (index < static_cast<unsigned int>(this->UncheckedPorts.size())
334  ? this->UncheckedPorts[index]
335  : 0);
336  }
337  return this->GetPort(index);
338  }
339 
340  //------------------------------------------------------------------------------------
341  // Serialization methods.
342  //------------------------------------------------------------------------------------
343  bool WriteTo(paraview_protobuf::Variant* variant) const
344  {
345  variant->set_type(Variant::INPUT); // or PROXY?
346  for (SmartVectorOfProxies::const_iterator iter = this->Proxies.begin();
347  iter != this->Proxies.end(); ++iter)
348  {
349  if (vtkSMProxy* proxy = iter->GetPointer())
350  {
351  proxy->CreateVTKObjects();
352  variant->add_proxy_global_id(proxy->GetGlobalID());
353  }
354  else
355  {
356  variant->add_proxy_global_id(0);
357  }
358  }
359  for (VectorOfUInts::const_iterator iter = this->Ports.begin(); iter != this->Ports.end();
360  ++iter)
361  {
362  variant->add_port_number(*iter);
363  }
364  return true;
365  }
366 
367  bool ReadFrom(const paraview_protobuf::Variant& variant, vtkSMProxyLocator* locator)
368  {
369  SmartVectorOfProxies proxies;
370  VectorOfUInts ports;
371  assert(variant.proxy_global_id_size() == variant.port_number_size());
372  for (int cc = 0, max = variant.proxy_global_id_size(); cc < max; cc++)
373  {
374  vtkTypeUInt32 gid = variant.proxy_global_id(cc);
375  unsigned int port = variant.port_number(cc);
376 
377  // either ask the locator for the proxy, or find an existing one.
378  vtkSMProxy* proxy = nullptr;
379  if (locator && vtkSMProxyProperty::CanCreateProxy())
380  {
381  proxy = locator->LocateProxy(gid);
382  }
383  else
384  {
385  proxy =
387  }
388  if (proxy != nullptr || gid == 0)
389  {
390  proxies.push_back(proxy);
391  ports.push_back(port);
392  }
393  }
394  return this->SetProxies(proxies, ports);
395  }
396 };
397 #endif
398 // VTK-HeaderTest-Exclude: vtkSMProxyPropertyInternals.h
const VectorOfUInts & GetUncheckedPorts() const
static bool CanCreateProxy()
When we load ProxyManager state we want Proxy/InputProperty to be able to create the corresponding mi...
virtual void AddConsumer(vtkSMProperty *property, vtkSMProxy *proxy)
Called by a proxy property, this adds the property,proxy pair to the list of consumers.
property representing pointer(s) to vtkObject(s)
bool Set(unsigned int index, vtkSMProxy *proxy, unsigned int port=0)
unsigned long AddObserver(unsigned long event, vtkCommand *, float priority=0.0f)
vtkSMProxy * GetUnchecked(unsigned int index) const
void RemoveObserver(unsigned long tag)
const SmartVectorOfProxies & GetProxies() const
virtual vtkSMProxy * LocateProxy(vtkTypeUInt32 globalID)
Locate a proxy with the given "name".
bool ReadFrom(const paraview_protobuf::Variant &variant, vtkSMProxyLocator *locator)
bool SetProxies(const SmartVectorOfProxies &otherProxies, const VectorOfUInts &otherPorts)
bool Set(unsigned int count, vtkSMProxy **proxies, const unsigned int *ports=nullptr)
static vtkSMProxy * SafeDownCast(vtkObject *o)
bool WriteTo(paraview_protobuf::Variant *variant) const
void OnUpdateDataEvent()
Called when a producer fires the vtkCommand::UpdateDataEvent.
This class is used by vtkSMProxyProperty to keep track of the proxies.
bool SetUncheckedProxies(const WeakVectorOfProxies &otherProxies, const VectorOfUInts &otherPorts)
vtkObject * GetRemoteObject(vtkTypeUInt32 globalid)
Return a vtkSMRemoteObject given its global id if any otherwise return nullptr;.
proxy for a VTK object(s) on a server
Definition: vtkSMProxy.h:152
is used to locate proxies referred to in state xmls while loading state files.
bool SetUnchecked(unsigned int index, vtkSMProxy *proxy, unsigned int port=0)
bool Add(vtkSMProxy *proxy, unsigned int port=0)
vtkSMProxy * GetParent()
Get the proxy to which this property belongs.
virtual vtkSMSession * GetSession()
Get/Set the session on wihch this object exists.
bool AddUnchecked(vtkSMProxy *proxy, unsigned int port=0)
unsigned int GetUncheckedPort(unsigned int index) const
port
unsigned int GetPort(unsigned int index) const
const WeakVectorOfProxies & GetUncheckedProxies() const
std::vector< vtkWeakPointer< vtkSMProxy > > WeakVectorOfProxies
std::vector< vtkSmartPointer< vtkSMProxy > > SmartVectorOfProxies
vtkSMProxy * Get(unsigned int index) const
#define max(a, b)