feat: sync part physics on property change

This commit is contained in:
maelstrom 2025-02-01 14:35:06 +01:00
parent 211e667351
commit eb6436d683
4 changed files with 16 additions and 3 deletions

View file

@ -96,6 +96,7 @@ tl::expected<void, MemberNotFound> Instance::SetPropertyValue(std::string name,
if (!meta) return tl::make_unexpected(MemberNotFound()); if (!meta) return tl::make_unexpected(MemberNotFound());
meta->codec.write(value, meta->backingField); meta->codec.write(value, meta->backingField);
if (meta->updateCallback) meta->updateCallback.value()(name);
return {}; return {};
} }

View file

@ -2,6 +2,7 @@
#include "../../datatypes/base.h" #include "../../datatypes/base.h"
#include "datatypes/meta.h" #include "datatypes/meta.h"
#include <functional>
#include <map> #include <map>
#include <memory> #include <memory>
#include <optional> #include <optional>
@ -32,10 +33,16 @@ constexpr FieldCodec fieldCodecOf() {
}; };
} }
template <typename T>
std::function<void(std::string name)> memberFunctionOf(void(T::*func)(std::string), T* obj) {
return std::bind(func, obj, std::placeholders::_1);
}
struct PropertyMeta { struct PropertyMeta {
void* backingField; void* backingField;
const Data::TypeInfo* type; const Data::TypeInfo* type;
FieldCodec codec; FieldCodec codec;
std::optional<std::function<void(std::string name)>> updateCallback;
}; };
typedef std::variant<PropertyMeta> MemberMeta; typedef std::variant<PropertyMeta> MemberMeta;

View file

@ -4,6 +4,7 @@
#include "objects/base/member.h" #include "objects/base/member.h"
#include <memory> #include <memory>
#include <optional> #include <optional>
#include "physics/simulation.h"
static InstanceType TYPE_ { static InstanceType TYPE_ {
.super = Instance::TYPE, .super = Instance::TYPE,
@ -22,12 +23,11 @@ Part::Part(): Part(PartConstructParams {}) {
} }
Part::Part(PartConstructParams params): Instance(&TYPE_), position(params.position), rotation(params.rotation), Part::Part(PartConstructParams params): Instance(&TYPE_), position(params.position), rotation(params.rotation),
scale(params.scale), material(params.material), anchored(params.anchored) { scale(params.scale), material(params.material), anchored(params.anchored) {
this->memberMap = std::make_unique<MemberMap>(MemberMap { this->memberMap = std::make_unique<MemberMap>(MemberMap {
.super = std::move(this->memberMap), .super = std::move(this->memberMap),
.members = { .members = {
{ "Anchored", { .backingField = &anchored, .type = &Data::Bool::TYPE, .codec = fieldCodecOf<Data::Bool, bool>() } } { "Anchored", { .backingField = &anchored, .type = &Data::Bool::TYPE, .codec = fieldCodecOf<Data::Bool, bool>(), .updateCallback = memberFunctionOf(&Part::onUpdated, this) } }
} }
}); });
} }
@ -46,4 +46,8 @@ void Part::OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, s
this->rigidBody->setIsActive(newParent.has_value()); this->rigidBody->setIsActive(newParent.has_value());
// TODO: Sleeping bodies that touch this one also need to be updated // TODO: Sleeping bodies that touch this one also need to be updated
}
void Part::onUpdated(std::string property) {
syncPartPhysics(std::dynamic_pointer_cast<Part>(this->shared_from_this()));
} }

View file

@ -22,6 +22,7 @@ struct PartConstructParams {
class Part : public Instance { class Part : public Instance {
protected: protected:
void OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) override; void OnParentUpdated(std::optional<std::shared_ptr<Instance>> oldParent, std::optional<std::shared_ptr<Instance>> newParent) override;
void onUpdated(std::string);
public: public:
static InstanceType* TYPE; static InstanceType* TYPE;