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_WorkItemTypes.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  /// Shared implementation for ordering work items by their presence or
36  /// absents from a required dependency map
37  static bool prioritize(
38  const PDG_WorkItemIDBoolMap* priority_items,
39  const PDG_WorkItem* lhs,
40  const PDG_WorkItem* rhs,
41  bool reverse,
42  bool& result);
43 
44  /// Base class for comparators
45  template <typename T, bool Reverse, typename... Args>
46  class Comparator : public T
47  {
48  public:
49  Comparator() : T(), myReverse(Reverse), myPriorityItems(nullptr) {}
50  Comparator(bool reverse, Args... args)
51  : T(std::forward<Args>(args)...)
52  , myPriorityItems(nullptr)
53  , myReverse(reverse)
54  {
55  }
56  Comparator(bool reverse,
57  const PDG_WorkItemIDBoolMap* priority_items,
58  Args... args)
59  : T(std::forward<Args>(args)...)
60  , myPriorityItems(priority_items)
61  , myReverse(reverse)
62  {
63  }
64 
65  inline bool operator()(const PDG_WorkItem* lhs,
66  const PDG_WorkItem* rhs) const
67  {
68  if (lhs == rhs)
69  return false;
70  if (!lhs)
71  return myReverse;
72  if (!rhs)
73  return !myReverse;
74 
75  bool result = false;
76  if (prioritize(lhs, rhs, result))
77  return result;
78 
79  return T::compare(*lhs, *rhs) ^ myReverse;
80  }
81 
82  inline bool operator()(const PDG_WorkItem& lhs,
83  const PDG_WorkItem& rhs) const
84  {
85  if (&lhs == &rhs)
86  return false;
87 
88  bool result = false;
89  if (prioritize(&lhs, &rhs, result))
90  return result;
91 
92  return T::compare(lhs, rhs) ^ myReverse;
93  }
94 
95  inline bool prioritize(const PDG_WorkItem* lhs,
96  const PDG_WorkItem* rhs,
97  bool& result) const
98  {
99  return PDG_WorkItemSort::prioritize(
100  myPriorityItems, lhs, rhs, myReverse, result);
101  }
102 
103  private:
104  const PDG_WorkItemIDBoolMap* myPriorityItems;
105  bool myReverse;
106  };
107 
108  class PriorityComparator
109  {
110  public:
111  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
112  };
113 
114  class IndexComparator
115  {
116  public:
117  IndexComparator(const PDG_NodeArray* input_list=nullptr)
118  : myInputs(input_list) {}
119  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
120  private:
121  const PDG_NodeArray* myInputs;
122  };
123 
124  class InputComparator
125  {
126  public:
127  InputComparator(const PDG_NodeArray* input_list=nullptr)
128  : myInputs(input_list) {}
129  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
130 
131  private:
132  const PDG_NodeArray* myInputs;
133  };
134 
135  class AttributeComparator
136  {
137  public:
138  AttributeComparator(const PDG_AttributeEvaluator* evaluator)
139  : myEvaluator(evaluator) {}
140  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
141 
142  private:
143  const PDG_AttributeEvaluator* myEvaluator;
144  };
145 
146  class FrameComparator
147  {
148  public:
149  FrameComparator(const PDG_NodeArray* input_list=nullptr)
150  : myInputs(input_list) {}
151  bool compare(const PDG_WorkItem& lhs, const PDG_WorkItem& rhs) const;
152 
153  private:
154  const PDG_NodeArray* myInputs;
155  };
156 
157 public:
158  /// Functor that compares two work item references or pointers by priority
159  template<bool Reverse=false>
160  using Priority = Comparator<PriorityComparator, Reverse>;
161 
162  /// Functor for comparing work items for sorting by index
163  template<bool Reverse=false>
164  using Index = Comparator<IndexComparator, Reverse>;
165 
166  /// Functor for comparing work items for sorting by index and node.
167  template<bool Reverse=false>
168  using IndexInput =
169  Comparator<IndexComparator, Reverse, const PDG_NodeArray*>;
170 
171  /// Functor for comparing work items for sorting by input number. Fallback
172  /// to index when the input is the same.
173  template<bool Reverse=false>
174  using Input =
175  Comparator<InputComparator, Reverse, const PDG_NodeArray*>;
176 
177  /// Compares work items using an attribute
178  template<bool Reverse=false>
179  using Attribute =
180  Comparator<AttributeComparator, Reverse, const PDG_AttributeEvaluator*>;
181 
182  /// Compars work items using their frame value
183  template<bool Reverse=false>
184  using Frame = Comparator<FrameComparator, Reverse, const PDG_NodeArray*>;
185 
186 public:
187 
188  /// Sorts the work items based on index, in ascending order.
189  template <typename Array>
190  static void sortItems(Array& work_items)
191  {
192  PDG_SortOptions default_options;
193  sortItems(work_items, default_options, nullptr, nullptr);
194  }
195 
196  /// Sorts the work items based on the sort preferences of the specified
197  /// node
198  template <typename Array>
199  static void sortItems(
200  Array& work_items,
201  const PDG_Node* target_node,
202  const PDG_WorkItemIDBoolMap* required_items)
203  {
204  if (!target_node)
205  return;
206 
207  PDG_NodeArray inputs;
208  target_node->connectedNodes(inputs, PDG_PortType::eInput);
209 
210  sortItems(
211  work_items, target_node->sortOptions(), required_items, &inputs);
212  }
213 
214  /// Sorts the work items based on a sort options struct
215  template <typename Array>
216  static void sortItems(
217  Array& work_items,
218  const PDG_SortOptions& sort_options,
219  const PDG_WorkItemIDBoolMap* required_items,
220  const PDG_NodeArray* inputs)
221  {
222  bool reverse = sort_options.myDirection;
223  PDG_WorkItemSortOrder sort_order = sort_options.myOrder;
224  const PDG_WorkItemIDBoolMap* priority_items =
225  sort_options.myRequired ? required_items : nullptr;
226 
227  if (sort_order == PDG_WorkItemSortOrder::eSortIndex)
228  {
229  if (inputs)
230  work_items.sort(IndexInput<>(reverse, priority_items, inputs));
231  else
232  work_items.sort(Index<>(reverse, priority_items));
233  }
234  else if (sort_order == PDG_WorkItemSortOrder::eSortInputOrder)
235  {
236  if (inputs)
237  work_items.sort(Input<>(reverse, priority_items, inputs));
238  else
239  work_items.sort(Index<>(reverse, priority_items));
240  }
241  else if (sort_order == PDG_WorkItemSortOrder::eSortAttribute)
242  {
243  PDG_AttributeEvaluator evaluator(sort_options.myAttribute);
244  work_items.sort(Attribute<>(reverse, priority_items, &evaluator));
245  }
246  else if (sort_order == PDG_WorkItemSortOrder::eSortFrame)
247  {
248  work_items.sort(Frame<>(reverse, priority_items, inputs));
249  }
250  }
251 };
252 
253 #endif /* __PDG_WORKITEM_SORT_H__ */
Definition: ImfArray.h:45
bool myRequired
Sort required items to the beginning of the list.
Comparator< IndexComparator, Reverse > Index
Functor for comparing work items for sorting by index.
static void sortItems(Array &work_items)
Sorts the work items based on index, in ascending order.
Order by a specific attribute value.
Comparator< PriorityComparator, Reverse > Priority
Functor that compares two work item references or pointers by priority.
#define PDG_API
Definition: PDG_API.h:23
void reverse(I begin, I end)
Definition: pugixml.cpp:7190
**But if you need a result
Definition: thread.h:613
Comparator< FrameComparator, Reverse, const PDG_NodeArray * > Frame
Compars work items using their frame value.
PDG_WorkItemSortOrder
Input connection.
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
static void sortItems(Array &work_items, const PDG_SortOptions &sort_options, const PDG_WorkItemIDBoolMap *required_items, const PDG_NodeArray *inputs)
Sorts the work items based on a sort options struct.
const PDG_SortOptions & sortOptions() const
Returns the node's sort options struct.
Definition: PDG_Node.h:185
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.
UT_StringHolder myAttribute
The sort attribute, used when the sort order is SortAttribute.
static void sortItems(Array &work_items, const PDG_Node *target_node, const PDG_WorkItemIDBoolMap *required_items)
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.