function namespaces partially work
This commit is contained in:
parent
e85e83f491
commit
5ad7f9910f
@ -51,7 +51,8 @@ set(cv2_generated_hdrs
|
|||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_func_tab.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_func_tab.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_const_reg.h")
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_const_reg.h"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_ns_reg.h")
|
||||||
|
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -1205,6 +1205,40 @@ static PyMethodDef methods[] = {
|
|||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* Module init */
|
/* Module init */
|
||||||
|
|
||||||
|
static void init_submodule(PyObject * root, const char * name, PyMethodDef * methods)
|
||||||
|
{
|
||||||
|
std::string s = name;
|
||||||
|
size_t i = s.find('.')+1; // assume, that name is cv2.<name>...
|
||||||
|
while (i < s.length())
|
||||||
|
{
|
||||||
|
size_t j = s.find('.', i);
|
||||||
|
if (j == std::string::npos)
|
||||||
|
j = s.length();
|
||||||
|
std::string short_name = s.substr(i, j-i);
|
||||||
|
std::string full_name = s.substr(0, j);
|
||||||
|
i = j+1;
|
||||||
|
|
||||||
|
PyObject * d = PyModule_GetDict(root);
|
||||||
|
PyObject * submod = PyDict_GetItemString(d, short_name.c_str());
|
||||||
|
if (submod == NULL)
|
||||||
|
{
|
||||||
|
submod = PyImport_AddModule(full_name.c_str());
|
||||||
|
PyDict_SetItemString(d, short_name.c_str(), submod);
|
||||||
|
}
|
||||||
|
root = submod;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject * d = PyModule_GetDict(root);
|
||||||
|
for (PyMethodDef * m = methods; m->ml_name != NULL; ++m)
|
||||||
|
{
|
||||||
|
PyObject * method_obj = PyCFunction_NewEx(m, NULL, NULL);
|
||||||
|
PyDict_SetItemString(d, m->ml_name, method_obj);
|
||||||
|
Py_DECREF(method_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "pyopencv_generated_ns_reg.h"
|
||||||
|
|
||||||
static int to_ok(PyTypeObject *to)
|
static int to_ok(PyTypeObject *to)
|
||||||
{
|
{
|
||||||
to->tp_alloc = PyType_GenericAlloc;
|
to->tp_alloc = PyType_GenericAlloc;
|
||||||
@ -1242,6 +1276,8 @@ void initcv2()
|
|||||||
#else
|
#else
|
||||||
PyObject* m = Py_InitModule(MODULESTR, methods);
|
PyObject* m = Py_InitModule(MODULESTR, methods);
|
||||||
#endif
|
#endif
|
||||||
|
init_submodules(m); // from "pyopencv_generated_ns_reg.h"
|
||||||
|
|
||||||
PyObject* d = PyModule_GetDict(m);
|
PyObject* d = PyModule_GetDict(m);
|
||||||
|
|
||||||
PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
|
PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION));
|
||||||
|
@ -398,11 +398,6 @@ class FuncVariant(object):
|
|||||||
self.classname = classname
|
self.classname = classname
|
||||||
self.name = self.wname = name
|
self.name = self.wname = name
|
||||||
self.isconstructor = isconstructor
|
self.isconstructor = isconstructor
|
||||||
if self.isconstructor:
|
|
||||||
if self.wname.startswith("Cv"):
|
|
||||||
self.wname = self.wname[2:]
|
|
||||||
else:
|
|
||||||
self.wname = self.classname
|
|
||||||
|
|
||||||
self.rettype = handle_ptr(decl[1])
|
self.rettype = handle_ptr(decl[1])
|
||||||
if self.rettype == "void":
|
if self.rettype == "void":
|
||||||
@ -505,11 +500,12 @@ class FuncVariant(object):
|
|||||||
|
|
||||||
|
|
||||||
class FuncInfo(object):
|
class FuncInfo(object):
|
||||||
def __init__(self, classname, name, cname, isconstructor):
|
def __init__(self, classname, name, cname, isconstructor, namespace):
|
||||||
self.classname = classname
|
self.classname = classname
|
||||||
self.name = name
|
self.name = name
|
||||||
self.cname = cname
|
self.cname = cname
|
||||||
self.isconstructor = isconstructor
|
self.isconstructor = isconstructor
|
||||||
|
self.namespace = namespace
|
||||||
self.variants = []
|
self.variants = []
|
||||||
|
|
||||||
def add_variant(self, decl):
|
def add_variant(self, decl):
|
||||||
@ -560,6 +556,7 @@ class FuncInfo(object):
|
|||||||
def gen_code(self, all_classes):
|
def gen_code(self, all_classes):
|
||||||
proto = self.get_wrapper_prototype()
|
proto = self.get_wrapper_prototype()
|
||||||
code = "%s\n{\n" % (proto,)
|
code = "%s\n{\n" % (proto,)
|
||||||
|
code += " using namespace %s;\n\n" % self.namespace.replace('.', '::')
|
||||||
|
|
||||||
selfinfo = ClassInfo("")
|
selfinfo = ClassInfo("")
|
||||||
ismethod = self.classname != "" and not self.isconstructor
|
ismethod = self.classname != "" and not self.isconstructor
|
||||||
@ -782,6 +779,9 @@ class PythonWrapperGenerator(object):
|
|||||||
if classname in self.classes:
|
if classname in self.classes:
|
||||||
bareclassname = chunks[-2]
|
bareclassname = chunks[-2]
|
||||||
namespace = '.'.join(chunks[:-2])
|
namespace = '.'.join(chunks[:-2])
|
||||||
|
if normalize_class_name(namespace) in self.classes:
|
||||||
|
print('Note: skipping "%s" (nested classes are currently not supported)'%decl[0])
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
classname = ''
|
classname = ''
|
||||||
bareclassname = ''
|
bareclassname = ''
|
||||||
@ -795,14 +795,15 @@ class PythonWrapperGenerator(object):
|
|||||||
name = m[1:]
|
name = m[1:]
|
||||||
if isclassmethod:
|
if isclassmethod:
|
||||||
name = bareclassname+"_"+name
|
name = bareclassname+"_"+name
|
||||||
classname = bareclassname = ''
|
classname = ''
|
||||||
|
|
||||||
if classname:
|
if classname and not isconstructor:
|
||||||
func_map = classinfo = self.classes[classname].methods
|
cname = chunks[-1]
|
||||||
|
func_map = self.classes[classname].methods
|
||||||
else:
|
else:
|
||||||
func_map = self.ns_funcs.setdefault(namespace, {})
|
func_map = self.ns_funcs.setdefault(namespace, {})
|
||||||
|
|
||||||
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor))
|
func = func_map.setdefault(name, FuncInfo(classname, name, cname, isconstructor, namespace))
|
||||||
func.add_variant(decl)
|
func.add_variant(decl)
|
||||||
|
|
||||||
def gen_const_reg(self, constinfo):
|
def gen_const_reg(self, constinfo):
|
||||||
@ -816,6 +817,16 @@ class PythonWrapperGenerator(object):
|
|||||||
self.code_ns_reg.write(func.get_tab_entry())
|
self.code_ns_reg.write(func.get_tab_entry())
|
||||||
self.code_ns_reg.write(' {NULL, NULL}\n};\n\n')
|
self.code_ns_reg.write(' {NULL, NULL}\n};\n\n')
|
||||||
|
|
||||||
|
def gen_namespaces_reg(self):
|
||||||
|
self.code_ns_reg.write('static void init_submodules(PyObject * root) \n{\n')
|
||||||
|
for ns_name in sorted(self.ns_funcs):
|
||||||
|
if ns_name == 'cv':
|
||||||
|
continue
|
||||||
|
wname = normalize_class_name(ns_name)
|
||||||
|
self.code_ns_reg.write(' init_submodule(root, MODULESTR"%s", methods_%s);\n' % (ns_name[2:], wname))
|
||||||
|
self.code_ns_reg.write('};\n')
|
||||||
|
|
||||||
|
|
||||||
def save(self, path, name, buf):
|
def save(self, path, name, buf):
|
||||||
f = open(path + "/" + name, "wt")
|
f = open(path + "/" + name, "wt")
|
||||||
f.write(buf.getvalue())
|
f.write(buf.getvalue())
|
||||||
@ -872,12 +883,17 @@ class PythonWrapperGenerator(object):
|
|||||||
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
||||||
|
|
||||||
# step 3: generate the code for all the global functions
|
# step 3: generate the code for all the global functions
|
||||||
funclist = list(self.ns_funcs['cv'].items())
|
for ns in self.ns_funcs:
|
||||||
|
funclist = self.ns_funcs[ns].items()
|
||||||
funclist.sort()
|
funclist.sort()
|
||||||
for name, func in funclist:
|
for name, func in funclist:
|
||||||
code = func.gen_code(self.classes)
|
code = func.gen_code(self.classes)
|
||||||
self.code_funcs.write(code)
|
self.code_funcs.write(code)
|
||||||
|
if ns == 'cv':
|
||||||
self.code_func_tab.write(func.get_tab_entry())
|
self.code_func_tab.write(func.get_tab_entry())
|
||||||
|
if ns != 'cv':
|
||||||
|
self.gen_namespace(ns)
|
||||||
|
self.gen_namespaces_reg()
|
||||||
|
|
||||||
# step 4: generate the code for constants
|
# step 4: generate the code for constants
|
||||||
constlist = list(self.consts.items())
|
constlist = list(self.consts.items())
|
||||||
@ -885,11 +901,6 @@ class PythonWrapperGenerator(object):
|
|||||||
for name, constinfo in constlist:
|
for name, constinfo in constlist:
|
||||||
self.gen_const_reg(constinfo)
|
self.gen_const_reg(constinfo)
|
||||||
|
|
||||||
# step 5: generate the code for namespaces
|
|
||||||
for ns in sorted(self.ns_funcs):
|
|
||||||
if ns != 'cv':
|
|
||||||
self.gen_namespace(ns)
|
|
||||||
|
|
||||||
# That's it. Now save all the files
|
# That's it. Now save all the files
|
||||||
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
self.save(output_path, "pyopencv_generated_include.h", self.code_include)
|
||||||
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
self.save(output_path, "pyopencv_generated_funcs.h", self.code_funcs)
|
||||||
|
Loading…
Reference in New Issue
Block a user