Skip to content

GameMesh leaks a ModelCache reference if construction throws partway through #3

Description

@CanReader

Looking at the main GameMesh constructor (the one used for every downloaded building model):

public GameMesh(String name, Vector3 position, Vector3 rotation, Vector3 scale, btDynamicsWorld world) {
    super(name);
    this.world = world;

    this.sceneAsset = ModelCache.acquire(name);   // refcount incremented here
    if (sceneAsset == null)
        throw new IllegalArgumentException("Failed to load model: " + name);

    this.instance = GltfModelFiles.buildInstance(sceneAsset, name, position);  // can throw
    this.bounds = instance.model.calculateBoundingBox(new BoundingBox());
    this.bounds.mul(instance.transform);

    this.body = createStaticBody(boxShapeFromModel());  // can throw too
    world.addRigidBody(body);
}

ModelCache.acquire(name) increments the shared refcount for that building's model before the rest of construction runs. If GltfModelFiles.buildInstance(...) or createStaticBody(boxShapeFromModel()) throws partway through (malformed GLTF node, bad bounding box, whatever), the constructor throws and the GameMesh object never finishes being built. Since it never exists as a usable object, nobody can ever call dispose() on it, which is the only thing that calls ModelCache.release(name).

So that one acquire() just leaks. The cache's refcount for that building type is now permanently one higher than the number of real live instances, which means ModelCache.release() calls from every legitimate instance of that building will never bring the count to zero, and the shared model (and its GPU textures) never gets disposed for the rest of the app's life, even after the player deletes every instance of that building.

Would probably want a try/catch around the post-acquire construction that releases the reference back before rethrowing, something like:

this.sceneAsset = ModelCache.acquire(name);
if (sceneAsset == null) throw new IllegalArgumentException(...);
try {
    this.instance = GltfModelFiles.buildInstance(sceneAsset, name, position);
    ...
} catch (RuntimeException e) {
    ModelCache.release(name);
    throw e;
}

File: core/src/com/focus/kingdom/entity/GameMesh.java, the constructor around line 98-114.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions