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