Loading...
Searching...
No Matches
valueFromPython.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_VT_VALUE_FROM_PYTHON_H
8#define PXR_BASE_VT_VALUE_FROM_PYTHON_H
9
11
12#include "pxr/pxr.h"
13#include "pxr/base/vt/api.h"
14#include "pxr/base/vt/value.h"
15
16#include "pxr/base/tf/hash.h"
17#include "pxr/base/tf/hashmap.h"
18#include "pxr/base/tf/pyUtils.h"
20
22
23#include <vector>
24
25PXR_NAMESPACE_OPEN_SCOPE
26
29class Vt_ValueFromPythonRegistry {
30public:
31
32 static bool HasConversions() {
33 return !_GetInstance()._lvalueExtractors.empty() &&
34 !_GetInstance()._rvalueExtractors.empty();
35 }
36
37 VT_API static VtValue Invoke(PyObject *obj);
38
39 template <class T>
40 static void Register(bool registerRvalue) {
41 if (!TfPyIsInitialized()) {
42 TF_FATAL_ERROR("Tried to register a VtValue from python conversion "
43 "but python is not initialized!");
44 }
45 _GetInstance()._RegisterLValue(_Extractor::MakeLValue<T>());
46 if (registerRvalue)
47 _GetInstance()._RegisterRValue(_Extractor::MakeRValue<T>());
48 }
49
50 Vt_ValueFromPythonRegistry(Vt_ValueFromPythonRegistry const&) = delete;
51 Vt_ValueFromPythonRegistry& operator=(
52 Vt_ValueFromPythonRegistry const&) = delete;
53
54 Vt_ValueFromPythonRegistry(Vt_ValueFromPythonRegistry &&) = delete;
55 Vt_ValueFromPythonRegistry& operator=(
56 Vt_ValueFromPythonRegistry &&) = delete;
57
58private:
59 Vt_ValueFromPythonRegistry() {}
60 VT_API ~Vt_ValueFromPythonRegistry();
61
62 friend class TfSingleton<Vt_ValueFromPythonRegistry>;
63
64 class _Extractor {
65 private:
66 using _ExtractFunc = VtValue (*)(PyObject *);
67
68 // _ExtractLValue will attempt to obtain an l-value T from the python
69 // object it's passed. This effectively disallows type conversions
70 // (other than things like derived-to-base type conversions).
71 template <class T>
72 static VtValue _ExtractLValue(PyObject *);
73
74 // _ExtractRValue will attempt to obtain an r-value T from the python
75 // object it's passed. This allows boost.python to invoke type
76 // conversions to produce the T.
77 template <class T>
78 static VtValue _ExtractRValue(PyObject *);
79
80 public:
81
82 template <class T>
83 static _Extractor MakeLValue() {
84 return _Extractor(&_ExtractLValue<T>);
85 }
86
87 template <class T>
88 static _Extractor MakeRValue() {
89 return _Extractor(&_ExtractRValue<T>);
90 }
91
92 VtValue Invoke(PyObject *obj) const {
93 return _extract(obj);
94 }
95
96 private:
97 explicit _Extractor(_ExtractFunc extract) : _extract(extract) {}
98
99 _ExtractFunc _extract;
100 };
101
102 VT_API static Vt_ValueFromPythonRegistry &_GetInstance() {
104 }
105
106 VT_API void _RegisterLValue(_Extractor const &e);
107 VT_API void _RegisterRValue(_Extractor const &e);
108
109 std::vector<_Extractor> _lvalueExtractors;
110 std::vector<_Extractor> _rvalueExtractors;
111
112 typedef TfHashMap<PyObject *, _Extractor, TfHash> _LValueExtractorCache;
113 _LValueExtractorCache _lvalueExtractorCache;
114
115};
116
117VT_API_TEMPLATE_CLASS(TfSingleton<Vt_ValueFromPythonRegistry>);
118
119template <class T>
120VtValue Vt_ValueFromPythonRegistry::
121_Extractor::_ExtractLValue(PyObject *obj) {
122 pxr_boost::python::extract<T &> x(obj);
123 if (x.check())
124 return VtValue(x());
125 return VtValue();
126}
127
128template <class T>
129VtValue Vt_ValueFromPythonRegistry::
130_Extractor::_ExtractRValue(PyObject *obj) {
131 pxr_boost::python::extract<T> x(obj);
132 if (x.check())
133 return VtValue(x());
134 return VtValue();
135}
136
137template <class T>
138void VtValueFromPython() {
139 Vt_ValueFromPythonRegistry::Register<T>(/* registerRvalue = */ true);
140}
141
142template <class T>
143void VtValueFromPythonLValue() {
144 Vt_ValueFromPythonRegistry::Register<T>(/* registerRvalue = */ false);
145}
146
147PXR_NAMESPACE_CLOSE_SCOPE
148
149#endif // PXR_BASE_VT_VALUE_FROM_PYTHON_H
Miscellaneous Utilities for dealing with script.
TF_API bool TfPyIsInitialized()
Returns true if python is initialized.
Manage a single instance of an object (see.
Definition: singleton.h:105
static T & GetInstance()
Return a reference to an object of type T, creating it if necessary.
Definition: singleton.h:120
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:152
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:91
Intended to replace a direct include of Python.h, which causes several build problems with certain co...
Manage a single instance of an object.