From 6759d975b0ab78186896acb72afb7397b4fb0fbd Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 5 Sep 2017 22:42:53 +0100 Subject: [PATCH] Add conversion typemaps for fixed-size arrays in python --- qrenderdoc/Code/pyrenderdoc/pyconversion.h | 55 ++++++++++++++++++++++ qrenderdoc/Code/pyrenderdoc/pyconversion.i | 50 ++++++++++++++++++++ qrenderdoc/Code/pyrenderdoc/renderdoc.i | 9 ++++ 3 files changed, 114 insertions(+) diff --git a/qrenderdoc/Code/pyrenderdoc/pyconversion.h b/qrenderdoc/Code/pyrenderdoc/pyconversion.h index a727101bf..3eb627159 100644 --- a/qrenderdoc/Code/pyrenderdoc/pyconversion.h +++ b/qrenderdoc/Code/pyrenderdoc/pyconversion.h @@ -117,6 +117,37 @@ struct TypeConversion }; // specialisations for basic types +template <> +struct TypeConversion +{ + static int ConvertFromPy(PyObject *in, bool &out) + { + if(!PyBool_Check(in)) + return SWIG_TypeError; + + if(in == Py_True) + out = true; + else + out = false; + + return SWIG_OK; + } + + static PyObject *ConvertToPy(PyObject *self, const bool &in) + { + if(in) + { + Py_IncRef(Py_True); + return Py_True; + } + else + { + Py_IncRef(Py_False); + return Py_False; + } + } +}; + template <> struct TypeConversion { @@ -141,6 +172,30 @@ struct TypeConversion } }; +template <> +struct TypeConversion +{ + static int ConvertFromPy(PyObject *in, uint16_t &out) + { + if(!PyLong_Check(in)) + return SWIG_TypeError; + + uint32_t longval = PyLong_AsUnsignedLong(in); + + if(PyErr_Occurred() || longval > 0xffff) + return SWIG_OverflowError; + + out = uint16_t(longval & 0xff); + + return SWIG_OK; + } + + static PyObject *ConvertToPy(PyObject *self, const uint16_t &in) + { + return PyLong_FromUnsignedLong(in); + } +}; + template <> struct TypeConversion { diff --git a/qrenderdoc/Code/pyrenderdoc/pyconversion.i b/qrenderdoc/Code/pyrenderdoc/pyconversion.i index 5d21992fc..1cadd6c33 100644 --- a/qrenderdoc/Code/pyrenderdoc/pyconversion.i +++ b/qrenderdoc/Code/pyrenderdoc/pyconversion.i @@ -1,5 +1,55 @@ // this file is included from renderdoc.i, it's not a module in itself +// typemaps for more sensible fixed-array handling, based on typemaps from SWIG documentation + +%define FIXED_ARRAY_TYPEMAPS(BaseType) + +%typemap(out) BaseType [ANY] { + $result = PyList_New($1_dim0); + for(int i = 0; i < $1_dim0; i++) + { + PyObject *o = TypeConversion::ConvertToPy(self, $1[i]); + if(!o) + { + snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' returning type '$1_basetype', encoding element %d", i); + SWIG_exception_fail(SWIG_ValueError, convert_error); + } + PyList_SetItem($result,i,o); + } +} + +%typemap(arginit) BaseType [ANY] { + $1 = NULL; +} + +%typemap(in) BaseType [ANY] { + if(!PySequence_Check($input)) + { + SWIG_exception_fail(SWIG_TypeError, "in method '$symname' argument $argnum of type '$1_basetype'. Expected sequence"); + } + if(PySequence_Length($input) != $1_dim0) { + SWIG_exception_fail(SWIG_ValueError, "in method '$symname' argument $argnum of type '$1_basetype'. Expected $1_dim0 elements"); + } + $1 = new BaseType[$1_dim0]; + for(int i = 0; i < $1_dim0; i++) { + PyObject *o = PySequence_GetItem($input,i); + + int res = TypeConversion::ConvertFromPy(o, $1[i]); + + if(!SWIG_IsOK(res)) + { + snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' argument $argnum of type '$1_basetype', decoding element %d", i); + SWIG_exception_fail(SWIG_ArgError(res), convert_error); + } + } +} + +%typemap(freearg) BaseType [ANY] { + delete[] $1; +} + +%enddef + %define SIMPLE_TYPEMAPS_VARIANT(BaseType, SimpleType) %typemap(in, fragment="pyconvert") SimpleType (BaseType temp) { tempset($1, &temp); diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i index 61ffeb291..1e4aa486d 100644 --- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i @@ -55,6 +55,15 @@ SIMPLE_TYPEMAPS(rdctype::str) CONTAINER_TYPEMAPS(rdctype::array) CONTAINER_TYPEMAPS(rdctype::pair) +FIXED_ARRAY_TYPEMAPS(ResourceId) +FIXED_ARRAY_TYPEMAPS(double) +FIXED_ARRAY_TYPEMAPS(float) +FIXED_ARRAY_TYPEMAPS(bool) +FIXED_ARRAY_TYPEMAPS(uint64_t) +FIXED_ARRAY_TYPEMAPS(uint32_t) +FIXED_ARRAY_TYPEMAPS(int32_t) +FIXED_ARRAY_TYPEMAPS(uint16_t) + %typemap(in, fragment="pyconvert") std::function { PyObject *func = $input; $1 = ConvertFunc<$1_ltype>(self, "$symname", func, exHandle$argnum);