Scene Fusion 2 API Reference
ksHierarchyObject.h
1 /*************************************************************************
2  *
3  * KINEMATICOUP CONFIDENTIAL
4  * __________________
5  *
6  * Copyright (2016-2021) KinematicSoup Technologies Incorporated
7  * All Rights Reserved.
8  *
9  * NOTICE: All information contained herein is, and remains
10  * the property of KinematicSoup Technologies Incorporated and its
11  * suppliers, if any. The intellectual and technical concepts contained
12  * herein are proprietary to KinematicSoup Technologies Incorporated
13  * and its suppliers and may be covered by Canadian and Foreign Patents,
14  * patents in process, and are protected by trade secret or copyright law.
15  * Dissemination of this information or reproduction of this material
16  * is strictly forbidden unless prior written permission is obtained
17  * from KinematicSoup Technologies Incorporated.
18  */
19 #pragma once
20 
21 #include <functional>
22 #include <list>
23 #include <memory>
24 #include <stdexcept>
25 #include <stack>
26 
27 namespace KS {
31  template <typename T>
32  class ksHierarchyObject : public std::enable_shared_from_this<T>
33  {
34  public:
41  typedef std::function<bool(std::shared_ptr<T>)> ForEachCallback;
42 
47  {
48  }
49 
54  {
55  }
56 
62  std::shared_ptr<T> Parent()
63  {
64  return m_parentPtr.lock();
65  }
66 
72  const std::list<std::shared_ptr<T>>& Children()
73  {
74  return m_children;
75  }
76 
84  std::shared_ptr<T> Child(size_t index)
85  {
86  if (m_children.size() <= index) {
87  return nullptr;
88  }
89  auto iter = std::next(m_children.begin(), index);
90  return *iter;
91  }
92 
99  int IndexOfChild(std::shared_ptr<T> childPtr)
100  {
101  auto iter = m_children.begin();
102  int index = 0;
103  while (iter != m_children.end()) {
104  if (*iter == childPtr) {
105  return index;
106  }
107  index++;
108  iter++;
109  }
110  return -1;
111  }
112 
116  void Detach()
117  {
118  std::shared_ptr<T> parentPtr = Parent();
119  if (parentPtr != nullptr)
120  {
121  parentPtr->RemoveChild(std::enable_shared_from_this<T>::shared_from_this());
122  }
123  }
124 
131  bool IsDescendantOf(std::shared_ptr<T> objPtr)
132  {
133  if (objPtr == nullptr)
134  {
135  return false;
136  }
137 
138  std::shared_ptr<T> parentPtr = Parent();
139  while (parentPtr != nullptr) {
140  if (objPtr == parentPtr)
141  {
142  return true;
143  }
144  parentPtr = parentPtr->Parent();
145  }
146  return false;
147  }
148 
157  virtual bool AddChild(std::shared_ptr<T> childPtr)
158  {
159  return PerformAddChild(childPtr);
160  }
161 
171  virtual bool InsertChild(int index, std::shared_ptr<T> childPtr)
172  {
173  return PerformInsertChild(index, childPtr);
174  }
175 
182  virtual bool RemoveChild(std::shared_ptr<T> childPtr)
183  {
184  return PerformRemoveChild(childPtr);
185  }
186 
193  {
194  for (auto childPtr : m_children)
195  {
196  if (callback(childPtr))
197  {
198  childPtr->ForEachDescendant(callback);
199  }
200  }
201  }
202 
209  {
210  if (callback(std::enable_shared_from_this<T>::shared_from_this()))
211  {
212  ForEachDescendant(callback);
213  }
214  }
215 
220  template <typename A>
222  {
223  public:
229  AncestorIter(A obj) :
230  m_current{ obj }
231  {
232  }
233 
239  bool Next()
240  {
241  if (m_current != nullptr) {
242  m_current = m_current->Parent();
243  }
244  return (m_current!= nullptr);
245  }
246 
252  bool operator==(const AncestorIter<A>& other) const
253  {
254  return m_current == other.m_current;
255  }
256 
262  bool operator!=(const AncestorIter<A>& other) const
263  {
264  return m_current != other.m_current;
265  }
266 
272  A Value()
273  {
274  return m_current;
275  }
276  private:
277  A m_current;
278  };
279 
286  {
287  return AncestorIter<std::shared_ptr<T>>{ std::enable_shared_from_this<T>::shared_from_this() };
288  }
289 
296  {
297  return AncestorIter<std::shared_ptr<T>>{ m_parentPtr.lock() };
298  }
299 
304  template <typename D>
306  {
307  public:
313  DescendantIter(D obj) :
314  m_current{ obj }
315  {
316  }
317 
323  bool Next()
324  {
325  if (m_current != nullptr) {
326  if (m_current->Children().size() > 0)
327  {
328  typename std::list<D>::const_iterator iter = m_current->Children().cbegin();
329  m_stack.push(std::make_pair(m_current, iter));
330  m_current = *(m_stack.top().second);
331  return m_current != nullptr;
332  }
333  else {
334  while (m_stack.size() > 0) {
335  m_stack.top().second++;
336  if (m_stack.top().second != m_stack.top().first->Children().cend())
337  {
338  m_current = *(m_stack.top().second);
339  return m_current != nullptr;
340  }
341  else {
342  m_stack.pop();
343  }
344  }
345  m_current = nullptr;
346  }
347  }
348  return m_current != nullptr;
349  }
350 
356  bool operator==(const DescendantIter<D>& other) const
357  {
358  return m_current == other.m_current && m_stack == other.m_stack;
359  }
360 
366  bool operator!=(const DescendantIter<D>& other) const
367  {
368  return m_current != other.m_current || m_stack != other.m_stack;
369  }
370 
376  D Value()
377  {
378  return m_current;
379  }
380  private:
381  std::stack<std::pair<D, typename std::list<D>::const_iterator>> m_stack;
382  D m_current;
383  };
384 
391  {
392  return DescendantIter<std::shared_ptr<T>>{ std::enable_shared_from_this<T>::shared_from_this() };
393  }
394 
401  {
402  auto iter = DescendantIter<std::shared_ptr<T>>{ std::enable_shared_from_this<T>::shared_from_this() };
403  iter.Next();
404  return iter;
405  }
406  protected:
407  std::weak_ptr<T> m_parentPtr;
408  std::list<std::shared_ptr<T>> m_children;
409 
417  virtual bool MoveChild(std::shared_ptr<T> childPtr, int newIndex)
418  {
419  if (childPtr == nullptr)
420  {
421  throw std::invalid_argument("Argument null exception");
422  }
423 
424  auto iter = std::find(m_children.begin(), m_children.end(), childPtr);
425  if (iter != m_children.end())
426  {
427  m_children.remove(childPtr);
428  m_children.insert(std::next(m_children.begin(), newIndex), childPtr);
429  return true;
430  }
431  return false;
432  }
433 
445  virtual bool PerformAddChild(std::shared_ptr<T> childPtr)
446  {
447  if (childPtr == nullptr)
448  {
449  throw std::invalid_argument("Argument null exception");
450  }
451 
452  if (childPtr->m_parentPtr.lock() == std::enable_shared_from_this<T>::shared_from_this() ||
453  childPtr == std::enable_shared_from_this<T>::shared_from_this() ||
454  IsDescendantOf(childPtr))
455  {
456  return false;
457  }
458 
459  childPtr->PerformDetach();
460  childPtr->m_parentPtr = std::enable_shared_from_this<T>::shared_from_this();
461  m_children.push_back(childPtr);
462  return true;
463  }
464 
477  virtual bool PerformInsertChild(int index, std::shared_ptr<T> childPtr)
478  {
479  if (childPtr == nullptr)
480  {
481  throw std::invalid_argument("Argument null exception");
482  }
483 
484  if (index > (int)m_children.size() || index < 0 ||
485  childPtr->m_parentPtr.lock() == std::enable_shared_from_this<T>::shared_from_this() ||
486  childPtr == std::enable_shared_from_this<T>::shared_from_this() ||
487  IsDescendantOf(childPtr))
488  {
489  return false;
490  }
491 
492  childPtr->PerformDetach();
493  childPtr->m_parentPtr = std::enable_shared_from_this<T>::shared_from_this();
494  auto iter = std::next(m_children.begin(), index);
495  m_children.insert(iter, childPtr);
496  return true;
497  }
498 
508  virtual bool PerformRemoveChild(std::shared_ptr<T> childPtr)
509  {
510  if (childPtr == nullptr)
511  {
512  throw std::invalid_argument("Argument null exception");
513  }
514 
515  auto iter = std::find(m_children.begin(), m_children.end(), childPtr);
516  if (iter != m_children.end())
517  {
518  m_children.remove(childPtr);
519  childPtr->m_parentPtr.reset();
520  return true;
521  }
522  return false;
523  }
524 
531  {
532  std::shared_ptr<T> parentPtr = Parent();
533  if (parentPtr != nullptr)
534  {
535  std::static_pointer_cast<ksHierarchyObject<T>>(parentPtr)->
536  PerformRemoveChild(std::enable_shared_from_this<T>::shared_from_this());
537  }
538  }
539  };
540 }
Definition: ksHierarchyObject.h:222
AncestorIter(A obj)
Definition: ksHierarchyObject.h:229
bool operator==(const AncestorIter< A > &other) const
Definition: ksHierarchyObject.h:252
bool Next()
Definition: ksHierarchyObject.h:239
A Value()
Definition: ksHierarchyObject.h:272
bool operator!=(const AncestorIter< A > &other) const
Definition: ksHierarchyObject.h:262
Definition: ksHierarchyObject.h:306
DescendantIter(D obj)
Definition: ksHierarchyObject.h:313
D Value()
Definition: ksHierarchyObject.h:376
bool operator!=(const DescendantIter< D > &other) const
Definition: ksHierarchyObject.h:366
bool Next()
Definition: ksHierarchyObject.h:323
bool operator==(const DescendantIter< D > &other) const
Definition: ksHierarchyObject.h:356
Definition: ksHierarchyObject.h:33
AncestorIter< std::shared_ptr< T > > Ancestors()
Definition: ksHierarchyObject.h:295
ksHierarchyObject()
Definition: ksHierarchyObject.h:46
virtual ~ksHierarchyObject()
Definition: ksHierarchyObject.h:53
virtual bool PerformAddChild(std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:445
virtual bool PerformRemoveChild(std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:508
bool IsDescendantOf(std::shared_ptr< T > objPtr)
Definition: ksHierarchyObject.h:131
const std::list< std::shared_ptr< T > > & Children()
Definition: ksHierarchyObject.h:72
void PerformDetach()
Definition: ksHierarchyObject.h:530
virtual bool MoveChild(std::shared_ptr< T > childPtr, int newIndex)
Definition: ksHierarchyObject.h:417
virtual bool RemoveChild(std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:182
int IndexOfChild(std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:99
DescendantIter< std::shared_ptr< T > > SelfAndDescendants()
Definition: ksHierarchyObject.h:390
void Detach()
Definition: ksHierarchyObject.h:116
void ForEachDescendant(ForEachCallback callback)
Definition: ksHierarchyObject.h:192
virtual bool PerformInsertChild(int index, std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:477
virtual bool AddChild(std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:157
void ForSelfAndDescendants(ForEachCallback callback)
Definition: ksHierarchyObject.h:208
virtual bool InsertChild(int index, std::shared_ptr< T > childPtr)
Definition: ksHierarchyObject.h:171
std::function< bool(std::shared_ptr< T >)> ForEachCallback
Definition: ksHierarchyObject.h:41
std::shared_ptr< T > Parent()
Definition: ksHierarchyObject.h:62
DescendantIter< std::shared_ptr< T > > Descendants()
Definition: ksHierarchyObject.h:400
std::shared_ptr< T > Child(size_t index)
Definition: ksHierarchyObject.h:84
AncestorIter< std::shared_ptr< T > > SelfAndAncestors()
Definition: ksHierarchyObject.h:285
Definition: sfDictionaryProperty.h:24