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 <tuple>
31 #include <type_traits>
32 
33 
34 namespace UT { namespace Format { class ArgValue; } }
35 
36 namespace apex
37 {
38 
39 class APEX_Graph;
40 class APEX_Program;
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  myName = C::funcname.c_str();
108  mySignature = makeSignature<Ts...>(C::argnames);
109  UT_Options defaults;
110  defaults.setFromPyDictionary(C::parm_defaults);
111  myDefaults->mergeUtOptions(&defaults, false, true, true, &mySignature);
112  };
113 
115 
116  const UT_StringHolder &getName() const override { return myName; }
117 
118  static constexpr const char *parm_defaults = "";
119 
120  struct RunDataT : C::RunData
121  {
122  };
123  const APEX_TypeDefinitionBase *runDataTypeDef() const override
124  {
125  return findTypeDef<typename C::RunData>();
126  }
128  APEX_Argument *rundata_instance,
129  const APEX_Graph *in_graph,
130  APEX_NodeID for_node,
131  APEX_Program *bind_to) const override
132  {
133  if constexpr (std::is_base_of_v<APEX_RunDataErrorBase, typename C::RunData>)
134  {
135  auto *rd_error_base = static_cast<APEX_RunDataErrorBase *>(
136  castArg<typename C::RunData>(rundata_instance));
137  rd_error_base->initializeFromCompileArguments(in_graph, for_node, bind_to);
138  }
139  }
140 
141  // const APEX_Allocator *allocator() const override { return &myAllocator; };
142 
143  const APEX_Signature &signature() const override { return mySignature; };
144 
146 
147  const Dict &parmDefaults() const override { return myDefaults; }
148 
149  void addSparePort(const UT_StringRef &name="", exint index = -1)
150  {
151  mySignature.addSparePort(name, index);
152  }
153 
154  void execute(APEX_ArgPtrs &arg_ptrs) const override
155  {
156  utZoneScopedN(C::funcname);
157  auto cast_args = castArgs<RunDataT, std::remove_const_t<Ts>...>(arg_ptrs);
158  auto ref_args = makerefs(cast_args);
159 
160  const auto &derived = static_cast<const C &>(*this);
161 
162  std::apply(derived, ref_args);
163  }
164 
165 protected:
167 
168 private:
169  // APEX_Allocator myAllocator;
170  APEX_Signature mySignature;
171  Dict myDefaults;
172 };
173 
175 {
178 
179  APEX_Program *myProgram;
180 };
181 
182 template <typename C, typename... Ts>
184 {
185 public:
187  {
188  myName = C::funcname.c_str();
189  mySignature = makeSignature<Ts...>(C::argnames);
190  };
191 
193 
194  const UT_StringHolder &getName() const override { return myName; }
195 
196  struct RunDataT : C::RunData
197  {
198  };
199 
200  const APEX_TypeDefinitionBase *runDataTypeDef() const override
201  {
202  return findTypeDef<typename C::RunData>();
203  }
205  APEX_Argument *rundata_instance,
206  const APEX_Graph *in_graph,
207  APEX_NodeID for_node,
208  APEX_Program *bind_to) const override
209  {
210  SYS_STATIC_ASSERT(std::is_base_of_v<APEX_Context, typename C::RunData>);
211 
212  static_cast<APEX_Context *>(castArg<typename C::RunData>(rundata_instance))
213  ->myProgram = bind_to;
214  }
215 
216  const APEX_Signature &signature() const override
217  {
218  myFullSignature = mySignature;
219 
220  if (opensScope())
221  myFullSignature.myOutputs.insertAt({scopeConnection(), nullptr}, 0);
222  else if (closesScope())
223  myFullSignature.myInputs.insertAt({scopeConnection(), nullptr}, 0);
224  if (!scopeConnection().isEmpty())
225  {
226  myFullSignature.myInputs.append({theSparePortName.asRef(), nullptr});
227  myFullSignature.myOutputs.append({theSparePortName.asRef(), nullptr});
228  }
229 
230  return myFullSignature;
231  };
232 
233  void execute(APEX_ArgPtrs &arg_ptrs) const override
234  {
235  utZoneScopedN(C::funcname);
236  auto cast_args = castArgs<RunDataT, std::remove_const_t<Ts>...>(arg_ptrs);
237  auto ref_args = makerefs(cast_args);
238 
239  const auto &derived = static_cast<const C &>(*this);
240 
241  std::apply(derived, ref_args);
242  }
243 
244  APEX_CallbackType callbackType() const override = 0;
245 
246  static const UT_StringLit funcname;
247  static const UT_StringArray argnames;
248 
249 protected:
251 
252 private:
253  APEX_Signature mySignature;
254  mutable APEX_Signature myFullSignature;
255 };
256 
257 } // namespace apex
258 
259 #endif // header guard
static const UT_StringArray argnames
Definition: APEX_Generic.h:247
#define SYS_STATIC_ASSERT(expr)
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
auto makerefs(UT_Tuple< T...> &t)
Definition: APEX_Include.h:253
int64 exint
Definition: SYS_Types.h:125
bool closesScope() const
Does this node close a scope?
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:127
APEX_ParmList myInputs
APEX_CallbackType
Definition: APEX_Include.h:224
void execute(APEX_ArgPtrs &arg_ptrs) const override
Definition: APEX_Generic.h:154
const UT_StringHolder & getName() const override
Definition: APEX_Generic.h:194
Format
Definition: oidn.hpp:118
#define utZoneScopedN(name)
Definition: UT_Tracing.h:212
bool setFromPyDictionary(const char *dict)
static constexpr const char * parm_defaults
Definition: APEX_Generic.h:118
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:362
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:204
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:216
SYS_FORCE_INLINE const char * c_str() const
const APEX_TypeDefinitionBase * runDataTypeDef() const override
Definition: APEX_Generic.h:123
GLuint const GLchar * name
Definition: glcorearb.h:786
APEX_Program * myProgram
Definition: APEX_Generic.h:179
const APEX_Signature & signature() const override
Definition: APEX_Generic.h:143
exint append()
Definition: UT_Array.h:142
void addSparePort(const UT_StringRef &name="", exint index=-1)
Definition: APEX_Generic.h:149
APEX_CallbackType callbackType() const override
What kind of function is this? Informs things like scopes & conditions.
Definition: APEX_Generic.h:145
const Dict & parmDefaults() const override
Definition: APEX_Generic.h:147
A map of string to various well defined value types.
Definition: UT_Options.h:84
const APEX_TypeDefinitionBase * runDataTypeDef() const override
Definition: APEX_Generic.h:200
static const UT_StringLit funcname
Definition: APEX_Generic.h:246
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
auto makeSignature(const char *const argnames[sizeof...(Ts)], std::index_sequence< Index...>)
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:116
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:176
const UT_StringHolder & nodePath() const
Definition: APEX_Generic.h:78
UN_NodeID APEX_NodeID
Definition: APEX_Include.h:332
void execute(APEX_ArgPtrs &arg_ptrs) const override
Definition: APEX_Generic.h:233
void addMessage(const char *fmt, const Args &...args) const
Add a string message using format()-style arguments.
Definition: APEX_Generic.h:70
void stealErrors(UT_ErrorManager &err_mgr)
Steal errors from another error manager.
Definition: APEX_Generic.h:82
Do nothing; ignored after compilation.