diff --git a/common/src/api/java/dev/engine_room/flywheel/api/model/Model.java b/common/src/api/java/dev/engine_room/flywheel/api/model/Model.java index 9ad458193..e3d42fdd5 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/model/Model.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/model/Model.java @@ -2,12 +2,10 @@ package dev.engine_room.flywheel.api.model; import java.util.List; -import dev.engine_room.flywheel.api.instance.InstanceType; - -import dev.engine_room.flywheel.api.instance.InstancerProvider; - import org.joml.Vector4fc; +import dev.engine_room.flywheel.api.instance.InstanceType; +import dev.engine_room.flywheel.api.instance.InstancerProvider; import dev.engine_room.flywheel.api.material.Material; public interface Model { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/SimpleQuadMesh.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/SimpleQuadMesh.java index 92e1e9372..e7ff25a5b 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/SimpleQuadMesh.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/SimpleQuadMesh.java @@ -6,25 +6,21 @@ import org.joml.Vector4fc; import dev.engine_room.flywheel.api.vertex.MutableVertexList; import dev.engine_room.flywheel.api.vertex.VertexList; -import dev.engine_room.flywheel.lib.memory.MemoryBlock; public final class SimpleQuadMesh implements QuadMesh { private final VertexList vertexList; - // Unused but we need to hold on to a reference so the cleaner doesn't nuke us. - private final MemoryBlock data; private final Vector4f boundingSphere; @Nullable private final String descriptor; - public SimpleQuadMesh(VertexList vertexList, MemoryBlock data, @Nullable String descriptor) { + public SimpleQuadMesh(VertexList vertexList, @Nullable String descriptor) { this.vertexList = vertexList; - this.data = data; boundingSphere = ModelUtil.computeBoundingSphere(vertexList); this.descriptor = descriptor; } - public SimpleQuadMesh(VertexList vertexList, MemoryBlock data) { - this(vertexList, data, null); + public SimpleQuadMesh(VertexList vertexList) { + this(vertexList, null); } @Override diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java index 6adb15dac..05bff07e0 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java @@ -41,7 +41,8 @@ final class MeshHelper { vertexView.ptr(dstPtr); vertexView.vertexCount(vertexCount); + vertexView.nativeMemoryOwner(dst); - return new SimpleQuadMesh(vertexView, dst, meshDescriptor); + return new SimpleQuadMesh(vertexView, meshDescriptor); } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java index c03ba9ec7..1e4a17d27 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelPartConverter.java @@ -37,7 +37,7 @@ public final class ModelPartConverter { VertexView vertexView = new PosTexNormalVertexView(); vertexView.load(data); - return new SimpleQuadMesh(vertexView, data, "source=ModelPartConverter"); + return new SimpleQuadMesh(vertexView, "source=ModelPartConverter"); } public static Mesh convert(ModelLayerLocation layer, @Nullable TextureAtlasSprite sprite, String... childPath) { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java index b6752ee17..7a7b506f3 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java @@ -1,8 +1,12 @@ package dev.engine_room.flywheel.lib.vertex; +import org.jetbrains.annotations.Nullable; + public abstract class AbstractVertexView implements VertexView { protected long ptr; protected int vertexCount; + @Nullable + private Object nativeMemoryOwner; @Override public long ptr() { @@ -23,4 +27,15 @@ public abstract class AbstractVertexView implements VertexView { public void vertexCount(int vertexCount) { this.vertexCount = vertexCount; } + + @Override + @Nullable + public final Object nativeMemoryOwner() { + return nativeMemoryOwner; + } + + @Override + public final void nativeMemoryOwner(@Nullable Object owner) { + nativeMemoryOwner = owner; + } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java index 1336153cd..4c60462a2 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java @@ -1,5 +1,6 @@ package dev.engine_room.flywheel.lib.vertex; +import org.jetbrains.annotations.Nullable; import org.lwjgl.system.MemoryUtil; import dev.engine_room.flywheel.api.vertex.MutableVertexList; @@ -14,6 +15,17 @@ public interface VertexView extends MutableVertexList { long stride(); + @Nullable + Object nativeMemoryOwner(); + + /** + * The memory referenced by this vertex view's pointer may be owned by another object, such that the memory is + * automatically freed when the other object becomes phantom reachable or is garbage collected. Use this method to + * ensure this vertex view retains a strong reference to the memory owner so this vertex view's pointer remains + * valid even when no other references to the memory owner are retained. + */ + void nativeMemoryOwner(@Nullable Object owner); + default void load(MemoryBlock data) { long bytes = data.size(); long stride = stride(); @@ -24,6 +36,7 @@ public interface VertexView extends MutableVertexList { ptr(data.ptr()); vertexCount(vertexCount); + nativeMemoryOwner(data); } @Override