Extracting method from nested enum

Hello,

I am currently using nested enumerations to organize different objects in a game. The (simplified) hierarchy looks like this:

Entity
....|--> Agent
....|--> Obstacle
................|--> Ball
................|--> Rectangle

struct Agent;

struct Ball;

struct Rectangle;

enum Obstacle {
    Rectangle(Rectangle),
    Ball(Ball)
}

enum Entity {
    Object(Object),
    Agent(Agent)
}

I want the Entity enumeration to implement the Distance trait,

trait Distance {
    fn distance(&self, x: Vector3<f64>) -> f64;
}

which is implemented for each terminal entity variant

impl Distance for Ball {
    fn distance(&self, x: Vector3<f64>) -> f64 { ... }
}

impl Distance for Rectangle {
    fn distance(&self, x: Vector3<f64>) -> f64 { ... }
}

impl Distance for Agent {
    fn distance(&self, x: Vector3<f64>) -> f64 { ... }
}

My question is: How can I implement/access this trait at the Entity level ? The way I managed to do it involves a lot of code duplication (especially since in reality the Distance trait consists of several methods), and needs to be updated as the hierarchy grows, which is not ideal:

impl Distance for Obstacle {
    fn distance(&self, x: Vector3<f64>) -> f64 {
        match self {
            Self::Rectangle(rectangle) => rectangle.distance(x),
            Self::Ball(ball) => ball.distance(x),
        }
    }
}

impl Distance for Entity {
    fn distance(&self, x: Vector3<f64>) -> f64 {
        match self {
            Self::Agent(agent) => agent.distance(x),
            Self::Obstacle(obstacle) => obstacle.distance(x),
        }
    }
}

Is there a better way to access the distance method / to implement the Distance trait at the Entity level ? Or is there a better way to organize objects in order to do so ?

You're trying to do inheritance. Rust doesn't have inheritance. You might use traits for this, and implement some Position trait for the objects that will give them distance you can uniformly access.

You will also run into the problem of mutably referencing other entities, which goes against Rust's strictness about references and preference for immutability.

Here's a talk about such game desing, and Rust-friendly alternative of ECS:

Thank you for your answer, it's very helpful ! It seems like I have some reading to do before tackling the implementation :slight_smile:

Good luck!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.