HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_WorkItemSort.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * COMMENTS:
7  */
8 
9 #ifndef __PDG_WORKITEM_SORT_H__
10 #define __PDG_WORKITEM_SORT_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_AttributeEvaluator.h"
15 #include "PDG_Node.h"
16 #include "PDG_SortOptions.h"
17 #include "PDG_Types.h"
18 
19 class PDG_WorkItem;
20 
21 /**
22  * Utility functors for sorting work items. All functors can be used for both
23  * ascending or descending order, as determined by the "reverse" parameter
24  * passed during construction. They default to ascending order for compatibility
25  * with the standard C++ std::sort/less-than comparator.
26  *
27  * It is also possible to statically create a reversed comparator using the
28  * reverse template argument. This is useful when defining datastructures that
29  * need to use one of the comparators as a template argument for ordering, e.g.
30  * a Priority Queue.
31  */
33 {
34 private:
35  /// Base class for comparators
36  template <typename T, bool Reverse, typename... Args>
37  class Comparator : public T
38  {
39  public:
40  Comparator() : T(), myReverse(Reverse), myPriorityItems(nullptr) {}
41  Comparator(bool reverse, Args... args)
42  : T(std::forward<Args>(args)...)
43  , myPriorityItems(nullptr)
44  , myReverse(reverse)
45  {
46  }
47  Comparator(bool reverse,
48  const PDG_WorkItemConstBoolMap* priority_items,
49  Args... args)
50  : T(std::forward<Args>(args)...)
51  , myPriorityItems(priority_items)
52  , myReverse(reverse)
53  {
54  }
55 
56  inline bool operator()(const PDG_WorkItem* lhs,
57  const PDG_WorkItem* rhs) const
58  {
59  if (lhs == rhs)
60  return false;
61  if (!lhs)
62  return myReverse;
63  if (!rhs)
64  return !myReverse;
65 
66  bool result = false;
67  if (prioritize(lhs, rhs, result))
68  return result;
69 
70  return T::compare(*lhs, *rhs) ^ myReverse;
71  }
72 
73  inline bool operator()(const PDG_WorkItem& lhs,
74  const PDG_WorkItem& rhs) const
75  {
76  if (&lhs == &rhs)
77  return false;
78 
79  bool result = false;
80  if (prioritize(&lhs, &rhs, result))
81  return result;
82 
83  return T::compare(lhs, rhs) ^ myReverse;
84  }
85 
86  inline bool prioritize(const PDG_WorkItem* lhs,
87  const PDG_WorkItem* rhs,
88  bool& result) const
89  {
90  if (!myPriorityItems || myPriorityItems->empty())
91  return false;
92 
93  auto&& left = myPriorityItems->find(SYSconst_cast(lhs));
94  auto&& right = myPriorityItems->find(SYSconst_cast(rhs));
95 
96  if (right == myPriorityItems->end())
97  {
98  if (left == myPriorityItems->end())
99  return false;
100 
101  result = !myReverse;
102  return true;
103  }
104  else if (left == myPriorityItems->end())
105  {
106  result = myReverse;
107  return true;
108  }
109 
110  if (left->second == right->second)
111  return false;
112  if (left->second)
113  result = !myReverse;
114  else
115  result = myReverse;
116 
117  return true;
118  }
119 
120  private:
121  const PDG_WorkItemConstBoolMap* myPriorityItems;
122  bool myReverse;
123  };
124 
125  class PriorityComparator
126  {
127  public:
128  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
129  };
130 
131  class IndexComparator
132  {
133  public:
134  IndexComparator(const PDG_NodeArray* input_list=nullptr)
135  : myInputs(input_list) {}
136  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
137  private:
138  const PDG_NodeArray* myInputs;
139  };
140 
141  class InputComparator
142  {
143  public:
144  InputComparator(const PDG_NodeArray* input_list=nullptr)
145  : myInputs(input_list) {}
146  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
147 
148  private:
149  const PDG_NodeArray* myInputs;
150  };
151 
152  class AttributeComparator
153  {
154  public:
155  AttributeComparator(const PDG_AttributeEvaluator* evaluator)
156  : myEvaluator(evaluator) {}
157  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
158 
159  private:
160  const PDG_AttributeEvaluator* myEvaluator;
161  };
162 
163  class FrameComparator
164  {
165  public:
166  FrameComparator(const PDG_NodeArray* input_list=nullptr)
167  : myInputs(input_list) {}
168  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
169 
170  private:
171  const PDG_NodeArray* myInputs;
172  };
173 
174 public:
175  /// Functor that compares two work item references or pointers by priority
176  template<bool Reverse=false>
177  using Priority = Comparator<PriorityComparator, Reverse>;
178 
179  /// Functor for comparing work items for sorting by index
180  template<bool Reverse=false>
181  using Index = Comparator<IndexComparator, Reverse>;
182 
183  /// Functor for comparing work items for sorting by index and node.
184  template<bool Reverse=false>
185  using IndexInput =
186  Comparator<IndexComparator, Reverse, const PDG_NodeArray*>;
187 
188  /// Functor for comparing work items for sorting by input number. Fallback
189  /// to index when the input is the same.
190  template<bool Reverse=false>
191  using Input =
192  Comparator<InputComparator, Reverse, const PDG_NodeArray*>;
193 
194  /// Compares work items using an attribute
195  template<bool Reverse=false>
196  using Attribute =
197  Comparator<AttributeComparator, Reverse, const PDG_AttributeEvaluator*>;
198 
199  /// Compars work items using their frame value
200  template<bool Reverse=false>
201  using Frame = Comparator<FrameComparator, Reverse, const PDG_NodeArray*>;
202 
203 public:
204 
205  /// Sorts the work items based on index, in ascending order.
206  template <typename Array>
207  static void sortItems(Array& work_items)
208  {
209  PDG_SortOptions default_options;
210  sortItems(work_items, default_options, nullptr, nullptr);
211  }
212 
213  /// Sorts the work items based on the sort preferences of the specified
214  /// node
215  template <typename Array>
216  static void sortItems(
217  Array& work_items,
218  const PDG_Node* target_node,
219  const PDG_WorkItemConstBoolMap* required_items)
220  {
221  if (!target_node)
222  return;
223 
224  PDG_NodeArray inputs;
225  target_node->connectedNodes(inputs, PDG_PortType::eInput);
226 
227  sortItems(
228  work_items, target_node->sortOptions(), required_items, &inputs);
229  }
230 
231  /// Sorts the work items based on a sort options struct
232  template <typename Array>
233  static void sortItems(
234  Array& work_items,
235  const PDG_SortOptions& sort_options,
236  const PDG_WorkItemConstBoolMap* required_items,
237  const PDG_NodeArray* inputs)
238  {
239  bool reverse = sort_options.myDirection;
240  PDG_WorkItemSortOrder sort_order = sort_options.myOrder;
241  const PDG_WorkItemConstBoolMap* priority_items =
242  sort_options.myRequired ? required_items : nullptr;
243 
244  if (sort_order == PDG_WorkItemSortOrder::eSortIndex)
245  {
246  if (inputs)
247  work_items.sort(IndexInput<>(reverse, priority_items, inputs));
248  else
249  work_items.sort(Index<>(reverse, priority_items));
250  }
251  else if (sort_order == PDG_WorkItemSortOrder::eSortInputOrder)
252  {
253  if (inputs)
254  work_items.sort(Input<>(reverse, priority_items, inputs));
255  else
256  work_items.sort(Index<>(reverse, priority_items));
257  }
258  else if (sort_order == PDG_WorkItemSortOrder::eSortAttribute)
259  {
260  PDG_AttributeEvaluator evaluator(sort_options.myAttribute);
261  work_items.sort(Attribute<>(reverse, priority_items, &evaluator));
262  }
263  else if (sort_order == PDG_WorkItemSortOrder::eSortFrame)
264  {
265  work_items.sort(Frame<>(reverse, priority_items, inputs));
266  }
267  }
268 };
269 
270 #endif /* __PDG_WORKITEM_SORT_H__ */
Definition: ImfArray.h:47
static void sortItems(Array &work_items, const PDG_Node *target_node, const PDG_WorkItemConstBoolMap *required_items)
bool myRequired
Sort required items to the beginning of the list.
Comparator< IndexComparator, Reverse > Index
Functor for comparing work items for sorting by index.
GLint left
Definition: glcorearb.h:2005
static void sortItems(Array &work_items)
Sorts the work items based on index, in ascending order.
Comparator< PriorityComparator, Reverse > Priority
Functor that compares two work item references or pointers by priority.
#define PDG_API
Definition: PDG_API.h:23
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:136
GLdouble right
Definition: glad.h:2817
void reverse(I begin, I end)
Definition: pugixml.cpp:7190
Order by a specific attribute value.
**But if you need a result
Definition: thread.h:613
Comparator< FrameComparator, Reverse, const PDG_NodeArray * > Frame
Compars work items using their frame value.
Comparator< InputComparator, Reverse, const PDG_NodeArray * > Input
Comparator< AttributeComparator, Reverse, const PDG_AttributeEvaluator * > Attribute
Compares work items using an attribute.
Comparator< IndexComparator, Reverse, const PDG_NodeArray * > IndexInput
Functor for comparing work items for sorting by index and node.
void connectedNodes(PDG_NodeArray &nodes, PDG_PortType type, bool filter_bypassed=true, bool filter_reference=true) const
const PDG_SortOptions & sortOptions() const
Returns the node's sort options struct.
Definition: PDG_Node.h:159
PDG_WorkItemSortOrder
Definition: PDG_Types.h:394
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, ROI roi={}, int nthreads=0)
PDG_WorkItemSortOrder myOrder
The type of sort to use for work items.
Input connection.
UT_StringHolder myAttribute
The sort attribute, used when the sort order is SortAttribute.
static void sortItems(Array &work_items, const PDG_SortOptions &sort_options, const PDG_WorkItemConstBoolMap *required_items, const PDG_NodeArray *inputs)
Sorts the work items based on a sort options struct.
Order by the work item's frame value.
**If you just want to fire and args
Definition: thread.h:609
bool myDirection
Sort ascending or descending.