From 1bf347087318ee2efa2c7bd701a0afd16f528eab Mon Sep 17 00:00:00 2001 From: Orkuncakilkaya Date: Mon, 28 Sep 2026 17:09:00 +0300 Subject: [PATCH] render3d: a model owns its skin - @creates(Skin) skin_load, @releases(Skin) skin_free, @owns on Model.skin resource_drops 0 and owned_leaks 0 over main. Compiled (steady). Co-Authored-By: Claude Opus 5.5 --- packages/ludic.render3d/gltf.ludic | 2 +- packages/ludic.render3d/skin.ludic | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/ludic.render3d/gltf.ludic b/packages/ludic.render3d/gltf.ludic index 8544b1e4..f3804237 100644 --- a/packages/ludic.render3d/gltf.ludic +++ b/packages/ludic.render3d/gltf.ludic @@ -19,7 +19,7 @@ property Model { height: float = 0.0, # float bits: y extent above ymin ymin: float = 0.0, tris: int = 0, - skin: Skin # the skeleton, for a skinned node (skin.ludic); null for a rigid model + @owns(Skin) skin: Skin # the skeleton, for a skinned node (skin.ludic); null for a rigid model } diff --git a/packages/ludic.render3d/skin.ludic b/packages/ludic.render3d/skin.ludic index 03175ca2..da91ee1d 100644 --- a/packages/ludic.render3d/skin.ludic +++ b/packages/ludic.render3d/skin.ludic @@ -73,6 +73,7 @@ function skin_attribs(render3d_st: mut Render3dState, m: Mesh, attrs: Val) -> bo # the skin `idx` of the document being loaded (gltf_load holds gltf_doc / gltf_bin open) @alloc_ok("loading a model, a texture or a font: a load, not a frame (a guest loading a teammate's look is one)") +@creates(Skin) function skin_load(render3d_st: mut Render3dState, idx: int) -> Skin { let sk = new Skin let nodes = value_get(render3d_st.gltf_doc, "nodes") @@ -233,6 +234,7 @@ function skin_clone(src: Skin) -> Skin { # A skin loaded with a model, let go with it (model_release): every array it owns, its joints' names # and itself. The views into gmat, inv_bind and bones are slices of those, and freeing a view would # free its owner's data again, so only the lists that hold them go (a few bytes a joint stay). +@releases(Skin) function skin_free(sk: Skin) -> void { if sk == null { return } if sk.names != null {