From 588732fabf36fdff5865d72646503c67e3c8df63 Mon Sep 17 00:00:00 2001 From: Lilly Sieberer Date: Thu, 10 Nov 2022 20:19:54 -0500 Subject: [PATCH 1/3] Chain Polymorphism Proposal Improves use of managed `Chain<...>` in cases where chain elements may not be known at compile time apart from a prefix set --- .../Proposal - Chain Polymorphism.md | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 documentation/proposals/Proposal - Chain Polymorphism.md diff --git a/documentation/proposals/Proposal - Chain Polymorphism.md b/documentation/proposals/Proposal - Chain Polymorphism.md new file mode 100644 index 0000000000..19fd5bc9bd --- /dev/null +++ b/documentation/proposals/Proposal - Chain Polymorphism.md @@ -0,0 +1,106 @@ +# Summary + +Using the managed `Silk.NET.Vulkan.Chain` and its generically-typed descendants can be unwieldy in the specific case of recieving chains +with known starting element(s) but potential unknown later elements, e.g. a `SwapchainCreateInfoKHR` which may or may not have an +`ImageCreateInfo` later in the chain. If use of the managed chain api is desired in this case, the untyped `Chain` type must be used +and the result of its indexer cast to the desired chain start type. This, combined with the public api surface on ``Chain`2`` being +a strict superset of ``Chain`1`` etc., a polymorphic interface is desired for handling variable-size chains. + +# Contributors + +- [Khitiara](https://github.com/Khitiara) + +# Current Status + +- [x] Proposed +- [ ] Discussed with API Review Board (ARB) +- [ ] Approved +- [ ] Implemented + +# Design Decisions + +- This is mainly useful in cases where the managed api and its automatic management of chain memory is desired. The unmanaged non-generic API + already supports this use-case, so this function is mainly beneficial as method return types where chain extensions may not be known ahead of + time, and thus `out` parameters for all unmanaged chain elements are not suitable. + +# Proposed API + +A series of generic interfaces are created to accompany the generic `Chain<...>` classes: + +```csharp +public unsafe interface IChain : IDisposable + where TChain : unmanaged, IChainable { + public BaseInStructure* HeadPtr { get; } + public TChain Head { get; set; } +} + +public unsafe interface IChain : IChain + where TChain : unmanaged, IChainable + where T1 : unmanaged, IChainable { + public BaseInStructure* Item1Ptr { get; } + public T1 Item1 { get; set; } +} + +public unsafe interface IChain : IChain + where TChain : unmanaged, IChainable + where T1 : unmanaged, IChainable + where T2 : unmanaged, IChainable { + public BaseInStructure* Item2Ptr { get; } + public T2 Item2 { get; set; } +} + +... +``` + +and the existing generic `Chain<...>` types are modified to implement these new interfaces: + +```csharp +public unsafe sealed class Chain : Chain, IEquatable>, IChain + where TChain : unmanaged, IChainable { + ... +} + +public unsafe sealed class Chain : Chain, IEquatable>, IChain + where TChain : unmanaged, IChainable + where T1 : unmanaged, IChainable { + ... +} + +public unsafe sealed class Chain : Chain, IEquatable>, IChain + where TChain : unmanaged, IChainable + where T1 : unmanaged, IChainable + where T2 : unmanaged, IChainable { + ... +} + +... +``` + +Usage: + +```csharp +public IChain DeduceImageCreateInfo(IChain swapchainCreateInfo) { + ImageCreateInfo createInfo = ...; + + // condition here used for example - a TryFind extension or similar may be desirable in the long term + if (swapchainCreateInfo is Chain(_, formatListCreateInfo)) { + // Chain : IChain : IChain + return Chain.Create(createInfo, formatListCreateInfo); + } + + // Chain : IChain + return Chain.Create(createInfo); +} + +... + +public void Foo() { + SwapchainCreateInfoKHR sci = ...; + using IChain ici = DeduceImageCreateInfo(sci); + ReadOnlySpan fmts = ici switch { + Chain(_, var formatList) => + new ReadOnlySpan(formatList.PViewFormats, (int)formatList.ViewFormatCount).ToArray(), + Chain(var i) => stackalloc[] { i.Format } + } +} +``` From de637840eebf6d538ce7b135fc79abfc1d90847c Mon Sep 17 00:00:00 2001 From: Dylan Perks <11160611+Perksey@users.noreply.github.com> Date: Sat, 7 Jan 2023 20:04:50 +0000 Subject: [PATCH 2/3] Update Proposal - Chain Polymorphism.md --- documentation/proposals/Proposal - Chain Polymorphism.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/proposals/Proposal - Chain Polymorphism.md b/documentation/proposals/Proposal - Chain Polymorphism.md index 19fd5bc9bd..276e72696c 100644 --- a/documentation/proposals/Proposal - Chain Polymorphism.md +++ b/documentation/proposals/Proposal - Chain Polymorphism.md @@ -13,8 +13,8 @@ a strict superset of ``Chain`1`` etc., a polymorphic interface is desired for ha # Current Status - [x] Proposed -- [ ] Discussed with API Review Board (ARB) -- [ ] Approved +- [x] Discussed with API Review Board (ARB) +- [x] Approved - [ ] Implemented # Design Decisions From 39637feb0723217c51e4255faf4f4effa7bdb6dd Mon Sep 17 00:00:00 2001 From: Lilly Sieberer Date: Sat, 7 Jan 2023 18:29:42 -0500 Subject: [PATCH 3/3] Update Chain.cs --- src/Vulkan/Silk.NET.Vulkan/Chain.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Vulkan/Silk.NET.Vulkan/Chain.cs b/src/Vulkan/Silk.NET.Vulkan/Chain.cs index 321bad70a3..81af39c67c 100644 --- a/src/Vulkan/Silk.NET.Vulkan/Chain.cs +++ b/src/Vulkan/Silk.NET.Vulkan/Chain.cs @@ -14,7 +14,7 @@ namespace Silk.NET.Vulkan; /// Base class for all Managed Chains. /// public abstract unsafe partial class Chain : IReadOnlyList, IEquatable, IDisposable -{ +{ /// /// Gets a pointer to the current head. ///