HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_TypeRegistry.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_TYPE_REGISTRY_H__
10 #define __PDG_TYPE_REGISTRY_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_CustomHandlers.h"
15 #include "PDG_DependencyType.h"
16 #include "PDG_FileUtils.h"
17 #include "PDG_NodeCallbackType.h"
18 #include "PDG_RegisteredType.h"
19 #include "PDG_SchedulerType.h"
20 #include "PDG_ServiceType.h"
21 #include "PDG_WorkItemDataType.h"
22 
23 #include <PDGT/PDGT_TypeRegistry.h>
24 
25 class PDG_NodeInterface;
26 class PDG_Service;
27 
28 /*
29  * Specializtion of PDGT_TypeRegistry for the various types that can be
30  * registerted and created in PDG
31  */
32 class PDG_API PDG_TypeRegistry : public PDGT_TypeRegistry<PDG_RegistrationType,
33  (int)PDG_RegistrationType::eCount>
34 {
35 protected:
37 
38 public:
39  /// Returns the static type registry instance
40  static PDG_TypeRegistry* types();
41 
42  /// Destructor
43  ~PDG_TypeRegistry() override;
44 
45  /// Registers a function-based work item type
46  template <typename ClassType, typename... Args>
48  UT_WorkBuffer& errors,
49  const UT_StringHolder& name,
50  Args&&... args)
51  {
52  return registerSimpleType<PDG_WorkItemDataType, ClassType>(errors, name,
53  std::forward<Args>(args)...);
54  }
55 
56  /// Registers a function-based node type
57  template <typename ClassType, typename... Args>
59  UT_WorkBuffer& errors,
60  const UT_StringHolder& name,
61  Args&&... args)
62  {
63  return registerSimpleType<PDG_NodeCallbackType, ClassType>(errors, name,
64  std::forward<Args>(args)...);
65  }
66 
67  /// Registers a function-based scheduler type
68  template <typename ClassType, typename... Args>
70  UT_WorkBuffer& errors,
71  const UT_StringHolder& name,
72  Args&&... args)
73  {
74  return registerSimpleType<PDG_SchedulerType, ClassType>(errors, name,
75  std::forward<Args>(args)...);
76  }
77 
78  /// Registers a function-based dependency type
79  template <typename ClassType, typename... Args>
81  UT_WorkBuffer& errors,
82  const UT_StringHolder& name,
83  Args&&... args)
84  {
85  return registerSimpleType<PDG_DependencyType, ClassType>(errors, name,
86  std::forward<Args>(args)...);
87  }
88 
89  /// Registers a function-based service type
90  template <typename ClassType, typename... Args>
92  UT_WorkBuffer& errors,
93  const UT_StringHolder& name,
94  Args&&... args)
95  {
96  return registerSimpleType<PDG_ServiceType, ClassType>(errors, name,
97  std::forward<Args>(args)...);
98  }
99 
100  /// Utility method to register a custom C++-based external dependency
101  template <typename ClassType>
103  const UT_StringHolder& name,
104  const UT_StringHolder& label)
105  {
106  UT_WorkBuffer errors;
107  return handleErrors(registerCustomDependency<ClassType>(
108  errors, name, label, PDG_BaseType::eCpp), errors);
109  }
110 
111  /// Utility method to regiser a custom C++-based work item data
112  template <typename ClassType>
114  const UT_StringHolder& name,
115  const UT_StringHolder& label,
116  bool compatible = true,
117  bool make_default = false)
118  {
119  UT_WorkBuffer errors;
120  auto data_type = handleErrors(registerCustomWorkItemData<ClassType>(
121  errors, name, label, PDG_BaseType::eCpp), errors);
122  if (!data_type)
123  return nullptr;
124 
125  if (make_default)
126  setDefaultWorkItemDataType(data_type);
127 
128  if (compatible && myDefaultWorkItemDataType)
129  addParentType(data_type, myDefaultWorkItemDataType, errors);
130 
131  return data_type;
132  }
133 
134  /// Utility method to registers a C++-based scheduler node
135  template <typename ClassType>
137  const UT_StringHolder& name,
138  const UT_StringHolder& label,
139  const UT_StringHolder& parm_category,
140  const UT_StringHolder& node_category)
141  {
142  UT_WorkBuffer errors;
143  return handleErrors(registerCustomScheduler<ClassType>(
144  errors, name, label, parm_category, node_category,
145  PDG_BaseType::eCpp), errors);
146  }
147 
148  /// Utility method to registers a C++-based scheduler node with a
149  /// parm interface
150  template <typename ClassType>
152  const UT_StringHolder& name,
153  const UT_StringHolder& label,
154  const UT_StringHolder& parm_category,
155  const UT_StringHolder& node_category,
156  const PDG_NodeInterface& interface)
157  {
158  UT_WorkBuffer errors;
159  return handleErrors(registerCustomScheduler<ClassType>(
160  errors, name, label, parm_category, node_category,
161  PDG_BaseType::eCpp, interface), errors);
162  }
163 
164  /// Utility method to register a C++-based service using the default
165  /// service class
167  const UT_StringHolder& name,
168  const UT_StringHolder& label,
169  const UT_StringHolder& commandline,
170  bool internal)
171  {
172  UT_WorkBuffer errors;
173  return handleErrors(registerCustomService<PDG_Service>(
174  errors, name, label, PDG_BaseType::eCpp, commandline, internal),
175  errors);
176  }
177 
178  /// Utility method to register a C++-based processor node using defaults
179  /// for various standard node callback fields
180  template <typename ClassType>
182  const UT_StringHolder& name,
183  const UT_StringHolder& label,
184  const UT_StringHolder& category,
185  const PDG_NodeInterface& interface,
187  {
188  UT_WorkBuffer errors;
189  auto* new_type = registerCustomNodeCallback<ClassType>(
190  errors, name, label, category, true, PDG_BaseType::eCpp,
191  interface, PDG_NodeType::eProcessor, sub);
192  if (new_type)
193  new_type->setCallbackBits(PDG_NodeCallback::eProcessorBits);
194  return handleErrors(new_type, errors);
195  }
196 
197  /// Utility method to register a C++-based partitioner node using defaults
198  /// for various standard node callback fields
199  template <typename ClassType>
201  const UT_StringHolder& name,
202  const UT_StringHolder& label,
203  const UT_StringHolder& category,
204  const PDG_NodeInterface& interface,
206  {
207  UT_WorkBuffer errors;
208  auto* new_type = registerCustomNodeCallback<ClassType>(
209  errors, name, label, category, false, PDG_BaseType::eCpp,
210  interface, PDG_NodeType::ePartitioner, sub);
211  if (new_type)
212  new_type->setCallbackBits(PDG_NodeCallback::ePartitionerBits);
213  return handleErrors(new_type, errors);
214  }
215 
216  /// Utility method to register a C++-based mapper node using defaults
217  /// for various standard node callback fields
218  template <typename ClassType>
220  const UT_StringHolder& name,
221  const UT_StringHolder& label,
222  const UT_StringHolder& category,
223  const PDG_NodeInterface& interface)
224  {
225  UT_WorkBuffer errors;
226  auto* new_type = registerCustomNodeCallback<ClassType>(
227  errors, name, label, category, false, PDG_BaseType::eCpp,
229  if (new_type)
230  new_type->setCallbackBits(PDG_NodeCallback::eMapperBits);
231  return handleErrors(new_type, errors);
232  }
233 
234  /// Returns an external dependency type object for a given name
235  PDG_DependencyType* dependencyType(const UT_StringHolder& name) const;
236 
237  /// Retruns a node callback type object for a given name
238  PDG_NodeCallbackType* nodeCallbackType(const UT_StringHolder& name) const;
239 
240  /// Returns a scheduler type object for a give name
241  PDG_SchedulerType* schedulerType(const UT_StringHolder& name) const;
242 
243  /// Returns a service type object for a given name
244  PDG_ServiceType* serviceType(const UT_StringHolder& name) const;
245 
246  /// Returns a work item data type object for a given name
247  PDG_WorkItemDataType* workItemDataType(const UT_StringHolder& name) const;
248 
249  /// Gets/sets the default work item data type
251  { return myDefaultWorkItemDataType; }
253  { myDefaultWorkItemDataType = type; }
254 
255  /// Gets/sets the service scheduler type
257  { return myServiceSchedulerType; }
259  { myServiceSchedulerType = type; }
260 
261  /// Gets/sets the in process scheduler type
263  { return myInProcessSchedulerType; }
265  { myInProcessSchedulerType = type; }
266 
267  /// Returns the name of the local scheduler type
269  {
270  static const UT_StringHolder type_name =
271  "localscheduler";
272  return type_name;
273  }
274 
275  /// Returns the custom handlers table
277  { return &myCustomHandlers;}
278 
279  /// Returns the shared file utilities object
281  { return &myFileUtilities; }
282 
283  /// Returns the name of the module used to serialize and deserialize
284  /// PyObject attributes
285  UT_StringHolder pySerializationModule() const;
286 
287  /// Sets the custom serialization module name
288  void setPySerializationModule(const UT_StringHolder& mod);
289 
290  /// Returns true if the scheduler name is a "local" scheduler, e.g. it does
291  /// not use the farm.
292  static bool isSchedulerLocal(const UT_StringHolder& type_name);
293 
294 private:
295  /// Logs a message with the PDG debug logger
296  void handleLogMessage(
298  const UT_StringHolder& message,
299  const UT_StringHolder& tag) const override;
300 
301  /// Reports errors to stdout, if the type is invalid
302  template <typename Type>
303  Type* handleErrors(
304  Type* new_type,
305  const UT_WorkBuffer& errors) const
306  {
307  if (new_type || errors.isEmpty())
308  return new_type;
309 
310  handleLogMessage(
312  errors.buffer(),
313  "ERROR");
314 
315  return nullptr;
316  }
317 
318 private:
319  PDG_WorkItemDataType* myDefaultWorkItemDataType;
320  PDG_SchedulerType* myServiceSchedulerType;
321  PDG_SchedulerType* myInProcessSchedulerType;
322 
323  PDG_CustomHandlers myCustomHandlers;
324  PDG_FileUtils myFileUtilities;
325  UT_StringHolder myPySerializationModule;
326 };
327 
328 extern "C" {
330 };
331 
332 #endif
PDG_DependencyType * registerDependency(const UT_StringHolder &name, const UT_StringHolder &label)
Utility method to register a custom C++-based external dependency.
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
PDG_SchedulerType * inProcessSchedulerType() const
Gets/sets the in process scheduler type.
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
PDG_NodeCallbackType * registerMapper(const UT_StringHolder &name, const UT_StringHolder &label, const UT_StringHolder &category, const PDG_NodeInterface &interface)
void setDefaultWorkItemDataType(PDG_WorkItemDataType *type)
#define SYS_VISIBILITY_EXPORT
PDG_SchedulerType * serviceSchedulerType() const
Gets/sets the service scheduler type.
#define PDG_API
Definition: PDG_API.h:23
GLint level
Definition: glcorearb.h:108
SYS_FORCE_INLINE const char * buffer() const
PDG_FileUtils * fileUtils()
Returns the shared file utilities object.
PDGT_TypeErrorLevel
Error level typedef.
Definition: PDGT_Types.h:13
A regular node – default value.
PDG_WorkItemDataType * defaultWorkItemDataType() const
Gets/sets the default work item data type.
PDG_NodeCallbackType * registerPartitioner(const UT_StringHolder &name, const UT_StringHolder &label, const UT_StringHolder &category, const PDG_NodeInterface &interface, PDG_NodeSubtype sub=PDG_NodeSubtype::eRegular)
ImageBuf OIIO_API sub(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
PDG_SchedulerType * registerScheduler(const UT_StringHolder &name, const UT_StringHolder &label, const UT_StringHolder &parm_category, const UT_StringHolder &node_category, const PDG_NodeInterface &interface)
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: CLI11.h:1729
void setServiceSchedulerType(PDG_SchedulerType *type)
SYS_FORCE_INLINE bool isEmpty() const
bool addParentType(BaseType *type, BaseType *parent, UT_WorkBuffer &errors)
Directly adds a parent type, if it's valid.
PDG_ServiceType * registerCustomService(UT_WorkBuffer &errors, const UT_StringHolder &name, Args &&...args)
Registers a function-based service type.
GLuint const GLchar * name
Definition: glcorearb.h:786
PDG_DependencyType * registerCustomDependency(UT_WorkBuffer &errors, const UT_StringHolder &name, Args &&...args)
Registers a function-based dependency type.
PDG_NodeCallbackType * registerProcessor(const UT_StringHolder &name, const UT_StringHolder &label, const UT_StringHolder &category, const PDG_NodeInterface &interface, PDG_NodeSubtype sub=PDG_NodeSubtype::eRegular)
PDG_NodeCallbackType * registerCustomNodeCallback(UT_WorkBuffer &errors, const UT_StringHolder &name, Args &&...args)
Registers a function-based node type.
PDG_CustomHandlers * customHandlers()
Returns the custom handlers table.
PDG_SchedulerType * registerCustomScheduler(UT_WorkBuffer &errors, const UT_StringHolder &name, Args &&...args)
Registers a function-based scheduler type.
PDG_SchedulerType * registerScheduler(const UT_StringHolder &name, const UT_StringHolder &label, const UT_StringHolder &parm_category, const UT_StringHolder &node_category)
Utility method to registers a C++-based scheduler node.
void setInProcessSchedulerType(PDG_SchedulerType *type)
const UT_StringHolder & localSchedulerTypeName() const
Returns the name of the local scheduler type.
**If you just want to fire and args
Definition: thread.h:609
PDG_WorkItemDataType * registerCustomWorkItemData(UT_WorkBuffer &errors, const UT_StringHolder &name, Args &&...args)
Registers a function-based work item type.
PDG_NodeSubtype
Enumeration of node subtypes.
GLsizei GLenum GLenum * types
Definition: glcorearb.h:2542
PDG_WorkItemDataType * registerWorkItemData(const UT_StringHolder &name, const UT_StringHolder &label, bool compatible=true, bool make_default=false)
Utility method to regiser a custom C++-based work item data.
PDG_ServiceType * registerService(const UT_StringHolder &name, const UT_StringHolder &label, const UT_StringHolder &commandline, bool internal)
type
Definition: core.h:1059
SYS_VISIBILITY_EXPORT void registerPDGTypes(PDG_TypeRegistry *)
Errors are only logged if a type fails to load.