Skip to content

Commit 8f2b4d0

Browse files
committed
Remove CRTP and uses less error casting prone pattern
1 parent 8418e3e commit 8f2b4d0

5 files changed

Lines changed: 97 additions & 144 deletions

File tree

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Component.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ namespace sofapython3
3030
using sofa::core::objectmodel::Event;
3131
using sofa::core::objectmodel::BaseComponent;
3232

33+
// ---------------------------------------------------------------------------
34+
// Component_Trampoline
35+
// ---------------------------------------------------------------------------
36+
37+
Component_Trampoline::Component_Trampoline()
38+
: TrampolineBase(this) // pass this as BaseComponent* — no CRTP needed
39+
{
40+
}
3341

3442
void Component_Trampoline::draw(const sofa::core::visual::VisualParams* params)
3543
{
@@ -41,7 +49,6 @@ void Component_Trampoline::draw(const sofa::core::visual::VisualParams* params)
4149
void Component_Trampoline::init()
4250
{
4351
PythonEnvironment::executePython(this, [this](){
44-
// Initialize the Python object cache on first init
4552
initializePythonCache();
4653
PYBIND11_OVERLOAD(void, Component, init, );
4754
});
@@ -54,7 +61,6 @@ void Component_Trampoline::reinit()
5461
});
5562
}
5663

57-
5864
void Component_Trampoline::handleEvent(sofa::core::objectmodel::Event* event)
5965
{
6066
trampoline_handleEvent(event);
@@ -65,6 +71,10 @@ std::string Component_Trampoline::getClassName() const
6571
return trampoline_getClassName();
6672
}
6773

74+
// ---------------------------------------------------------------------------
75+
// Module registration
76+
// ---------------------------------------------------------------------------
77+
6878
void moduleAddComponent(py::module &m) {
6979
py::class_<Component,
7080
Component_Trampoline,
@@ -73,8 +83,8 @@ void moduleAddComponent(py::module &m) {
7383
py::dynamic_attr(),
7484
sofapython3::doc::component::componentClass);
7585

76-
f.def(py::init(&Trampoline_T<Component_Trampoline>::_init_));
77-
f.def("__setattr__",&Trampoline_T<Component_Trampoline>::_setattr_);
86+
f.def(py::init(&trampoline_init<Component_Trampoline>));
87+
f.def("__setattr__", &trampoline_setattr<Component_Trampoline>);
7888

7989
f.def("init", &Component::init);
8090
f.def("reinit", &Component::reinit);
@@ -83,6 +93,4 @@ void moduleAddComponent(py::module &m) {
8393
}, pybind11::return_value_policy::reference);
8494
}
8595

86-
87-
88-
}
96+
} // namespace sofapython3

bindings/Sofa/src/SofaPython3/Sofa/Core/Binding_Component.h

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -28,81 +28,63 @@
2828
namespace sofapython3 {
2929

3030

31-
template<class T>
32-
class Trampoline_T
31+
class TrampolineBase
3332
{
3433
public:
35-
36-
virtual ~Trampoline_T();
37-
34+
explicit TrampolineBase(sofa::core::objectmodel::BaseComponent* self);
35+
virtual ~TrampolineBase();
3836

3937
void trampoline_handleEvent(sofa::core::objectmodel::Event* event);
40-
4138
std::string trampoline_getClassName() const;
42-
43-
/// Invalidates a specific entry in the method cache (called when a user reassigns an on* attribute)
4439
void invalidateMethodCache(const std::string& methodName);
4540

46-
static sofa::core::sptr<T> _init_(pybind11::args& /*args*/, pybind11::kwargs& kwargs);
47-
48-
static void _setattr_(pybind11::object self, const std::string& s, pybind11::object value);
49-
5041
protected:
51-
/// Initializes the Python object cache (m_pySelf and method cache)
5242
void initializePythonCache();
53-
54-
/// Returns a cached method if it exists, or an empty object if not
5543
pybind11::object getCachedMethod(const std::string& methodName);
56-
57-
/// Calls a cached Python method with the given event
5844
bool callCachedMethod(const pybind11::object& method, sofa::core::objectmodel::Event* event);
59-
60-
/// Legacy method for uncached calls (fallback)
6145
bool callScriptMethod(const pybind11::object& self, sofa::core::objectmodel::Event* event,
62-
const std::string& methodName);
46+
const std::string& methodName);
6347

64-
/// Cached Python self reference (avoids repeated py::cast(this))
65-
pybind11::object m_pySelf;
48+
/// Raw non-owning pointer to the concrete trampoline as BaseComponent.
49+
/// Safe because TrampolineBase is always embedded in the same object.
50+
sofa::core::objectmodel::BaseComponent* m_componentSelf { nullptr };
6651

67-
/// Cache of Python method objects, keyed by method name (including "onEvent" fallback)
68-
/// Stores the method object if it exists, or an empty object if checked and not found
52+
pybind11::object m_pySelf;
6953
std::unordered_map<std::string, pybind11::object> m_methodCache;
70-
71-
/// Flag indicating whether the cache has been initialized
7254
bool m_cacheInitialized = false;
7355
};
7456

7557

76-
/**
77-
* Empty controller shell that allows pybind11 to bind the init and reinit methods (since BaseComponent doesn't have
78-
* them)
79-
*/
58+
template<class T>
59+
sofa::core::sptr<T> trampoline_init(pybind11::args& /*args*/, pybind11::kwargs& kwargs);
60+
61+
template<class T>
62+
void trampoline_setattr(pybind11::object self, const std::string& s, pybind11::object value);
63+
64+
65+
8066
class Component : public sofa::core::objectmodel::BaseComponent {
8167
public:
8268
SOFA_CLASS(Component, sofa::core::objectmodel::BaseComponent);
83-
void init() override {};
84-
void reinit() override {};
69+
void init() override {}
70+
void reinit() override {}
8571
};
8672

87-
class Component_Trampoline : public Component, public Trampoline_T<Component_Trampoline>
73+
class Component_Trampoline : public Component, public TrampolineBase
8874
{
8975
public:
9076
SOFA_CLASS(Component_Trampoline, Component);
9177

92-
Component_Trampoline() = default;
93-
virtual ~Component_Trampoline() = default;
78+
Component_Trampoline();
79+
~Component_Trampoline() override = default;
9480

9581
void init() override;
9682
void reinit() override;
9783
void draw(const sofa::core::visual::VisualParams* params) override;
98-
9984
void handleEvent(sofa::core::objectmodel::Event* event) override;
100-
10185
std::string getClassName() const override;
102-
10386
};
10487

10588
void moduleAddComponent(pybind11::module &m);
10689

10790
} /// namespace sofapython3
108-

0 commit comments

Comments
 (0)