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_SchedulerType.h"
19 #include "PDG_ServiceType.h"
20 #include "PDG_Types.h"
21 #include "PDG_WorkItemDataType.h"
22 
23 #include <PDGT/PDGT_TypeRegistry.h>
24 
25 class PDG_NodeInterface;
26 class PDG_Service;
27 
28 #ifdef WIN32
29 /// Explicit instantiate for base type, to avoid linker errors on windows
31 #endif
32 
33 /*
34  * Specializtion of PDGT_TypeRegistry for the various types that can be
35  * registerted and created in PDG
36  */
39 {
40 protected:
42 
43 public:
44  /// Returns the static type registry instance
45  static PDG_TypeRegistry* types();
46 
47  /// Destructor
48  ~PDG_TypeRegistry() override;
49 
50  /// Registers a function-based work item type
51  template <typename ClassType, typename... Args>
53  UT_WorkBuffer& errors,
54  const UT_StringHolder& name,
55  Args&&... args)
56  {
57  return registerSimpleType<PDG_WorkItemDataType, ClassType>(errors, name,
58  std::forward<Args>(args)...);
59  }
60 
61  /// Registers a function-based node type
62  template <typename ClassType, typename... Args>
64  UT_WorkBuffer& errors,
65  const UT_StringHolder& name,
66  Args&&... args)
67  {
68  return registerSimpleType<PDG_NodeCallbackType, ClassType>(errors, name,
69  std::forward<Args>(args)...);
70  }
71 
72  /// Registers a function-based scheduler type
73  template <typename ClassType, typename... Args>
75  UT_WorkBuffer& errors,
76  const UT_StringHolder& name,
77  Args&&... args)
78  {
79  return registerSimpleType<PDG_SchedulerType, ClassType>(errors, name,
80  std::forward<Args>(args)...);
81  }
82 
83  /// Registers a function-based dependency type
84  template <typename ClassType, typename... Args>
86  UT_WorkBuffer& errors,
87  const UT_StringHolder& name,
88  Args&&... args)
89  {
90  return registerSimpleType<PDG_DependencyType, ClassType>(errors, name,
91  std::forward<Args>(args)...);
92  }
93 
94  /// Registers a function-based service type
95  template <typename ClassType, typename... Args>
97  UT_WorkBuffer& errors,
98  const UT_StringHolder& name,
99  Args&&... args)
100  {
101  return registerSimpleType<PDG_ServiceType, ClassType>(errors, name,
102  std::forward<Args>(args)...);
103  }
104 
105  /// Utility method to register a custom C++-based external dependency
106  template <typename ClassType>
108  const UT_StringHolder& name,
109  const UT_StringHolder& label)
110  {
111  UT_WorkBuffer errors;
112  return handleErrors(registerCustomDependency<ClassType>(
113  errors, name, label, PDG_BaseType::eCpp), errors);
114  }
115 
116  /// Utility method to regiser a custom C++-based work item data
117  template <typename ClassType>
119  const UT_StringHolder& name,
120  const UT_StringHolder& label,
121  bool compatible = true,
122  bool make_default = false)
123  {
124  UT_WorkBuffer errors;
125  auto data_type = handleErrors(registerCustomWorkItemData<ClassType>(
126  errors, name, label, PDG_BaseType::eCpp), errors);
127  if (!data_type)
128  return nullptr;
129 
130  if (make_default)
131  setDefaultWorkItemDataType(data_type);
132 
133  if (compatible && myDefaultWorkItemDataType)
134  addParentType(data_type, myDefaultWorkItemDataType, errors);
135 
136  return data_type;
137  }
138 
139  /// Utility method to registers a C++-based scheduler node
140  template <typename ClassType>
142  const UT_StringHolder& name,
143  const UT_StringHolder& label,
144  const UT_StringHolder& parm_category,
145  const UT_StringHolder& node_category)
146  {
147  UT_WorkBuffer errors;
148  return handleErrors(registerCustomScheduler<ClassType>(
149  errors, name, label, parm_category, node_category,
150  PDG_BaseType::eCpp), errors);
151  }
152 
153  /// Utility method to registers a C++-based scheduler node with a
154  /// parm interface
155  template <typename ClassType>
157  const UT_StringHolder& name,
158  const UT_StringHolder& label,
159  const UT_StringHolder& parm_category,
160  const UT_StringHolder& node_category,
161  const PDG_NodeInterface& interface)
162  {
163  UT_WorkBuffer errors;
164  return handleErrors(registerCustomScheduler<ClassType>(
165  errors, name, label, parm_category, node_category,
166  PDG_BaseType::eCpp, interface), errors);
167  }
168 
169  /// Utility method to register a C++-based service using the default
170  /// service class
172  const UT_StringHolder& name,
173  const UT_StringHolder& label,
174  const UT_StringHolder& commandline,
175  bool internal)
176  {
177  UT_WorkBuffer errors;
178  return handleErrors(registerCustomService<PDG_Service>(
179  errors, name, label, PDG_BaseType::eCpp, commandline, internal),
180  errors);
181  }
182 
183  /// Utility method to register a C++-based processor node using defaults
184  /// for various standard node callback fields
185  template <typename ClassType>
187  const UT_StringHolder& name,
188  const UT_StringHolder& label,
189  const UT_StringHolder& category,
190  const PDG_NodeInterface& interface,
192  {
193  UT_WorkBuffer errors;
194  auto* new_type = registerCustomNodeCallback<ClassType>(
195  errors, name, label, category, true, PDG_BaseType::eCpp,
196  interface, PDG_NodeType::eProcessor, sub);
197  if (new_type)
198  new_type->setCallbackBits(PDG_NodeCallback::eProcessorBits);
199  return handleErrors(new_type, errors);
200  }
201 
202  /// Utility method to register a C++-based partitioner node using defaults
203  /// for various standard node callback fields
204  template <typename ClassType>
206  const UT_StringHolder& name,
207  const UT_StringHolder& label,
208  const UT_StringHolder& category,
209  const PDG_NodeInterface& interface,
211  {
212  UT_WorkBuffer errors;
213  auto* new_type = registerCustomNodeCallback<ClassType>(
214  errors, name, label, category, false, PDG_BaseType::eCpp,
215  interface, PDG_NodeType::ePartitioner, sub);
216  if (new_type)
217  new_type->setCallbackBits(PDG_NodeCallback::ePartitionerBits);
218  return handleErrors(new_type, errors);
219  }
220 
221  /// Utility method to register a C++-based mapper node using defaults
222  /// for various standard node callback fields
223  template <typename ClassType>
225  const UT_StringHolder& name,
226  const UT_StringHolder& label,
227  const UT_StringHolder& category,
228  const PDG_NodeInterface& interface)
229  {
230  UT_WorkBuffer errors;
231  auto* new_type = registerCustomNodeCallback<ClassType>(
232  errors, name, label, category, false, PDG_BaseType::eCpp,
234  if (new_type)
235  new_type->setCallbackBits(PDG_NodeCallback::eMapperBits);
236  return handleErrors(new_type, errors);
237  }
238 
239  /// Returns an external dependency type object for a given name
240  PDG_DependencyType* dependencyType(const UT_StringHolder& name) const;
241 
242  /// Retruns a node callback type object for a given name
243  PDG_NodeCallbackType* nodeCallbackType(const UT_StringHolder& name) const;
244 
245  /// Returns a scheduler type object for a give name
246  PDG_SchedulerType* schedulerType(const UT_StringHolder& name) const;
247 
248  /// Returns a service type object for a given name
249  PDG_ServiceType* serviceType(const UT_StringHolder& name) const;
250 
251  /// Returns a work item data type object for a given name
252  PDG_WorkItemDataType* workItemDataType(const UT_StringHolder& name) const;
253 
254  /// Gets/sets the default work item data type
256  { return myDefaultWorkItemDataType; }
258  { myDefaultWorkItemDataType = type; }
259 
260  /// Gets/sets the service scheduler type
262  { return myServiceSchedulerType; }
264  { myServiceSchedulerType = type; }
265 
266  /// Gets/sets the in process scheduler type
268  { return myInProcessSchedulerType; }
270  { myInProcessSchedulerType = type; }
271 
272  /// Returns the name of the local scheduler type
274  {
275  static const UT_StringHolder type_name =
276  "localscheduler";
277  return type_name;
278  }
279 
280  /// Returns the custom handlers table
282  { return &myCustomHandlers;}
283 
284  /// Returns the shared file utilities object
286  { return &myFileUtilities; }
287 
288  /// Returns the name of the module used to serialize and deserialize
289  /// PyObject attributes
290  UT_StringHolder pySerializationModule() const;
291 
292  /// Sets the custom serialization module name
293  void setPySerializationModule(const UT_StringHolder& mod);
294 
295  /// Returns true if the scheduler name is a "local" scheduler, e.g. it does
296  /// not use the farm.
297  static bool isSchedulerLocal(const UT_StringHolder& type_name);
298 
299 private:
300  /// Logs a message with the PDG debug logger
301  void handleLogMessage(
303  const UT_StringHolder& message,
304  const UT_StringHolder& tag) const override;
305 
306  /// Reports errors to stdout, if the type is invalid
307  template <typename Type>
308  Type* handleErrors(
309  Type* new_type,
310  const UT_WorkBuffer& errors) const
311  {
312  if (new_type || errors.isEmpty())
313  return new_type;
314 
315  handleLogMessage(
317  errors.buffer(),
318  "ERROR");
319 
320  return nullptr;
321  }
322 
323 private:
324  PDG_WorkItemDataType* myDefaultWorkItemDataType;
325  PDG_SchedulerType* myServiceSchedulerType;
326  PDG_SchedulerType* myInProcessSchedulerType;
327 
328  PDG_CustomHandlers myCustomHandlers;
329  PDG_FileUtils myFileUtilities;
330  UT_StringHolder myPySerializationModule;
331 };
332 
333 extern "C" {
335 };
336 
337 #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
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
PDG_SchedulerType * inProcessSchedulerType() const
Gets/sets the in process scheduler type.
PDG_NodeSubtype
Enumeration of node subtypes.
Definition: PDG_Types.h:302
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
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)
PDG_RegistrationType
Enumeration of entities that can be registered with PDG_TypeRegistry.
Definition: PDG_Types.h:506
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
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.
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.
A regular node – default value.