mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Add support for documenting bindings API directly in code
This commit is contained in:
+69
-1
@@ -21,6 +21,15 @@ import os
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
import struct
|
||||
|
||||
if struct.calcsize("P") == 8:
|
||||
modulepath = '../x64/Development'
|
||||
else:
|
||||
modulepath = '../Win32/Development'
|
||||
|
||||
sys.path.insert(0, os.path.abspath(modulepath))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
@@ -29,7 +38,7 @@ import os
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -301,3 +310,62 @@ html_context = {
|
||||
if(tags.has('htmlhelp')):
|
||||
print("**** We require sphinx 1.5 for htmlhelp build to have the fix for issue #2550 ****")
|
||||
needs_sphinx = '1.5'
|
||||
|
||||
def maybe_skip_member(app, what, name, obj, skip, options):
|
||||
# Hide these SWIG internals
|
||||
if name == "this" or name == "thisown":
|
||||
return True
|
||||
# Allow hiding free module functions, or only showing free module functions
|
||||
if 'exclude-members' in options and what == "module":
|
||||
if 'free_functions__' in options['exclude-members'] and 'built-in function' in repr(obj):
|
||||
return True
|
||||
if 'non_free_functions__' in options['exclude-members'] and 'built-in function' not in repr(obj):
|
||||
return True
|
||||
# Allow hiding enum constant members (i.e. int constants). These can then be documented explicitly
|
||||
# as we don't have a way in SWIG to attach docstrings to constants directly.
|
||||
if 'exclude-members' in options and 'enum_constants__' in options['exclude-members'] and isinstance(obj, int):
|
||||
return True
|
||||
# Allow arbitrary globbing as a hack to exclude or include members
|
||||
if 'exclude-members' in options:
|
||||
for exclude in options['exclude-members']:
|
||||
# Look for a hack that describes a name match
|
||||
if exclude.startswith('name_match__'):
|
||||
match = exclude.replace('name_match__', '')
|
||||
|
||||
include_only = False
|
||||
|
||||
# see if it wants to include only matches, or exclude matches (default)
|
||||
if match.startswith('include_only__'):
|
||||
match = match.replace('include_only__', '')
|
||||
include_only = True
|
||||
|
||||
objname = ""
|
||||
if '__qualname__' in dir(obj):
|
||||
objname = obj.__qualname__
|
||||
else:
|
||||
try:
|
||||
objname = obj.__name__
|
||||
except AttributeError:
|
||||
objname = obj.__class__.__name__
|
||||
ismatch = False
|
||||
|
||||
# see if we're matching a prefix, or doing just a glob
|
||||
if match.startswith('startswith__'):
|
||||
match = match.replace('startswith__', '')
|
||||
ismatch = objname.startswith(match)
|
||||
|
||||
if match.startswith('in__'):
|
||||
match = match.replace('in__', '')
|
||||
ismatch = match in objname
|
||||
|
||||
# if we want to include only matches and it didn't match, skip this
|
||||
if include_only and not ismatch:
|
||||
return True
|
||||
|
||||
# If we want to exclude matches and it DID match, skip
|
||||
if not include_only and ismatch:
|
||||
return True
|
||||
return None
|
||||
|
||||
def setup(app):
|
||||
app.connect('autodoc-skip-member', maybe_skip_member)
|
||||
|
||||
@@ -18,6 +18,7 @@ Table of Contents
|
||||
:maxdepth: 2
|
||||
|
||||
introduction
|
||||
python_api/index
|
||||
in_application_api
|
||||
credits_acknowledgements
|
||||
getting_started/index
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
Enums and Data Structures
|
||||
=========================
|
||||
|
||||
.. automodule:: renderdoc
|
||||
:members:
|
||||
:undoc-members:
|
||||
:imported-members:
|
||||
:exclude-members: free_functions__, str
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Functions
|
||||
=========
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Python API
|
||||
==========
|
||||
|
||||
.. toctree::
|
||||
main_ifaces
|
||||
funcs
|
||||
enums_data
|
||||
qrenderdoc
|
||||
@@ -0,0 +1,4 @@
|
||||
Primary Interfaces
|
||||
==================
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
QRenderDoc
|
||||
==========
|
||||
|
||||
.. automodule:: qrenderdoc
|
||||
:members:
|
||||
:undoc-members:
|
||||
:imported-members:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%module(docstring="This is the API to RenderDoc's internals.") renderdoc
|
||||
|
||||
%feature("autodoc");
|
||||
%feature("autodoc", "0");
|
||||
|
||||
// just define linux platform to make sure things compile with no extra __declspec attributes
|
||||
#define RENDERDOC_PLATFORM_LINUX
|
||||
@@ -8,6 +8,9 @@
|
||||
// we don't need these for the interface, they just confuse things
|
||||
#define NO_ENUM_CLASS_OPERATORS
|
||||
|
||||
// use documentation for docstrings
|
||||
#define DOCUMENT(text) %feature("docstring") text
|
||||
|
||||
// ignore warning about base class rdctype::array<char> methods in rdctype::str
|
||||
#pragma SWIG nowarn=401
|
||||
|
||||
@@ -127,6 +130,9 @@
|
||||
%rename(D3D12_ResourceData) D3D12Pipe::ResourceData;
|
||||
%rename(D3D12_State) D3D12Pipe::State;
|
||||
|
||||
// strip off the RENDERDOC_ namespace prefix, it's unnecessary
|
||||
%rename("%(strip:[RENDERDOC_])s") "";
|
||||
|
||||
%fragment("pyconvert", "header") {
|
||||
static char convert_error[1024] = {};
|
||||
|
||||
@@ -279,3 +285,71 @@ PyObject *PassObjectToPython(const char *type, void *obj)
|
||||
|
||||
%}
|
||||
|
||||
%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
|
||||
%}
|
||||
|
||||
@@ -40,6 +40,10 @@ inline const char *TypeName();
|
||||
typedef uint8_t byte;
|
||||
typedef uint32_t bool32;
|
||||
|
||||
#ifndef DOCUMENT
|
||||
#define DOCUMENT(text)
|
||||
#endif
|
||||
|
||||
#if defined(RENDERDOC_PLATFORM_WIN32)
|
||||
|
||||
#ifdef RENDERDOC_EXPORTS
|
||||
|
||||
Reference in New Issue
Block a user