-
In python, I can change an object's 3D position by doing: newPos = Vector3(2, 4, 9)
entity.position = newPos What happens behind the curtains when I do that is that I call a function named setPos that updates the entity position, as well as the entity rigidbody's properties, using pybind11's .def_property: py::class_<Entity>(entity_module, "Entity")
// ...
.def_property("position",
[](const Entity& entity) { return entity.position; },
[](Entity& entity, LitVector3& position) { entity.setPos(position); })
// ... However, I can't update the entity's position and rigidbody's position if I try to access and modify the position properties directly: entity.position.x = 2
entity.position.y += 4 How can I call entity.setPos in c++ when I change the entity.position.x/y/z instead of only being when I attribute something to entity.position? The function setPos() should only be called in c++'s side and the supported python syntax needs to be:
Currently, I can only support |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Hi @luis605 , I am not sure about all details of your library. However it is possible, you need to return pointer to the vector structure. If you don't do this, there is no proper ownership over the vector which results in "no updates". It might not be a perfect solution, you can probably do it in a slightly different way without exposing Cheers, I hope that helps! Here is small reproducer: class Vector3 {
public:
Vector3(int _x, int _y, int _z): x(_x), y(_y), z(_z) {}
int x;
int y;
int z;
};
class Entity {
public:
Entity() : position(Vector3(0, 0, 0)) {}
Entity(Vector3& _position) : position(_position) {}
Vector3* getPos() { // this is important!
return &position;
}
void setPos(Vector3& _position) {
position = _position;
}
Vector3 position;
};
PYBIND11_MODULE(mymodule, m)
{
m.doc() = "This is the module test";
py::class_<Vector3>(m, "Vector3")
.def(py::init<int, int, int>())
.def_property("x",
[](Vector3& position) { return position.x; },
[](Vector3& position, int value) { position.x = value; })
.def_property("y",
[](Vector3& position) { return position.y; },
[](Vector3& position, int value) { position.y = value; })
.def_property("z",
[](Vector3& position) { return position.z; },
[](Vector3& position, int value) { position.z = value; })
.def("__repr__",
[](Vector3& position) {
return "(" + std::to_string(position.x) + ", " + std::to_string(position.y) + ", " + std::to_string(position.z) + ")";
});
py::class_<Entity>(m, "Entity")
.def(py::init<>())
.def(py::init<Vector3&>())
.def_property("position",
[](Entity& entity) { return entity.getPos(); },
[](Entity& entity, Vector3& position) { entity.setPos(position); });
} With results from Python: In [1]: import mymodule
...:
...: entity = mymodule.Entity()
...:
...: newPos = mymodule.Vector3(2, 4, 9)
...: entity.position = newPos
...:
...: print(entity.position)
...:
...: entity.position.x = 111
...: entity.position.y += 440
...:
...: print(entity.position)
(2, 4, 9)
(111, 444, 9) |
Beta Was this translation helpful? Give feedback.
Hi @luis605 , I am not sure about all details of your library. However it is possible, you need to return pointer to the vector structure. If you don't do this, there is no proper ownership over the vector which results in "no updates". It might not be a perfect solution, you can probably do it in a slightly different way without exposing
getPos
and getting policies right to fit your needs/project. You can read more about returning values here: https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policiesCheers, I hope that helps!
Here is small reproducer: