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