Skip to content

Commit

Permalink
Fix operators generation and logging, clean up lambda for ops
Browse files Browse the repository at this point in the history
  • Loading branch information
SamFlt committed Mar 11, 2024
1 parent 3d954fa commit 36ad312
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 47 deletions.
51 changes: 51 additions & 0 deletions modules/python/config/core.json
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,17 @@
"use_default_param_policy": false,
"param_is_input": [true, false],
"param_is_output": [false, true]
},
{
"static": true,
"signature": "void getMinMaxRoi(const std::vector<vpImagePoint>&, int&, int&, int&, int&)",
"use_default_param_policy": false,
"param_is_input": [
true, false, false, false, false
],
"param_is_output": [
false, true, true, true, true
]
}
]
},
Expand Down Expand Up @@ -301,6 +312,31 @@
"static": true,
"signature": "vpImagePoint computeCurvePoint(double, unsigned int, unsigned int, std::vector<double> &, std::vector<vpImagePoint>&)",
"custom_name": "computeCurvePointFromSpline"
},
{
"static": false,
"signature": "void get_crossingPoints(std::list<vpImagePoint>&)",
"use_default_param_policy": false,
"param_is_input": [
false
],
"param_is_output": [
true
]
},
{
"static": false,
"signature": "void get_knots(std::list<double>&)",
"use_default_param_policy": false,
"param_is_input": [false],
"param_is_output": [true]
},
{
"static": false,
"signature": "void get_controlPoints(std::list<vpImagePoint>&)",
"use_default_param_policy": false,
"param_is_input": [false],
"param_is_output": [true]
}
]
},
Expand Down Expand Up @@ -773,6 +809,21 @@
true,
false
]
},
{
"static": true,
"signature": "bool getKeyboardEvent(const vpImage<unsigned char>&, std::string&, bool)",
"use_default_param_policy": false,
"param_is_input": [
true,
false,
true
],
"param_is_output": [
false,
true,
false
]
}
]
},
Expand Down
36 changes: 18 additions & 18 deletions modules/python/config/core_image.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,24 +68,24 @@
"ignore": true
}
]
},
"vpRGBf": {
"methods": [
{
"static": false,
"signature": "vpRGBf& operator=(const vpRGBf&&)",
"ignore": true
}
]
},
"vpRGBa": {
"methods": [
{
"static": false,
"signature": "vpRGBa& operator=(const vpRGBa&&)",
"ignore": true
}
]
}
},
"vpRGBf": {
"methods": [
{
"static": false,
"signature": "vpRGBf& operator=(const vpRGBf&&)",
"ignore": true
}
]
},
"vpRGBa": {
"methods": [
{
"static": false,
"signature": "vpRGBa& operator=(const vpRGBa&&)",
"ignore": true
}
]
}
}
46 changes: 20 additions & 26 deletions modules/python/generator/visp_python_bindgen/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,35 +380,29 @@ def add_method_doc_to_pyargs(method: types.Method, py_arg_strs: List[str]) -> Li
elif len(params_strs) < 1:
for cpp_op, python_op_name in unary_return_ops.items():
if method_name == f'operator{cpp_op}':
operator_str = f'''
{python_ident}.def("__{python_op_name}__", []({"const" if method_is_const else ""} {name_cpp}& self) -> {return_type_str} {{
return {cpp_op}self;
}}, {", ".join(py_args)});'''
operator_str = lambda_const_return_unary_op(python_ident, python_op_name, cpp_op,
method_is_const, name_cpp,
return_type_str, py_args)
add_to_method_dict(f'__{python_op_name}__', MethodBinding(operator_str, is_static=False, is_lambda=True,
is_operator=True, is_constructor=False))
break

logging.info(f'Found unary operator {name_cpp}::{method_name}, skipping')
continue
for cpp_op, python_op_name in binary_return_ops.items():
if method_name == f'operator{cpp_op}':
operator_str = f'''
{python_ident}.def("__{python_op_name}__", []({"const" if method_is_const else ""} {name_cpp}& self, {params_strs[0]} o) -> {return_type_str} {{
return (self {cpp_op} o);
}}, {", ".join(py_args)});'''
add_to_method_dict(f'__{python_op_name}__', MethodBinding(operator_str, is_static=False, is_lambda=True,
is_operator=True, is_constructor=False))
break
for cpp_op, python_op_name in binary_in_place_ops.items():
if method_name == f'operator{cpp_op}':
operator_str = f'''
{python_ident}.def("__{python_op_name}__", []({"const" if method_is_const else ""} {name_cpp}& self, {params_strs[0]} o) -> {return_type_str} {{
self {cpp_op} o;
return self;
}}, {", ".join(py_args)});'''
add_to_method_dict(f'__{python_op_name}__', MethodBinding(operator_str, is_static=False, is_lambda=True,
is_operator=True, is_constructor=False))
break
elif len(params_strs) == 1: # e.g., self + other
for cpp_op, python_op_name in binary_return_ops.items():
if method_name == f'operator{cpp_op}':
operator_str = lambda_const_return_binary_op(python_ident, python_op_name, cpp_op,
method_is_const, name_cpp, params_strs[0],
return_type_str, py_args)
add_to_method_dict(f'__{python_op_name}__', MethodBinding(operator_str, is_static=False, is_lambda=True,
is_operator=True, is_constructor=False))
break
for cpp_op, python_op_name in binary_in_place_ops.items():
if method_name == f'operator{cpp_op}':
operator_str = lambda_in_place_binary_op(python_ident, python_op_name, cpp_op,
method_is_const, name_cpp, params_strs[0],
return_type_str, py_args)
add_to_method_dict(f'__{python_op_name}__', MethodBinding(operator_str, is_static=False, is_lambda=True,
is_operator=True, is_constructor=False))
break

# Define classical methods
class_def_names = BoundObjectNames(python_ident, name_python, name_cpp_no_template, name_cpp)
Expand Down
30 changes: 27 additions & 3 deletions modules/python/generator/visp_python_bindgen/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ def supported_const_return_binary_op_map():
'^': 'xor',
}

def lambda_const_return_binary_op(python_ident: str, python_op_name: str, cpp_op: str, method_is_const: bool,
cpp_type: str, param_type: str, return_type: str, py_args: List[str]) -> str:
return f'''
{python_ident}.def("__{python_op_name}__", []({"const" if method_is_const else ""} {cpp_type}& self, {param_type} o) -> {return_type} {{
return (self {cpp_op} o);
}}, {", ".join(py_args)});'''

def supported_in_place_binary_op_map():
return {
'+=': 'iadd',
Expand All @@ -101,11 +108,28 @@ def supported_in_place_binary_op_map():
'/=': 'itruediv',
}

def lambda_in_place_binary_op(python_ident: str, python_op_name: str, cpp_op: str, method_is_const: bool,
cpp_type: str, param_type: str, return_type: str, py_args: List[str]) -> str:
return f'''
{python_ident}.def("__{python_op_name}__", []({"const" if method_is_const else ""} {cpp_type}& self, {param_type} o) -> {return_type} {{
self {cpp_op} o;
return self;
}}, {", ".join(py_args)});'''

def supported_const_return_unary_op_map():
return {
'-': 'neg',
'~': 'invert',
}

def lambda_const_return_unary_op(python_ident: str, python_op_name: str, cpp_op: str, method_is_const: bool,
cpp_type: str, return_type: str, py_args: List[str]) -> str:
return f'''
{python_ident}.def("__{python_op_name}__", []({"const" if method_is_const else ""} {cpp_type}& self) -> {return_type} {{
return {cpp_op}self;
}}, {", ".join(py_args)});'''


def find_and_define_repr_str(cls: ClassScope, cls_name: str, python_ident: str) -> str:
for friend in cls.friends:
if friend.fn is not None:
Expand Down Expand Up @@ -419,13 +443,13 @@ def get_bindable_methods_with_config(submodule: 'Submodule', methods: List[types
(lambda m, _: not m.constructor and is_unsupported_return_type(m.return_type), NotGeneratedReason.ReturnType)
]
for method in methods:
method_config = submodule.get_method_config(cls_name, method, specializations, mapping)
method_config = submodule.get_method_config(cls_name, method, {}, mapping)
method_can_be_bound = True
for predicate, motive in filtering_predicates_and_motives:
if predicate(method, method_config):
return_str = '' if method.return_type is None else (get_type(method.return_type, specializations, mapping) or '<unparsed>')
return_str = '' if method.return_type is None else (get_type(method.return_type, {}, mapping) or '<unparsed>')
method_name = '::'.join(seg.name for seg in method.name.segments)
param_strs = [get_type(param.type, specializations, mapping) or '<unparsed>' for param in method.parameters]
param_strs = [get_type(param.type, {}, mapping) or '<unparsed>' for param in method.parameters]
rejected_methods.append(RejectedMethod(cls_name, method, method_config, get_method_signature(method_name, return_str, param_strs), motive))
method_can_be_bound = False
break
Expand Down

0 comments on commit 36ad312

Please sign in to comment.