Skip to content

Commit f11f2bf

Browse files
keroiberalalek
andauthored
Merge pull request #20743 from keroiber:prefix_js_function_bindings_with_namespace
* Prefix global javascript functions with sub-namespaces * js: handle 'namespace_prefix_override', update filtering - avoid functions override with same name but different namespace Co-authored-by: Alexander Alekhin <[email protected]>
1 parent 24f43e7 commit f11f2bf

File tree

3 files changed

+63
-13
lines changed

3 files changed

+63
-13
lines changed

modules/js/generator/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ add_custom_command(
6060
${JS_SOURCE_DIR}/src/core_bindings.cpp
6161
${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py
6262
${CMAKE_CURRENT_SOURCE_DIR}/templates.py
63+
"${OPENCV_JS_WHITELIST_FILE}"
6364
${scripts_hdr_parser}
6465
#(not needed - generated by CMake) ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
6566
${opencv_hdrs}

modules/js/generator/embindgen.py

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ def makeWhiteList(module_list):
104104
return wl
105105

106106
white_list = None
107+
namespace_prefix_override = {
108+
'dnn' : ''
109+
}
107110

108111
# Features to be exported
109112
export_enums = False
@@ -271,6 +274,8 @@ def __init__(self, class_name, name, decl, is_constructor, is_class_method, is_c
271274

272275
class FuncInfo(object):
273276
def __init__(self, class_name, name, cname, namespace, isconstructor):
277+
self.name_id = '_'.join([namespace] + ([class_name] if class_name else []) + [name]) # unique id for dict key
278+
274279
self.class_name = class_name
275280
self.name = name
276281
self.cname = cname
@@ -295,9 +300,9 @@ def __init__(self):
295300
self.bindings = []
296301
self.wrapper_funcs = []
297302

298-
self.classes = {}
303+
self.classes = {} # FIXIT 'classes' should belong to 'namespaces'
299304
self.namespaces = {}
300-
self.enums = {}
305+
self.enums = {} # FIXIT 'enums' should belong to 'namespaces'
301306

302307
self.parser = hdr_parser.CppHeaderParser()
303308
self.class_idx = 0
@@ -419,7 +424,8 @@ def add_func(self, decl):
419424
else:
420425
func_map = self.namespaces.setdefault(namespace, Namespace()).funcs
421426

422-
func = func_map.setdefault(name, FuncInfo(class_name, name, cpp_name, namespace, is_constructor))
427+
fi = FuncInfo(class_name, name, cpp_name, namespace, is_constructor)
428+
func = func_map.setdefault(fi.name_id, fi)
423429

424430
variant = FuncVariant(class_name, name, decl, is_constructor, is_class_method, is_const_method,
425431
is_virtual_method, is_pure_virtual_method, ref_return, const_return)
@@ -430,7 +436,7 @@ def save(self, path, name, buf):
430436
f.write(buf.getvalue())
431437
f.close()
432438

433-
def gen_function_binding_with_wrapper(self, func, class_info):
439+
def gen_function_binding_with_wrapper(self, func, ns_name, class_info):
434440

435441
binding_text = None
436442
wrapper_func_text = None
@@ -488,8 +494,23 @@ def gen_function_binding_with_wrapper(self, func, class_info):
488494

489495

490496
# Wrapper function
491-
wrap_func_name = (func.class_name+"_" if class_info != None else "") + func.name.split("::")[-1] + "_wrapper"
492-
js_func_name = func.name
497+
if ns_name != None and ns_name != "cv":
498+
ns_parts = ns_name.split(".")
499+
if ns_parts[0] == "cv":
500+
ns_parts = ns_parts[1:]
501+
ns_part = "_".join(ns_parts) + "_"
502+
ns_id = '_'.join(ns_parts)
503+
ns_prefix = namespace_prefix_override.get(ns_id, ns_id)
504+
if ns_prefix:
505+
ns_prefix = ns_prefix + '_'
506+
else:
507+
ns_prefix = ''
508+
if class_info == None:
509+
js_func_name = ns_prefix + func.name
510+
wrap_func_name = js_func_name + "_wrapper"
511+
else:
512+
wrap_func_name = ns_prefix + func.class_name + "_" + func.name + "_wrapper"
513+
js_func_name = func.name
493514

494515
# TODO: Name functions based wrap directives or based on arguments list
495516
if index > 0:
@@ -740,12 +761,22 @@ def gen(self, dst_file, src_files, core_bindings):
740761
# step 2: generate bindings
741762
# Global functions
742763
for ns_name, ns in sorted(self.namespaces.items()):
743-
if ns_name.split('.')[0] != 'cv':
764+
ns_parts = ns_name.split('.')
765+
if ns_parts[0] != 'cv':
766+
print('Ignore namespace: {}'.format(ns_name))
744767
continue
745-
for name, func in sorted(ns.funcs.items()):
768+
else:
769+
ns_parts = ns_parts[1:]
770+
ns_id = '_'.join(ns_parts)
771+
ns_prefix = namespace_prefix_override.get(ns_id, ns_id)
772+
for name_id, func in sorted(ns.funcs.items()):
773+
name = func.name
774+
if ns_prefix:
775+
name = ns_prefix + '_' + name
746776
if name in ignore_list:
747777
continue
748778
if not name in white_list['']:
779+
#print('Not in whitelist: "{}" from ns={}'.format(name, ns_name))
749780
continue
750781

751782
ext_cnst = False
@@ -769,7 +800,7 @@ def gen(self, dst_file, src_files, core_bindings):
769800
continue
770801

771802
if with_wrapped_functions:
772-
binding, wrapper = self.gen_function_binding_with_wrapper(func, class_info=None)
803+
binding, wrapper = self.gen_function_binding_with_wrapper(func, ns_name, class_info=None)
773804
self.bindings += binding
774805
self.wrapper_funcs += wrapper
775806
else:
@@ -802,7 +833,7 @@ def gen(self, dst_file, src_files, core_bindings):
802833
class_bindings.append(constructor_template.substitute(signature=', '.join(args)))
803834
else:
804835
if with_wrapped_functions and (len(method.variants) > 1 or len(method.variants[0].args)>0 or "String" in method.variants[0].rettype):
805-
binding, wrapper = self.gen_function_binding_with_wrapper(method, class_info=class_info)
836+
binding, wrapper = self.gen_function_binding_with_wrapper(method, None, class_info=class_info)
806837
self.wrapper_funcs = self.wrapper_funcs + wrapper
807838
class_bindings = class_bindings + binding
808839
else:

platforms/js/opencv_js.config.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,26 @@
5555
'BFMatcher': ['isMaskSupported', 'create'],
5656
'': ['drawKeypoints', 'drawMatches', 'drawMatchesKnn']}
5757

58-
calib3d = {'': ['findHomography', 'calibrateCameraExtended', 'drawFrameAxes', 'estimateAffine2D', \
59-
'getDefaultNewCameraMatrix', 'initUndistortRectifyMap', 'Rodrigues', \
60-
'solvePnP', 'solvePnPRansac', 'solvePnPRefineLM']}
58+
calib3d = {
59+
'': [
60+
'findHomography',
61+
'calibrateCameraExtended',
62+
'drawFrameAxes',
63+
'estimateAffine2D',
64+
'getDefaultNewCameraMatrix',
65+
'initUndistortRectifyMap',
66+
'Rodrigues',
67+
'solvePnP',
68+
'solvePnPRansac',
69+
'solvePnPRefineLM',
70+
'projectPoints',
71+
72+
# cv::fisheye namespace
73+
'fisheye_initUndistortRectifyMap',
74+
'fisheye_projectPoints',
75+
],
76+
}
6177

6278
white_list = makeWhiteList([core, imgproc, objdetect, video, dnn, features2d, calib3d])
79+
80+
# namespace_prefix_override['dnn'] = '' # compatibility stuff (enabled by default)

0 commit comments

Comments
 (0)