HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PY_Callback.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  * Instances of this class hold a Python callback (any callable Python
8  * object). You can invoke this callback with the call() method, passing
9  * it optional arguments. When this object is destroyed, the reference
10  * count on the Python callback will be decremented.
11  */
12 
13 #ifndef __PY_Callback_h__
14 #define __PY_Callback_h__
15 
16 #include "PY_API.h"
17 #include "PY_CompiledCode.h"
18 #include "PY_CPythonAPI.h"
19 #include "PY_InterpreterAutoLock.h"
20 #include "PY_EvaluationContext.h"
21 #include "PY_OpaqueObject.h"
22 #include "PY_Result.h"
23 #include "PY_Kwargs.h"
24 
25 #include <UT/UT_StringHolder.h>
26 #include <UT/UT_StringMap.h>
27 #include <UT/UT_UniquePtr.h>
28 
29 class BM_View;
30 class FUSE_Office;
31 class OP_Node;
32 
33 // A cache to avoid recompiling PY_CompiledCode.
35 {
36 public:
37  PY_CallbackCompiledCodeCache(exint cache_size=100);
39 
40  PY_CompiledCode *compile(const UT_StringHolder &code);
41 
44 
46 };
47 
48 // Interface class implemented in HOMUI/HOMF which allows allows code in low
49 // level libraries such as PY and BM to create HOM wrapper instances.
50 // This can be used to avoid generating code that has a pointer as an int64 in
51 // its python code string.
53 {
54 public:
55  virtual ~PY_CallbackHOM(){}
56 
57  virtual bool getDesktopOffice(const BM_View& v, int &desktop_id, int &office_id) = 0;
58  virtual FUSE_Office *getOffice(const BM_View& v) = 0;
59 
60  virtual PY_PyObject *newNode(OP_Node &node) = 0;
61  virtual PY_PyObject *newSceneViewer(FUSE_Office &office, bool convert_context_viewer=false) = 0;
62  virtual PY_PyObject *newViewerStateContext(int64 val) = 0;
63  virtual PY_PyObject *newUIEvent(int64 val) = 0;
64  virtual PY_PyObject *newViewerEvent(int desktop, int office, int64 val) = 0;
65 };
66 
68 {
69 public:
70  using ArgHandler = std::function<void (PY_PyObject* args, PY_PyObject* kwargs)>;
71 
72  // Construct instances of this class with an opaque PY_PyObject
73  // containing a callable Python object.
74  PY_Callback(void *python_callable_object)
75  : PY_OpaqueObject(python_callable_object)
76  , myExpressionCache(nullptr)
77  {}
78 
79  PY_Callback(const PY_Callback &callback)
80  : PY_OpaqueObject(callback)
81  , myExpressionCache(nullptr)
82  {}
83 
84  PY_Callback &operator=(const PY_Callback &callback)
85  { return (PY_Callback &)PY_OpaqueObject::operator=(callback); }
86 
87  // Given two strings containing Python expressions (one that evaluates to
88  // a tuple of arguments and another that evaluates to a dictionary of
89  // keyword arguments), call the callback. Either or both of the argument
90  // tuple and keyword argument dictionary may be null. The result is
91  // returned in the PY_Result object.
92  void call(PY_Result &result, const char *args_expression=NULL,
93  const char *kwargs_expression=NULL) const;
94 
95  // This convenience version of call() returns the PY_Result by value,
96  // instead of passing it in by reference. This versions can be used by
97  // code that isn't performance-critical.
98  PY_Result call(const char *args_expression=NULL,
99  const char *kwargs_expression=NULL) const
100  {
102  call(result, args_expression, kwargs_expression);
103  return result;
104  }
105 
106  // For callbacks returning values
107  PY_Result call(
108  const char *args_expression,
109  const char *kwargs_expression,
110  PY_Result::Type desired_result_type ) const;
111 
112  // Similar to the above methods but take a lambda function to add elements to
113  // the evaluated expressions before firing the callback. Also takes a module name
114  // to evaluate the expressions, the module is optional and can be set to nullptr if
115  // not required.
116  //
118  const char* args_expression,
119  const char* kwargs_expression,
120  const char* module_name,
121  PY_Result::Type desired_result_type,
122  PY_PyObject*& out_args,
123  PY_PyObject*& out_kwargs,
124  ArgHandler arg_handler ) const
125  {
126  PY_InterpreterAutoLock auto_lock;
127 
128  PY_Result result = evaluateArgs(
129  args_expression, kwargs_expression, module_name, out_args, out_kwargs, arg_handler);
130  if (result.myResultType == PY_Result::ERR)
131  {
132  return result;
133  }
134 
135  return call(out_args, out_kwargs, desired_result_type);
136  }
137 
138  // Evaluates argument expressions and use a lambda function for
139  // adding extra elements to the arg and kwarg objects.
141  const char* args_expression,
142  const char* kwargs_expression,
143  const char* module_name,
144  PY_PyObject*& out_args,
145  PY_PyObject*& out_kwargs,
146  ArgHandler arg_handler ) const
147  {
148  PY_InterpreterAutoLock auto_lock;
149 
150  PY_Result result = evaluate(
151  args_expression, kwargs_expression, module_name, out_args, out_kwargs);
152  if (result.myResultType == PY_Result::ERR)
153  {
154  return result;
155  }
156 
157  arg_handler(out_args, out_kwargs);
158 
159  return result;
160  }
161 
163  { myExpressionCache = c; }
164 
165  static void setHOM(PY_CallbackHOM *hom)
166  { theHOM = hom; }
167 
169  { return theHOM; }
170 
171 private:
172  // Performs a call with pre-evaluated args and kwargs
173  PY_Result call(
174  PY_PyObject * args,
175  PY_PyObject * kwargs,
176  PY_Result::Type desired_result_type=PY_Result::NONE ) const;
177 
178  // Evaluates positional and keyworded arguments. The returned arguments can
179  // be expanded with other values before performing a call.
180  PY_Result evaluate(
181  const char *args_expression,
182  const char *kwargs_expression,
183  const char *module_name,
184  PY_PyObject*& out_args,
185  PY_PyObject*& out_kwargs ) const;
186 
187  PY_PyObject* evaluateExpression(const char *expression, PY_Result &result) const;
188  // This version use an input module to evaluate the expression
189  PY_PyObject* evaluateExpression(
190  const char *expression, const char* module_name, PY_Result &result) const;
191 
192  PY_CallbackCompiledCodeCache *myExpressionCache;
193 
194  static PY_CallbackHOM *theHOM;
195 };
196 
197 #endif
virtual ~PY_CallbackHOM()
Definition: PY_Callback.h:55
PY_Callback(void *python_callable_object)
Definition: PY_Callback.h:74
const GLfloat * c
Definition: glew.h:16631
int64 exint
Definition: SYS_Types.h:125
static void setHOM(PY_CallbackHOM *hom)
Definition: PY_Callback.h:165
PY_Result call(const char *args_expression, const char *kwargs_expression, const char *module_name, PY_Result::Type desired_result_type, PY_PyObject *&out_args, PY_PyObject *&out_kwargs, ArgHandler arg_handler) const
Definition: PY_Callback.h:117
GLuint64EXT * result
Definition: glew.h:14311
PY_Callback & operator=(const PY_Callback &callback)
Definition: PY_Callback.h:84
static PY_CallbackHOM * getHOM()
Definition: PY_Callback.h:168
UT_StringMap< PY_CompiledCode * > myExpressionCache
Definition: PY_Callback.h:43
const GLdouble * v
Definition: glcorearb.h:837
PY_EvaluationContext myContext
Definition: PY_Callback.h:42
PY_PyObject
#define PY_API
Definition: PY_API.h:10
long long int64
Definition: SYS_Types.h:116
PY_OpaqueObject & operator=(const PY_OpaqueObject &opaque_object)
GLuint GLfloat * val
Definition: glcorearb.h:1608
void setExpressionCache(PY_CallbackCompiledCodeCache *c)
Definition: PY_Callback.h:162
std::function< void(PY_PyObject *args, PY_PyObject *kwargs)> ArgHandler
Definition: PY_Callback.h:70
PY_Result evaluateArgs(const char *args_expression, const char *kwargs_expression, const char *module_name, PY_PyObject *&out_args, PY_PyObject *&out_kwargs, ArgHandler arg_handler) const
Definition: PY_Callback.h:140
**If you just want to fire and args
Definition: thread.h:609
PY_Callback(const PY_Callback &callback)
Definition: PY_Callback.h:79
Type myResultType
Definition: PY_Result.h:44
PY_Result call(const char *args_expression=NULL, const char *kwargs_expression=NULL) const
Definition: PY_Callback.h:98