customrealms / core

Core library for the CustomRealms runtime
https://customrealms.io/core
MIT License
35 stars 13 forks source link

Casting between entity types #8

Closed connerdouglass closed 2 years ago

connerdouglass commented 2 years ago

If you get an Entity from some API call (World.getEntities() for instance) we are able to check the type with Entity.getType() but we can't actually cast the entity to the correct instance type. Everything is stuck as the base class.

I think we need to update Entity.fromJava(...) to construct an instance of the proper entity subclass, based on the entity's specific type. This would enable us to do convenient if (entity instanceof Player) checks.

Here's the Entity.fromJava function today:

public static fromJava(_entity: Java.Value): Entity {
    return new Entity(_entity);
}

Here's roughly what I'm thinking it should become:

// Mapping of entity types to the appropriate subclass
const ENTITY_TYPE_TO_CLASS: {[key in EntityType]?: Constructor<Entity>} = {
    [EntityType.PLAYER]: Player,
    [EntityType.ENDERMAN]: Enderman,
    [EntityType.SHEEP]: Sheep,
    // etc...
};

public static fromJava(_entity: Java.Value): Entity {
    // Construct the correct type of Entity
    const entityType: EntityType = _entity.getType().name();
    if (entityType in ENTITY_TYPE_TO_CLASS) {
        return new (ENTITY_TYPE_TO_CLASS[entityType])(_entity);
    }
    return new Entity(_entity); // Fallback to just an Entity instance
}

Want to discuss design considerations before implementing this.

I don't like the idea of Entity needing to import all of its subclasses, so maybe this should be split off into a utility function elsewhere.

AL1L commented 2 years ago

You could just make the EntityType enum have the constructor for the entity as its value?

connerdouglass commented 2 years ago

@AL1L That would make this situation easier, but would remove the ability to console.log an entity's type. In my example above ENTITY_TYPE_TO_CLASS does what you're suggesting, just separate from the enum itself.

I have an idea for how to get the best of both worlds. I'll give it a shot and have you review the PR