From 7dd117d318fa1e0a320fb7b2f86d097f4ff55208 Mon Sep 17 00:00:00 2001 From: Jay Dolan Date: Wed, 2 Sep 2026 19:22:01 -0400 Subject: [PATCH 1/3] Adopt zero-length interface members from Objectively Objectively no longer stores an interface pointer on each instance; `$` resolves the interface through Object::clazz, and the struct member exists only to carry a type for typeof. ClassDef.interfaceOffset is gone. Follow suit: each instance struct's interface member becomes a zero-length array, and each ClassDef drops interfaceOffset. No call sites change. See jdolan/Objectively#41. Co-Authored-By: Claude Fable 5.1 --- .github/copilot-instructions.md | 3 +-- Sources/ObjectivelyGPU/Buffer.c | 1 - Sources/ObjectivelyGPU/Buffer.h | 4 ++-- Sources/ObjectivelyGPU/CommandBuffer.c | 1 - Sources/ObjectivelyGPU/CommandBuffer.h | 4 ++-- Sources/ObjectivelyGPU/ComputePass.c | 1 - Sources/ObjectivelyGPU/ComputePass.h | 4 ++-- Sources/ObjectivelyGPU/ComputePipeline.c | 1 - Sources/ObjectivelyGPU/ComputePipeline.h | 4 ++-- Sources/ObjectivelyGPU/CopyPass.c | 1 - Sources/ObjectivelyGPU/CopyPass.h | 4 ++-- Sources/ObjectivelyGPU/Fence.c | 1 - Sources/ObjectivelyGPU/Fence.h | 4 ++-- Sources/ObjectivelyGPU/Framebuffer.c | 1 - Sources/ObjectivelyGPU/Framebuffer.h | 4 ++-- Sources/ObjectivelyGPU/GraphicsPipeline.c | 1 - Sources/ObjectivelyGPU/GraphicsPipeline.h | 4 ++-- Sources/ObjectivelyGPU/QueryPool.c | 1 - Sources/ObjectivelyGPU/QueryPool.h | 4 ++-- Sources/ObjectivelyGPU/RenderDevice.c | 1 - Sources/ObjectivelyGPU/RenderDevice.h | 4 ++-- Sources/ObjectivelyGPU/RenderPass.c | 1 - Sources/ObjectivelyGPU/RenderPass.h | 4 ++-- Sources/ObjectivelyGPU/Sampler.c | 1 - Sources/ObjectivelyGPU/Sampler.h | 4 ++-- Sources/ObjectivelyGPU/Shader.c | 1 - Sources/ObjectivelyGPU/Shader.h | 4 ++-- Sources/ObjectivelyGPU/Texture.c | 1 - Sources/ObjectivelyGPU/Texture.h | 4 ++-- Sources/ObjectivelyGPU/TransferBuffer.c | 1 - Sources/ObjectivelyGPU/TransferBuffer.h | 4 ++-- 31 files changed, 31 insertions(+), 47 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index e72a9a9..0984861 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -45,7 +45,7 @@ typedef struct FooInterface FooInterface; */ struct Foo { Bar bar; // superclass is always first - FooInterface *interface; // @protected + FooInterface *interface[0]; // @protected int publicField; SomeType *privateField; // @private }; @@ -130,7 +130,6 @@ Class *_Foo(void) { .name = "Foo", .superclass = _Bar(), .instanceSize = sizeof(Foo), - .interfaceOffset = offsetof(Foo, interface), .interfaceSize = sizeof(FooInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Buffer.c b/Sources/ObjectivelyGPU/Buffer.c index 78a1688..f1b1cfe 100644 --- a/Sources/ObjectivelyGPU/Buffer.c +++ b/Sources/ObjectivelyGPU/Buffer.c @@ -180,7 +180,6 @@ Class *_Buffer(void) { .name = "Buffer", .superclass = _Object(), .instanceSize = sizeof(Buffer), - .interfaceOffset = offsetof(Buffer, interface), .interfaceSize = sizeof(BufferInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Buffer.h b/Sources/ObjectivelyGPU/Buffer.h index b8e6d6e..66e1750 100644 --- a/Sources/ObjectivelyGPU/Buffer.h +++ b/Sources/ObjectivelyGPU/Buffer.h @@ -66,10 +66,10 @@ struct Buffer { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - BufferInterface *interface; + BufferInterface *interface[0]; /** * @brief The underlying SDL buffer. diff --git a/Sources/ObjectivelyGPU/CommandBuffer.c b/Sources/ObjectivelyGPU/CommandBuffer.c index 617d792..34230cd 100644 --- a/Sources/ObjectivelyGPU/CommandBuffer.c +++ b/Sources/ObjectivelyGPU/CommandBuffer.c @@ -362,7 +362,6 @@ Class *_CommandBuffer(void) { .name = "CommandBuffer", .superclass = _Object(), .instanceSize = sizeof(CommandBuffer), - .interfaceOffset = offsetof(CommandBuffer, interface), .interfaceSize = sizeof(CommandBufferInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/CommandBuffer.h b/Sources/ObjectivelyGPU/CommandBuffer.h index eb4d272..a654075 100644 --- a/Sources/ObjectivelyGPU/CommandBuffer.h +++ b/Sources/ObjectivelyGPU/CommandBuffer.h @@ -86,10 +86,10 @@ struct CommandBuffer { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - CommandBufferInterface *interface; + CommandBufferInterface *interface[0]; /** * @brief The underlying SDL command buffer. diff --git a/Sources/ObjectivelyGPU/ComputePass.c b/Sources/ObjectivelyGPU/ComputePass.c index bc32ee3..28aeb7b 100644 --- a/Sources/ObjectivelyGPU/ComputePass.c +++ b/Sources/ObjectivelyGPU/ComputePass.c @@ -154,7 +154,6 @@ Class *_ComputePass(void) { .name = "ComputePass", .superclass = _Object(), .instanceSize = sizeof(ComputePass), - .interfaceOffset = offsetof(ComputePass, interface), .interfaceSize = sizeof(ComputePassInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/ComputePass.h b/Sources/ObjectivelyGPU/ComputePass.h index 1e87afa..ba2fa52 100644 --- a/Sources/ObjectivelyGPU/ComputePass.h +++ b/Sources/ObjectivelyGPU/ComputePass.h @@ -61,10 +61,10 @@ struct ComputePass { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - ComputePassInterface *interface; + ComputePassInterface *interface[0]; /** * @brief The CommandBuffer this pass was begun from. diff --git a/Sources/ObjectivelyGPU/ComputePipeline.c b/Sources/ObjectivelyGPU/ComputePipeline.c index db270e8..f5ea7ea 100644 --- a/Sources/ObjectivelyGPU/ComputePipeline.c +++ b/Sources/ObjectivelyGPU/ComputePipeline.c @@ -97,7 +97,6 @@ Class *_ComputePipeline(void) { .name = "ComputePipeline", .superclass = _Object(), .instanceSize = sizeof(ComputePipeline), - .interfaceOffset = offsetof(ComputePipeline, interface), .interfaceSize = sizeof(ComputePipelineInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/ComputePipeline.h b/Sources/ObjectivelyGPU/ComputePipeline.h index ab39749..528e3b0 100644 --- a/Sources/ObjectivelyGPU/ComputePipeline.h +++ b/Sources/ObjectivelyGPU/ComputePipeline.h @@ -55,10 +55,10 @@ struct ComputePipeline { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - ComputePipelineInterface *interface; + ComputePipelineInterface *interface[0]; /** * @brief The underlying SDL compute pipeline. diff --git a/Sources/ObjectivelyGPU/CopyPass.c b/Sources/ObjectivelyGPU/CopyPass.c index b531540..40df29e 100644 --- a/Sources/ObjectivelyGPU/CopyPass.c +++ b/Sources/ObjectivelyGPU/CopyPass.c @@ -204,7 +204,6 @@ Class *_CopyPass(void) { .name = "CopyPass", .superclass = _Object(), .instanceSize = sizeof(CopyPass), - .interfaceOffset = offsetof(CopyPass, interface), .interfaceSize = sizeof(CopyPassInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/CopyPass.h b/Sources/ObjectivelyGPU/CopyPass.h index 5372677..f643ff0 100644 --- a/Sources/ObjectivelyGPU/CopyPass.h +++ b/Sources/ObjectivelyGPU/CopyPass.h @@ -60,10 +60,10 @@ struct CopyPass { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - CopyPassInterface *interface; + CopyPassInterface *interface[0]; /** * @brief The CommandBuffer this pass was begun from. diff --git a/Sources/ObjectivelyGPU/Fence.c b/Sources/ObjectivelyGPU/Fence.c index 7e33332..56501c1 100644 --- a/Sources/ObjectivelyGPU/Fence.c +++ b/Sources/ObjectivelyGPU/Fence.c @@ -109,7 +109,6 @@ Class *_Fence(void) { .name = "Fence", .superclass = _Object(), .instanceSize = sizeof(Fence), - .interfaceOffset = offsetof(Fence, interface), .interfaceSize = sizeof(FenceInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Fence.h b/Sources/ObjectivelyGPU/Fence.h index 130dad0..0c03f0e 100644 --- a/Sources/ObjectivelyGPU/Fence.h +++ b/Sources/ObjectivelyGPU/Fence.h @@ -60,10 +60,10 @@ struct Fence { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - FenceInterface *interface; + FenceInterface *interface[0]; /** * @brief The underlying SDL fence. diff --git a/Sources/ObjectivelyGPU/Framebuffer.c b/Sources/ObjectivelyGPU/Framebuffer.c index 69e7b72..dcc9219 100644 --- a/Sources/ObjectivelyGPU/Framebuffer.c +++ b/Sources/ObjectivelyGPU/Framebuffer.c @@ -321,7 +321,6 @@ Class *_Framebuffer(void) { .name = "Framebuffer", .superclass = _Object(), .instanceSize = sizeof(Framebuffer), - .interfaceOffset = offsetof(Framebuffer, interface), .interfaceSize = sizeof(FramebufferInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Framebuffer.h b/Sources/ObjectivelyGPU/Framebuffer.h index 9b979f1..49ea2f9 100644 --- a/Sources/ObjectivelyGPU/Framebuffer.h +++ b/Sources/ObjectivelyGPU/Framebuffer.h @@ -182,10 +182,10 @@ struct Framebuffer { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - FramebufferInterface *interface; + FramebufferInterface *interface[0]; /** * @brief The owning RenderDevice, used for texture allocation and dealloc. diff --git a/Sources/ObjectivelyGPU/GraphicsPipeline.c b/Sources/ObjectivelyGPU/GraphicsPipeline.c index 9c76669..fb94ab0 100644 --- a/Sources/ObjectivelyGPU/GraphicsPipeline.c +++ b/Sources/ObjectivelyGPU/GraphicsPipeline.c @@ -165,7 +165,6 @@ Class *_GraphicsPipeline(void) { .name = "GraphicsPipeline", .superclass = _Object(), .instanceSize = sizeof(GraphicsPipeline), - .interfaceOffset = offsetof(GraphicsPipeline, interface), .interfaceSize = sizeof(GraphicsPipelineInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/GraphicsPipeline.h b/Sources/ObjectivelyGPU/GraphicsPipeline.h index 6d1077d..04fafd2 100644 --- a/Sources/ObjectivelyGPU/GraphicsPipeline.h +++ b/Sources/ObjectivelyGPU/GraphicsPipeline.h @@ -56,10 +56,10 @@ struct GraphicsPipeline { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - GraphicsPipelineInterface *interface; + GraphicsPipelineInterface *interface[0]; /** * @brief The underlying SDL graphics pipeline. diff --git a/Sources/ObjectivelyGPU/QueryPool.c b/Sources/ObjectivelyGPU/QueryPool.c index 85cff7a..4c9ea54 100644 --- a/Sources/ObjectivelyGPU/QueryPool.c +++ b/Sources/ObjectivelyGPU/QueryPool.c @@ -102,7 +102,6 @@ Class *_QueryPool(void) { .name = "QueryPool", .superclass = _Object(), .instanceSize = sizeof(QueryPool), - .interfaceOffset = offsetof(QueryPool, interface), .interfaceSize = sizeof(QueryPoolInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/QueryPool.h b/Sources/ObjectivelyGPU/QueryPool.h index 5414111..64bc8ad 100644 --- a/Sources/ObjectivelyGPU/QueryPool.h +++ b/Sources/ObjectivelyGPU/QueryPool.h @@ -91,10 +91,10 @@ struct QueryPool { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - QueryPoolInterface *interface; + QueryPoolInterface *interface[0]; /** * @brief The underlying SDL query pool, or `NULL` if occlusion queries are diff --git a/Sources/ObjectivelyGPU/RenderDevice.c b/Sources/ObjectivelyGPU/RenderDevice.c index 54a3593..8c4d758 100644 --- a/Sources/ObjectivelyGPU/RenderDevice.c +++ b/Sources/ObjectivelyGPU/RenderDevice.c @@ -723,7 +723,6 @@ Class *_RenderDevice(void) { .name = "RenderDevice", .superclass = _Object(), .instanceSize = sizeof(RenderDevice), - .interfaceOffset = offsetof(RenderDevice, interface), .interfaceSize = sizeof(RenderDeviceInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/RenderDevice.h b/Sources/ObjectivelyGPU/RenderDevice.h index abd1c7a..2b019fc 100644 --- a/Sources/ObjectivelyGPU/RenderDevice.h +++ b/Sources/ObjectivelyGPU/RenderDevice.h @@ -68,10 +68,10 @@ struct RenderDevice { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - RenderDeviceInterface *interface; + RenderDeviceInterface *interface[0]; /** * @brief The `SDL_GPUDevice`. diff --git a/Sources/ObjectivelyGPU/RenderPass.c b/Sources/ObjectivelyGPU/RenderPass.c index ea2897a..a639338 100644 --- a/Sources/ObjectivelyGPU/RenderPass.c +++ b/Sources/ObjectivelyGPU/RenderPass.c @@ -328,7 +328,6 @@ Class *_RenderPass(void) { .name = "RenderPass", .superclass = _Object(), .instanceSize = sizeof(RenderPass), - .interfaceOffset = offsetof(RenderPass, interface), .interfaceSize = sizeof(RenderPassInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/RenderPass.h b/Sources/ObjectivelyGPU/RenderPass.h index e99fb59..459e39b 100644 --- a/Sources/ObjectivelyGPU/RenderPass.h +++ b/Sources/ObjectivelyGPU/RenderPass.h @@ -62,10 +62,10 @@ struct RenderPass { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - RenderPassInterface *interface; + RenderPassInterface *interface[0]; /** * @brief The current blend constants. diff --git a/Sources/ObjectivelyGPU/Sampler.c b/Sources/ObjectivelyGPU/Sampler.c index 45242c7..6416071 100644 --- a/Sources/ObjectivelyGPU/Sampler.c +++ b/Sources/ObjectivelyGPU/Sampler.c @@ -92,7 +92,6 @@ Class *_Sampler(void) { .name = "Sampler", .superclass = _Object(), .instanceSize = sizeof(Sampler), - .interfaceOffset = offsetof(Sampler, interface), .interfaceSize = sizeof(SamplerInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Sampler.h b/Sources/ObjectivelyGPU/Sampler.h index ca50c85..0b03aaa 100644 --- a/Sources/ObjectivelyGPU/Sampler.h +++ b/Sources/ObjectivelyGPU/Sampler.h @@ -56,10 +56,10 @@ struct Sampler { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - SamplerInterface *interface; + SamplerInterface *interface[0]; /** * @brief The underlying SDL sampler. diff --git a/Sources/ObjectivelyGPU/Shader.c b/Sources/ObjectivelyGPU/Shader.c index a904df7..5017447 100644 --- a/Sources/ObjectivelyGPU/Shader.c +++ b/Sources/ObjectivelyGPU/Shader.c @@ -94,7 +94,6 @@ Class *_Shader(void) { .name = "Shader", .superclass = _Object(), .instanceSize = sizeof(Shader), - .interfaceOffset = offsetof(Shader, interface), .interfaceSize = sizeof(ShaderInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Shader.h b/Sources/ObjectivelyGPU/Shader.h index a878cd0..4200ffe 100644 --- a/Sources/ObjectivelyGPU/Shader.h +++ b/Sources/ObjectivelyGPU/Shader.h @@ -56,10 +56,10 @@ struct Shader { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - ShaderInterface *interface; + ShaderInterface *interface[0]; /** * @brief The RenderDevice that owns this shader. diff --git a/Sources/ObjectivelyGPU/Texture.c b/Sources/ObjectivelyGPU/Texture.c index 0a9fc17..33673f9 100644 --- a/Sources/ObjectivelyGPU/Texture.c +++ b/Sources/ObjectivelyGPU/Texture.c @@ -312,7 +312,6 @@ Class *_Texture(void) { .name = "Texture", .superclass = _Object(), .instanceSize = sizeof(Texture), - .interfaceOffset = offsetof(Texture, interface), .interfaceSize = sizeof(TextureInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/Texture.h b/Sources/ObjectivelyGPU/Texture.h index cb75246..b26e659 100644 --- a/Sources/ObjectivelyGPU/Texture.h +++ b/Sources/ObjectivelyGPU/Texture.h @@ -65,10 +65,10 @@ struct Texture { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - TextureInterface *interface; + TextureInterface *interface[0]; /** * @brief The underlying SDL texture. diff --git a/Sources/ObjectivelyGPU/TransferBuffer.c b/Sources/ObjectivelyGPU/TransferBuffer.c index 0549441..3c43562 100644 --- a/Sources/ObjectivelyGPU/TransferBuffer.c +++ b/Sources/ObjectivelyGPU/TransferBuffer.c @@ -133,7 +133,6 @@ Class *_TransferBuffer(void) { .name = "TransferBuffer", .superclass = _Object(), .instanceSize = sizeof(TransferBuffer), - .interfaceOffset = offsetof(TransferBuffer, interface), .interfaceSize = sizeof(TransferBufferInterface), .initialize = initialize, }); diff --git a/Sources/ObjectivelyGPU/TransferBuffer.h b/Sources/ObjectivelyGPU/TransferBuffer.h index 00252af..2ec8169 100644 --- a/Sources/ObjectivelyGPU/TransferBuffer.h +++ b/Sources/ObjectivelyGPU/TransferBuffer.h @@ -64,10 +64,10 @@ struct TransferBuffer { Object object; /** - * @brief The interface. + * @brief The interface type. * @protected */ - TransferBufferInterface *interface; + TransferBufferInterface *interface[0]; /** * @brief The underlying SDL transfer buffer. From fa4fa3f338b5ee3bdf01fde474cab0b75b1cce2d Mon Sep 17 00:00:00 2001 From: Jay Dolan Date: Wed, 2 Sep 2026 19:32:52 -0400 Subject: [PATCH 2/3] Bump version to 2.2.0; require Objectively >= 2.2.0 Objectively 2.2.0 changed the instance layout (no per-instance interface pointers), so this library MUST be built against it and nothing older. Co-Authored-By: Claude Fable 5.1 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 806132a..bf51b72 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.69) -AC_INIT([ObjectivelyGPU], [1.0.0], [jay@jaydolan.com]) +AC_INIT([ObjectivelyGPU], [2.2.0], [jay@jaydolan.com]) AC_CONFIG_HEADERS([Sources/ObjectivelyGPU/Config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -58,7 +58,7 @@ AM_CONDITIONAL([MINGW], [test "x$HOST_NAME" = "xMINGW"]) AM_CONDITIONAL([LINUX], [test "x$HOST_NAME" = "xLINUX"]) PKG_CHECK_MODULES([CHECK], [check >= 0.9.4]) -PKG_CHECK_MODULES([OBJECTIVELY], [Objectively >= 2.0.0]) +PKG_CHECK_MODULES([OBJECTIVELY], [Objectively >= 2.2.0]) PKG_CHECK_MODULES([SDL3], [sdl3 >= 3.2.0]) AC_CONFIG_FILES([ From ff9bb40bf5b4c14d30c20ff93c53ba092242f51b Mon Sep 17 00:00:00 2001 From: Jay Dolan Date: Wed, 2 Sep 2026 19:39:35 -0400 Subject: [PATCH 3/3] Derive the shared library soname from the package version Replace the -version-info hard-coded in Makefile.am with -release MAJOR.MINOR, computed from AC_INIT, so the soname follows configure.ac. Every minor release gets a new soname; patch releases stay compatible. Co-Authored-By: Claude Fable 5.1 --- Sources/ObjectivelyGPU/Makefile.am | 2 +- configure.ac | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/ObjectivelyGPU/Makefile.am b/Sources/ObjectivelyGPU/Makefile.am index 72a1690..da54d7f 100644 --- a/Sources/ObjectivelyGPU/Makefile.am +++ b/Sources/ObjectivelyGPU/Makefile.am @@ -49,7 +49,7 @@ libObjectivelyGPU_la_CFLAGS = \ $(SDL3_CFLAGS) libObjectivelyGPU_la_LDFLAGS = \ - -version-info 1:0:0 \ + -release @RELEASE_VERSION@ \ $(HOST_LDFLAGS) libObjectivelyGPU_la_LIBADD = \ diff --git a/configure.ac b/configure.ac index bf51b72..bd58d20 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,7 @@ AC_PREREQ(2.69) AC_INIT([ObjectivelyGPU], [2.2.0], [jay@jaydolan.com]) +AC_SUBST([RELEASE_VERSION], [m4_bpatsubst(AC_PACKAGE_VERSION, [\.[0-9]*$], [])]) AC_CONFIG_HEADERS([Sources/ObjectivelyGPU/Config.h]) AC_CONFIG_MACRO_DIR([m4])