HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
APEX_Generic.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  * NAME: APEX_Generic.h (APEX Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __APEX_GENERIC_H__
12 #define __APEX_GENERIC_H__
13 
14 #include "APEX_API.h"
15 #include "APEX_Buffer.h"
16 #include "APEX_Callback.h"
17 #include "APEX_Include.h"
18 #include "APEX_Types.h"
19 
20 #include <UT/UT_Debug.h>
21 #include <UT/UT_ErrorManager.h>
22 #include <UT/UT_Options.h>
23 #include <UT/UT_StringArray.h>
24 #include <UT/UT_StringHolder.h>
25 #include <UT/UT_Tracing.h>
26 #include <SYS/SYS_StaticAssert.h>
27 #include <SYS/SYS_Types.h>
28 
29 #include <initializer_list>
30 #include <type_traits>
31 
32 
33 namespace UT { namespace Format { class ArgValue; } }
34 
35 namespace apex
36 {
37 
38 class APEX_Graph;
39 class APEX_Program;
40 class APEX_ProgramCounter;
41 
42 /// APEX callbacks defined using APEX_GenericFunctionRunData whose RunData inherits from this class
43 /// will be automatically provided with a UT_ErrorManager for reporting computation errors.
45 {
46 public:
47  /// Extract the error manager from the program.
48  /// @internal implemented in .C to avoid depending on APEX_Program.h
49  void initializeFromCompileArguments(
50  const APEX_Graph *in_graph,
51  APEX_NodeID for_node,
52  APEX_Program *bind_to);
53 
54  /// Add a string error using format()-style arguments
55  template <typename... Args>
56  void addError(const char *fmt, const Args &...args) const
57  {
58  addError(fmt, {args...});
59  }
60 
61  /// Add a string warning using format()-style arguments
62  template <typename... Args>
63  void addWarning(const char *fmt, const Args &...args) const
64  {
65  addWarning(fmt, {args...});
66  }
67 
68  /// Add a string message using format()-style arguments
69  template <typename... Args>
70  void addMessage(const char *fmt, const Args &...args) const
71  {
72  addMessage(fmt, {args...});
73  }
74 
75  /// Accesssors
76  /// @{
77  const UT_ErrorManager &errorManager() const { return *myErrorManager; }
78  const UT_StringHolder &nodePath() const { return myNodePath; }
79  /// @}
80 
81  /// Steal errors from another error manager
83  {
84  myErrorManager->stealErrors(err_mgr);
85  }
86 
87 private:
88  void addError(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const;
89  void addWarning(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const;
90  void addMessage(const char *fmt, std::initializer_list<UT::Format::ArgValue> args) const;
91 
92 private:
93  /// Error manager to send errors to.
94  UT_ErrorManager *myErrorManager;
95  /// Full path to the node that this callback is implementing (useful for prefixing errors)
96  UT_StringHolder myNodePath;
97  // FIXME: This should also pull out things like the callback name for formatting the errors with
98  // some source information.
99 };
100 
101 template <typename C, typename... Ts>
103 {
104 public:
106  {
107  if constexpr (!std::is_null_pointer_v<decltype(C::argnames)>)
108  {
109  static_assert(
110  sizeof...(Ts) == std::size(C::argnames),
111  "Callback argnames size does not match template argument size");
112  }
113 
114  myName = C::funcname.c_str();
115  mySignature = makeSignature<Ts...>(C::argnames);
116  UT_Options defaults;
117  defaults.setFromPyDictionary(C::parm_defaults);
118  myDefaults->mergeUtOptions(&defaults, false, true, true, &mySignature);
119  }
120 
122 
123  const UT_StringHolder &getName() const override { return myName; }
124 
125  static constexpr const char *parm_defaults = "";
126 
127  struct RunDataT : C::RunData
128  {
129  };
130  const APEX_TypeDefinitionBase *runDataTypeDef() const override
131  {
132  return findTypeDef<typename C::RunData>();
133  }
135  APEX_Argument *rundata_instance,
136  const APEX_Graph *in_graph,
137  APEX_NodeID for_node,
138  APEX_Program *bind_to) const override
139  {
140  if constexpr (std::is_base_of_v<APEX_RunDataErrorBase, typename C::RunData>)
141  {
142  auto *rd_error_base = static_cast<APEX_RunDataErrorBase *>(
143  castArg<typename C::RunData>(rundata_instance));
144  rd_error_base->initializeFromCompileArguments(in_graph, for_node, bind_to);
145  }
146  }
147 
148  // const APEX_Allocator *allocator() const override { return &myAllocator; };
149 
150  const APEX_Signature &signature() const override { return mySignature; };
151 
153 
154  const Dict &parmDefaults() const override { return myDefaults; }
155 
156  void addSparePort(const UT_StringRef &name="", exint index = -1)
157  {
158  mySignature.addSparePort(name, index);
159  }
160 
161  void execute(APEX_ArgPtrs &arg_ptrs) const override
162  {
163  utZoneScopedN(C::funcname);
164 
165  const auto &derived = static_cast<const C &>(*this);
166  applyArgs<C, RunDataT, Ts ...>(derived, arg_ptrs);
167  }
168 
169 protected:
171 
172 private:
173  // APEX_Allocator myAllocator;
174  APEX_Signature mySignature;
175  Dict myDefaults;
176 };
177 
179 {
180  APEX_ProgramCounter *myProgramCounter = nullptr;
181 };
182 
183 template <typename C, typename... Ts>
185 {
186 public:
188  {
189  if constexpr (!std::is_null_pointer_v<decltype(C::argnames)>)
190  {
191  static_assert(
192  sizeof...(Ts) == std::size(C::argnames),
193  "Callback argnames size does not match template argument size");
194  }
195 
196  myName = C::funcname.c_str();
197  mySignature = makeSignature<Ts...>(C::argnames);
198  }
199 
201 
202  void addSparePort(const UT_StringRef &name="", exint index = -1)
203  {
204  mySignature.addSparePort(name, index);
205  }
206 
208  {
209  if (opensScope())
210  mySignature.myOutputs.insertAt({scopeConnection(), nullptr}, 0);
211 
212  if (closesScope())
213  mySignature.myInputs.insertAt({scopeConnection(), nullptr}, 0);
214  }
215 
216  const UT_StringHolder &getName() const override { return myName; }
217 
218  struct RunDataT : C::RunData
219  {
220  };
221 
222  const APEX_TypeDefinitionBase *runDataTypeDef() const override
223  {
224  return findTypeDef<typename C::RunData>();
225  }
226 
228  APEX_Argument *rundata_instance,
229  const APEX_Graph *in_graph,
230  APEX_NodeID for_node,
231  APEX_Program *bind_to) const override
232  {
233  SYS_STATIC_ASSERT(std::is_base_of_v<APEX_Context, typename C::RunData>);
234  }
235 
236  const APEX_Signature &signature() const override { return mySignature; }
237 
238  void execute(APEX_ArgPtrs &arg_ptrs) const override
239  {
240  utZoneScopedN(C::funcname);
241 
242  const auto &derived = static_cast<const C &>(*this);
243  applyArgs<C, RunDataT, Ts...>(derived, arg_ptrs);
244  }
245 
246  APEX_CallbackType callbackType() const override = 0;
247 
248  static const UT_StringLit funcname;
249  static const UT_StringArray argnames;
250 
251 protected:
253 
254 private:
255  APEX_Signature mySignature;
256 };
257 
258 } // namespace apex
259 
260 #endif // header guard
static const UT_StringArray argnames
Definition: APEX_Generic.h:249
APEX_ProgramCounter * myProgramCounter
Definition: APEX_Generic.h:180
#define SYS_STATIC_ASSERT(expr)
constexpr size_t size(const OIIO::span< T, E > &c)
Definition: span.h:381
void addError(const char *fmt, const Args &...args) const
Add a string error using format()-style arguments.
Definition: APEX_Generic.h:56
const UT_ErrorManager & errorManager() const
Definition: APEX_Generic.h:77
bool opensScope() const
Does this node open a scope?
#define APEX_API
Definition: APEX_API.h:21
int64 exint
Definition: SYS_Types.h:125
bool closesScope() const
Does this node close a scope?
void addSparePort(const UT_StringRef &name="", exint index=-1)
Definition: APEX_Generic.h:202
void runDataCompileHook(APEX_Argument *rundata_instance, const APEX_Graph *in_graph, APEX_NodeID for_node, APEX_Program *bind_to) const override
Called for any type with rundata with a reference to the rundata so it can be initialized.
Definition: APEX_Generic.h:134
APEX_ParmList myInputs
APEX_CallbackType
void execute(APEX_ArgPtrs &arg_ptrs) const override
Definition: APEX_Generic.h:161
const UT_StringHolder & getName() const override
Definition: APEX_Generic.h:216
Format
Definition: oidn.hpp:118
#define utZoneScopedN(name)
Definition: UT_Tracing.h:222
bool setFromPyDictionary(const char *dict)
static constexpr const char * parm_defaults
Definition: APEX_Generic.h:125
void initializeFromCompileArguments(const APEX_Graph *in_graph, APEX_NodeID for_node, APEX_Program *bind_to)
APEX_ParmList myOutputs
exint insertAt(const T &t, exint index)
Definition: UT_Array.h:366
void runDataCompileHook(APEX_Argument *rundata_instance, const APEX_Graph *in_graph, APEX_NodeID for_node, APEX_Program *bind_to) const override
Called for any type with rundata with a reference to the rundata so it can be initialized.
Definition: APEX_Generic.h:227
APEX_CallbackType callbackType() const override=0
What kind of function is this? Informs things like scopes & conditions.
const APEX_Signature & signature() const override
Definition: APEX_Generic.h:236
SYS_FORCE_INLINE const char * c_str() const
const APEX_TypeDefinitionBase * runDataTypeDef() const override
Definition: APEX_Generic.h:130
GLuint const GLchar * name
Definition: glcorearb.h:786
const APEX_Signature & signature() const override
Definition: APEX_Generic.h:150
void applyArgs(const C &callback, APEX_ArgPtrs &arg_ptrs, std::index_sequence< Index...>)
void addSparePort(const UT_StringRef &name="", exint index=-1)
Definition: APEX_Generic.h:156
APEX_CallbackType callbackType() const override
What kind of function is this? Informs things like scopes & conditions.
Definition: APEX_Generic.h:152
const Dict & parmDefaults() const override
Definition: APEX_Generic.h:154
A map of string to various well defined value types.
Definition: UT_Options.h:87
const APEX_TypeDefinitionBase * runDataTypeDef() const override
Definition: APEX_Generic.h:222
static const UT_StringLit funcname
Definition: APEX_Generic.h:248
virtual UT_StringHolder scopeConnection() const
Name of the fake wire which is used to denote scope relationships.
GLuint index
Definition: glcorearb.h:786
void addWarning(const char *fmt, const Args &...args) const
Add a string warning using format()-style arguments.
Definition: APEX_Generic.h:63
A global error manager scope.
**If you just want to fire and args
Definition: thread.h:618
const UT_StringHolder & getName() const override
Definition: APEX_Generic.h:123
void addSparePort(const UT_StringRef &name="", exint index=-1)
Represents a location for a single object inside of an APEX_Buffer.
Definition: APEX_Buffer.h:177
const UT_StringHolder & nodePath() const
Definition: APEX_Generic.h:78
UN_NodeID APEX_NodeID
Definition: APEX_Include.h:233
void execute(APEX_ArgPtrs &arg_ptrs) const override
Definition: APEX_Generic.h:238
void addMessage(const char *fmt, const Args &...args) const
Add a string message using format()-style arguments.
Definition: APEX_Generic.h:70
APEX_Signature makeSignature(UT_Span< const char *const, sizeof...(Ts)> argnames, std::index_sequence< Index...>)
void stealErrors(UT_ErrorManager &err_mgr)
Steal errors from another error manager.
Definition: APEX_Generic.h:82
Do nothing; ignored after compilation.