Split apart renderdoc.i for better organisation

This commit is contained in:
baldurk
2017-03-28 19:49:03 +01:00
parent b33d64acac
commit 694d7b6c7b
7 changed files with 226 additions and 238 deletions
@@ -0,0 +1,70 @@
// this file is included from renderdoc.i, it's not a module in itself
%header %{
#include <set>
%}
%init %{
// verify that docstrings aren't duplicated, which is a symptom of missing DOCUMENT()
// macros around newly added classes/members.
#if !defined(RELEASE)
static bool doc_checked = false;
if(!doc_checked)
{
doc_checked = true;
std::set<std::string> docstrings;
for(size_t i=0; i < sizeof(swig_type_initial)/sizeof(swig_type_initial[0]); i++)
{
SwigPyClientData *typeinfo = (SwigPyClientData *)swig_type_initial[i]->clientdata;
// opaque types have no typeinfo, skip these
if(!typeinfo) continue;
PyTypeObject *typeobj = typeinfo->pytype;
std::string typedoc = typeobj->tp_doc;
auto result = docstrings.insert(typedoc);
if(!result.second)
{
snprintf(convert_error, sizeof(convert_error)-1, "Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?", typedoc.c_str(), typeobj->tp_name);
RENDERDOC_LogMessage(LogType::Fatal, "QTRD", __FILE__, __LINE__, convert_error);
}
PyMethodDef *method = typeobj->tp_methods;
while(method->ml_doc)
{
std::string typedoc = method->ml_doc;
size_t i = 0;
while(typedoc[i] == '\n')
i++;
// skip the first line as it's autodoc generated
i = typedoc.find('\n', i);
if(i != std::string::npos)
{
while(typedoc[i] == '\n')
i++;
typedoc.erase(0, i);
result = docstrings.insert(typedoc);
if(!result.second)
{
snprintf(convert_error, sizeof(convert_error)-1, "Duplicate docstring '%s' found on method '%s' - are you missing a DOCUMENT()?", typedoc.c_str(), method->ml_name);
RENDERDOC_LogMessage(LogType::Fatal, "QTRD", __FILE__, __LINE__, convert_error);
}
}
method++;
}
}
}
#endif
%}
@@ -879,3 +879,53 @@ funcType ConvertFunc(PyObject *self, const char *funcname, PyObject *func, bool
return f.call(funcname, func, global_internal_handle, failflag);
};
}
namespace
{
template <typename T, bool is_pointer = std::is_pointer<T>::value>
struct pointer_unwrap;
template <typename T>
struct pointer_unwrap<T, false>
{
static void tempset(T &ptr, T *tempobj) {}
static void tempalloc(T &ptr, unsigned char *tempmem) {}
static void tempdealloc(T &ptr) {}
static T &indirect(T &ptr) { return ptr; }
};
template <typename T>
struct pointer_unwrap<T, true>
{
typedef typename std::remove_pointer<T>::type U;
static void tempset(U *&ptr, U *tempobj) { ptr = tempobj; }
static void tempalloc(U *&ptr, unsigned char *tempmem) { ptr = new(tempmem) U; }
static void tempdealloc(U *ptr) { ptr->~U(); }
static U &indirect(U *ptr) { return *ptr; }
};
};
template <typename T>
inline void tempalloc(T &ptr, unsigned char *tempmem)
{
pointer_unwrap<T>::tempalloc(ptr, tempmem);
}
template <typename T, typename U>
inline void tempset(T &ptr, U *tempobj)
{
pointer_unwrap<T>::tempset(ptr, tempobj);
}
template <typename T>
inline void tempdealloc(T ptr)
{
pointer_unwrap<T>::tempdealloc(ptr);
}
template <typename T>
inline typename std::remove_pointer<T>::type &indirect(T &ptr)
{
return pointer_unwrap<T>::indirect(ptr);
}
@@ -0,0 +1,95 @@
// this file is included from renderdoc.i, it's not a module in itself
%define SIMPLE_TYPEMAPS_VARIANT(BaseType, SimpleType)
%typemap(in, fragment="pyconvert") SimpleType (BaseType temp) {
tempset($1, &temp);
int res = ConvertFromPy($input, indirect($1));
if(!SWIG_IsOK(res))
{
SWIG_exception_fail(SWIG_ArgError(res), "in method '$symname' argument $argnum of type '$1_basetype'");
}
}
%typemap(out, fragment="pyconvert") SimpleType {
$result = ConvertToPy(self, indirect($1));
}
%enddef
%define SIMPLE_TYPEMAPS(SimpleType)
SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType)
SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType *)
SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType &)
%enddef
%define CONTAINER_TYPEMAPS_VARIANT(ContainerType)
%typemap(in, fragment="pyconvert") ContainerType (unsigned char tempmem[32]) {
static_assert(sizeof(tempmem) >= sizeof(std::remove_pointer<decltype($1)>::type), "not enough temp space for $1_basetype");
if(!PyList_Check($input))
{
SWIG_exception_fail(SWIG_TypeError, "in method '$symname' list expected for argument $argnum of type '$1_basetype'");
}
tempalloc($1, tempmem);
int failIdx = 0;
int res = TypeConversion<std::remove_pointer<decltype($1)>::type>::ConvertFromPy($input, indirect($1), &failIdx);
if(!SWIG_IsOK(res))
{
snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' argument $argnum of type '$1_basetype', decoding element %d", failIdx);
SWIG_exception_fail(SWIG_ArgError(res), convert_error);
}
}
%typemap(freearg, fragment="pyconvert") ContainerType {
tempdealloc($1);
}
%typemap(argout, fragment="pyconvert") ContainerType {
// empty the previous contents
if(PyDict_Check($input))
{
PyDict_Clear($input);
}
else
{
Py_ssize_t sz = PySequence_Size($input);
if(sz > 0)
PySequence_DelSlice($input, 0, sz);
}
// overwrite with array contents
int failIdx = 0;
PyObject *res = TypeConversion<std::remove_pointer<decltype($1)>::type>::ConvertToPyInPlace(self, $input, indirect($1), &failIdx);
if(!res)
{
snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' argument $argnum of type '$1_basetype', encoding element %d", failIdx);
SWIG_exception_fail(SWIG_ValueError, convert_error);
}
}
%typemap(out, fragment="pyconvert") ContainerType {
int failIdx = 0;
$result = TypeConversion<std::remove_pointer<$1_basetype>::type>::ConvertToPy(self, indirect($1), &failIdx);
if(!$result)
{
snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' returning type '$1_basetype', encoding element %d", failIdx);
SWIG_exception_fail(SWIG_ValueError, convert_error);
}
}
%enddef
%define CONTAINER_TYPEMAPS(ContainerType)
CONTAINER_TYPEMAPS_VARIANT(ContainerType)
CONTAINER_TYPEMAPS_VARIANT(ContainerType *)
CONTAINER_TYPEMAPS_VARIANT(ContainerType &)
%enddef
-8
View File
@@ -11,17 +11,9 @@
SIMPLE_TYPEMAPS(QString)
SIMPLE_TYPEMAPS(QDateTime)
CONTAINER_TYPEMAPS(QList &)
CONTAINER_TYPEMAPS(QList *)
CONTAINER_TYPEMAPS(QList)
CONTAINER_TYPEMAPS(QStringList &)
CONTAINER_TYPEMAPS(QStringList *)
CONTAINER_TYPEMAPS(QStringList)
CONTAINER_TYPEMAPS(QVector &)
CONTAINER_TYPEMAPS(QVector *)
CONTAINER_TYPEMAPS(QVector)
CONTAINER_TYPEMAPS(QMap &)
CONTAINER_TYPEMAPS(QMap *)
CONTAINER_TYPEMAPS(QMap)
// pass QWidget objects to PySide
+3 -230
View File
@@ -38,171 +38,11 @@
%#include "Code/pyrenderdoc/pyconversion.h"
}
%fragment("tempalloc", "header") {
template<typename T, bool is_pointer = std::is_pointer<T>::value>
struct pointer_unwrap;
template<typename T>
struct pointer_unwrap<T, false>
{
static void tempset(T &ptr, T *tempobj)
{
}
static void tempalloc(T &ptr, unsigned char *tempmem)
{
}
static void tempdealloc(T &ptr)
{
}
static T &indirect(T &ptr)
{
return ptr;
}
};
template<typename T>
struct pointer_unwrap<T, true>
{
typedef typename std::remove_pointer<T>::type U;
static void tempset(U *&ptr, U *tempobj)
{
ptr = tempobj;
}
static void tempalloc(U *&ptr, unsigned char *tempmem)
{
ptr = new (tempmem) U;
}
static void tempdealloc(U *ptr)
{
ptr->~U();
}
static U &indirect(U *ptr)
{
return *ptr;
}
};
template<typename T>
void tempalloc(T &ptr, unsigned char *tempmem)
{
pointer_unwrap<T>::tempalloc(ptr, tempmem);
}
template<typename T, typename U>
void tempset(T &ptr, U *tempobj)
{
pointer_unwrap<T>::tempset(ptr, tempobj);
}
template<typename T>
void tempdealloc(T ptr)
{
pointer_unwrap<T>::tempdealloc(ptr);
}
template<typename T>
typename std::remove_pointer<T>::type &indirect(T &ptr)
{
return pointer_unwrap<T>::indirect(ptr);
}
}
%define SIMPLE_TYPEMAPS_VARIANT(BaseType, SimpleType)
%typemap(in, fragment="tempalloc,pyconvert") SimpleType (BaseType temp) {
tempset($1, &temp);
int res = ConvertFromPy($input, indirect($1));
if(!SWIG_IsOK(res))
{
SWIG_exception_fail(SWIG_ArgError(res), "in method '$symname' argument $argnum of type '$1_basetype'");
}
}
%typemap(out, fragment="tempalloc,pyconvert") SimpleType {
$result = ConvertToPy(self, indirect($1));
}
%enddef
%define SIMPLE_TYPEMAPS(SimpleType)
SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType)
SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType *)
SIMPLE_TYPEMAPS_VARIANT(SimpleType, SimpleType &)
%enddef
%define CONTAINER_TYPEMAPS(ContainerType)
%typemap(in, fragment="tempalloc,pyconvert") ContainerType (unsigned char tempmem[32]) {
static_assert(sizeof(tempmem) >= sizeof(std::remove_pointer<decltype($1)>::type), "not enough temp space for $1_basetype");
if(!PyList_Check($input))
{
SWIG_exception_fail(SWIG_TypeError, "in method '$symname' list expected for argument $argnum of type '$1_basetype'");
}
tempalloc($1, tempmem);
int failIdx = 0;
int res = TypeConversion<std::remove_pointer<decltype($1)>::type>::ConvertFromPy($input, indirect($1), &failIdx);
if(!SWIG_IsOK(res))
{
snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' argument $argnum of type '$1_basetype', decoding element %d", failIdx);
SWIG_exception_fail(SWIG_ArgError(res), convert_error);
}
}
%typemap(freearg, fragment="tempalloc") ContainerType {
tempdealloc($1);
}
%typemap(argout, fragment="tempalloc,pyconvert") ContainerType {
// empty the previous contents
if(PyDict_Check($input))
{
PyDict_Clear($input);
}
else
{
Py_ssize_t sz = PySequence_Size($input);
if(sz > 0)
PySequence_DelSlice($input, 0, sz);
}
// overwrite with array contents
int failIdx = 0;
PyObject *res = TypeConversion<std::remove_pointer<decltype($1)>::type>::ConvertToPyInPlace(self, $input, indirect($1), &failIdx);
if(!res)
{
snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' argument $argnum of type '$1_basetype', encoding element %d", failIdx);
SWIG_exception_fail(SWIG_ValueError, convert_error);
}
}
%typemap(out, fragment="tempalloc,pyconvert") ContainerType {
int failIdx = 0;
$result = TypeConversion<std::remove_pointer<$1_basetype>::type>::ConvertToPy(self, indirect($1), &failIdx);
if(!$result)
{
snprintf(convert_error, sizeof(convert_error)-1, "in method '$symname' returning type '$1_basetype', encoding element %d", failIdx);
SWIG_exception_fail(SWIG_ValueError, convert_error);
}
}
%enddef
%include "pyconversion.i"
SIMPLE_TYPEMAPS(rdctype::str)
CONTAINER_TYPEMAPS(rdctype::arr)
CONTAINER_TYPEMAPS(rdctype::array)
%typemap(in, fragment="pyconvert") std::function {
PyObject *func = $input;
@@ -296,71 +136,4 @@ void HandleCallbackFailure(PyObject *global_handle, bool &fail_flag)
%}
%header %{
#include <set>
%}
%init %{
// verify that docstrings aren't duplicated, which is a symptom of missing DOCUMENT()
// macros around newly added classes/members.
#if !defined(RELEASE)
static bool doc_checked = false;
if(!doc_checked)
{
doc_checked = true;
std::set<std::string> docstrings;
for(size_t i=0; i < sizeof(swig_type_initial)/sizeof(swig_type_initial[0]); i++)
{
SwigPyClientData *typeinfo = (SwigPyClientData *)swig_type_initial[i]->clientdata;
// opaque types have no typeinfo, skip these
if(!typeinfo) continue;
PyTypeObject *typeobj = typeinfo->pytype;
std::string typedoc = typeobj->tp_doc;
auto result = docstrings.insert(typedoc);
if(!result.second)
{
snprintf(convert_error, sizeof(convert_error)-1, "Duplicate docstring '%s' found on struct '%s' - are you missing a DOCUMENT()?", typedoc.c_str(), typeobj->tp_name);
RENDERDOC_LogMessage(LogType::Fatal, "QTRD", __FILE__, __LINE__, convert_error);
}
PyMethodDef *method = typeobj->tp_methods;
while(method->ml_doc)
{
std::string typedoc = method->ml_doc;
size_t i = 0;
while(typedoc[i] == '\n')
i++;
// skip the first line as it's autodoc generated
i = typedoc.find('\n', i);
if(i != std::string::npos)
{
while(typedoc[i] == '\n')
i++;
typedoc.erase(0, i);
result = docstrings.insert(typedoc);
if(!result.second)
{
snprintf(convert_error, sizeof(convert_error)-1, "Duplicate docstring '%s' found on method '%s' - are you missing a DOCUMENT()?", typedoc.c_str(), method->ml_name);
RENDERDOC_LogMessage(LogType::Fatal, "QTRD", __FILE__, __LINE__, convert_error);
}
}
method++;
}
}
}
#endif
%}
%include "document_check.i"
+2
View File
@@ -1374,7 +1374,9 @@
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="Code\pyrenderdoc\document_check.i" />
<None Include="Code\pyrenderdoc\pyconversion.h" />
<None Include="Code\pyrenderdoc\pyconversion.i" />
<None Include="Resources\128.png" />
<None Include="Resources\accept.png" />
<None Include="Resources\add.png" />
@@ -1057,6 +1057,12 @@
<None Include="Code\pyrenderdoc\pyconversion.h">
<Filter>Code\pyrenderdoc</Filter>
</None>
<None Include="Code\pyrenderdoc\pyconversion.i">
<Filter>Code\pyrenderdoc</Filter>
</None>
<None Include="Code\pyrenderdoc\document_check.i">
<Filter>Code\pyrenderdoc</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Resources\qrenderdoc.rc">