#include "physics/PhysicsLink.h" #include "physics/Body.h" #include "physics/Body3D.h" #include "physics/Joint3D.h" #include "physics/Shape3D.h" #include "physics/World.h" #include "physics/World3D.h" namespace eve::physics { namespace { eve::Diagnostic invalidLinkDiagnostic(const char* path, const char* message) { return eve::Diagnostic::error(eve::DiagnosticCode::InvalidArgument, message, path); } eve::Diagnostic staleLinkDiagnostic(const char* path) { return eve::Diagnostic::error(eve::DiagnosticCode::StaleHandle, "Physics link does not resolve to a live object owned by this world", path); } template eve::Result attachLink(PhysicsWorldHandle world, Handle handle, const char* path, const char* message) { if (world.isInvalid() || handle.isInvalid()) return eve::Result::failure(invalidLinkDiagnostic(path, message)); return eve::Result::success(Link{world, handle}); } } // namespace eve::Result PhysicsLink::attach(PhysicsWorldHandle world, PhysicsBodyHandle body) { if (world.isInvalid() || body.isInvalid()) { return eve::Result::failure( invalidLinkDiagnostic("physics.link", "PhysicsLink requires valid world and body handles")); } return eve::Result::success({world, body}); } eve::Result PhysicsLink::fromBody(const Body& body) { const World* world = body.getWorld(); if (!body.isValid() || !world || !world->isValid()) { return eve::Result::failure(staleLinkDiagnostic("physics.link.body")); } return attach(world->runtimeHandle(), body.runtimeHandle()); } eve::Result PhysicsLink::fromBody(const Body3D& body) { const World3D* world = body.getWorld(); if (!body.isValid() || !world || !world->isValid()) { return eve::Result::failure(staleLinkDiagnostic("physics.link.body3d")); } return attach(world->runtimeHandle(), body.runtimeHandle()); } eve::Result PhysicsLink::resolve(World& world) const { if (!isValid() || world.runtimeHandle() != this->world) { return eve::Result::failure(staleLinkDiagnostic("physics.link.resolve")); } Body* resolved = world.findBody(body); if (!resolved) { return eve::Result::failure(staleLinkDiagnostic("physics.link.resolve")); } return eve::Result::success(resolved); } eve::Result PhysicsLink::resolve(World3D& world) const { if (!isValid() || world.runtimeHandle() != this->world) { return eve::Result::failure(staleLinkDiagnostic("physics.link.resolve3d")); } Body3D* resolved = world.findBody(body); if (!resolved) { return eve::Result::failure(staleLinkDiagnostic("physics.link.resolve3d")); } return eve::Result::success(resolved); } eve::Result PhysicsShapeLink::attach(PhysicsWorldHandle world, PhysicsShapeHandle shape) { return attachLink(world, shape, "physics.shapeLink", "PhysicsShapeLink requires valid world and shape handles"); } eve::Result PhysicsShapeLink::fromShape(const Shape3D& shape) { const Body3D* body = shape.getBody(); const World3D* world = body ? body->getWorld() : nullptr; if (!shape.isValid() || !body || !world || !world->isValid()) return eve::Result::failure(staleLinkDiagnostic("physics.shapeLink.shape")); return attach(world->runtimeHandle(), shape.runtimeHandle()); } eve::Result PhysicsShapeLink::resolve(World3D& world) const { if (!isValid() || world.runtimeHandle() != this->world) return eve::Result::failure(staleLinkDiagnostic("physics.shapeLink.resolve")); Shape3D* resolved = world.findShape(shape); if (!resolved) return eve::Result::failure(staleLinkDiagnostic("physics.shapeLink.resolve")); return eve::Result::success(resolved); } eve::Result PhysicsJointLink::attach(PhysicsWorldHandle world, PhysicsJointHandle joint) { return attachLink(world, joint, "physics.jointLink", "PhysicsJointLink requires valid world and joint handles"); } eve::Result PhysicsJointLink::fromJoint(const Joint3D& joint) { World3D* world = joint.getWorld(); if (!joint.isValid() || !world || !world->isValid()) return eve::Result::failure(staleLinkDiagnostic("physics.jointLink.joint")); return attach(world->runtimeHandle(), joint.runtimeHandle()); } eve::Result PhysicsJointLink::resolve(World3D& world) const { if (!isValid() || world.runtimeHandle() != this->world) return eve::Result::failure(staleLinkDiagnostic("physics.jointLink.resolve")); Joint3D* resolved = world.findJoint(joint); if (!resolved) return eve::Result::failure(staleLinkDiagnostic("physics.jointLink.resolve")); return eve::Result::success(resolved); } } // namespace eve::physics