Skip to content

Commit 994c9c8

Browse files
committed
fix(uwp): make BakedAspectGraph compile under .NET Native
Four fixes restore the UWP build the v0.6.0 release surfaced as broken: - Switch CompositionExpressions from a sibling-repo ProjectReference to a NuGet PackageReference (arcadiog.CompositionExpressions 0.1.3, newly published from the CompositionCollectionView repo with a UWP flavour). Both Combobulate.csproj and Combobulate.WinAppSdk.csproj consume the same package now; CI no longer needs to find a sibling checkout. - Add the BAG sources (AspectGraphBake, BakedAspectGraphRenderer, EventFunctions, PredicateCompiler, SignatureBake, TransformAnimationAxis) to Combobulate.csproj's explicit Compile list so the UWP target actually compiles them. Add #if WINAPPSDK around Microsoft.UI.Composition / Microsoft.UI.Dispatching usings, with Windows.UI.Composition / Windows.System fallbacks aliased via DispatcherQueueNS. - Replace VisualCollection.Contains (a LINQ extension that fails to resolve once System.Memory is referenced and pulls a colliding MemoryExtensions.Contains overload into scope) with a Visual.Parent null-check. - Move IFaceSorter.CullEpsilon onto FaceSorterFactory: an interface const requires default-interface-implementation support which UWP's .NET Native runtime rejects with CS8701. Update the one test that read the const accordingly. - Add a System.Memory PackageReference to the UWP csproj so Span<T> resolves (PolygonSplitter and NewellSorter use Span).
1 parent 36d65e2 commit 994c9c8

5 files changed

Lines changed: 25 additions & 19 deletions

File tree

src/Combobulate.WinAppSdk/Combobulate.WinAppSdk.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,13 @@
2222

2323
<ItemGroup>
2424
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.7.250401001" />
25+
<PackageReference Include="arcadiog.CompositionExpressions" Version="0.1.3" />
2526
<PackageReference Include="PolySharp" Version="1.14.1">
2627
<PrivateAssets>all</PrivateAssets>
2728
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2829
</PackageReference>
2930
</ItemGroup>
3031

31-
<ItemGroup>
32-
<ProjectReference Include="..\..\..\CompositionCollectionView\src\CompositionExpressions.WinAppSdk\CompositionExpressions.WinAppSdk.csproj" />
33-
</ItemGroup>
34-
3532
<!-- Shared source files from the UWP library project -->
3633
<ItemGroup>
3734
<Compile Include="..\Combobulate\**\*.cs"

src/Combobulate/Combobulate.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@
177177
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
178178
<Version>6.2.14</Version>
179179
</PackageReference>
180+
<PackageReference Include="System.Memory">
181+
<Version>4.5.5</Version>
182+
</PackageReference>
183+
<PackageReference Include="arcadiog.CompositionExpressions">
184+
<Version>0.1.3</Version>
185+
</PackageReference>
180186
<PackageReference Include="PolySharp" Version="1.14.1">
181187
<PrivateAssets>all</PrivateAssets>
182188
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

src/Combobulate/Rendering/BakedAspectGraphRenderer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ private void EvictStaging()
744744
{
745745
try
746746
{
747-
if (_parent.Children.Contains(t)) _parent.Children.Remove(t);
747+
if (t.Parent != null) _parent.Children.Remove(t);
748748
t.Dispose();
749749
}
750750
catch { }
@@ -759,7 +759,7 @@ private void DisposeTrees()
759759
{
760760
t.StopAnimation("Opacity");
761761
t.Children.RemoveAll();
762-
if (_parent.Children.Contains(t)) _parent.Children.Remove(t);
762+
if (t.Parent != null) _parent.Children.Remove(t);
763763
t.Dispose();
764764
}
765765
_trees = null;

src/Combobulate/Sorting/IFaceSorter.cs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,6 @@ namespace Combobulate.Sorting;
2626
/// </summary>
2727
public interface IFaceSorter
2828
{
29-
/// <summary>
30-
/// Back-face cull threshold. Re-exports
31-
/// <see cref="GeometryPredicates.CosineEpsilon"/> so existing call
32-
/// sites and tests that reference <c>IFaceSorter.CullEpsilon</c>
33-
/// continue to work; new code should prefer
34-
/// <see cref="GeometryPredicates.IsFrontFacing"/> directly.
35-
///
36-
/// <para>See <see cref="GeometryPredicates"/> for the full epsilon
37-
/// hierarchy (cosine / distance / divisor / squared-length scales).</para>
38-
/// </summary>
39-
public const float CullEpsilon = GeometryPredicates.CosineEpsilon;
4029
/// <summary>
4130
/// Number of source quads this sorter was built for. The caller's
4231
/// <paramref name="orderBuffer"/> and <paramref name="visibleBuffer"/>
@@ -78,6 +67,20 @@ public interface IFaceSorter
7867
/// </summary>
7968
public static class FaceSorterFactory
8069
{
70+
/// <summary>
71+
/// Back-face cull threshold. Re-exports
72+
/// <see cref="GeometryPredicates.CosineEpsilon"/> so existing call
73+
/// sites and tests that reference <c>FaceSorterFactory.CullEpsilon</c>
74+
/// keep working; new code should prefer
75+
/// <see cref="GeometryPredicates.IsFrontFacing"/> directly.
76+
///
77+
/// <para>Lives on this static class rather than <see cref="IFaceSorter"/>
78+
/// because UWP's .NET Native runtime doesn't support the default-interface-
79+
/// implementation feature (CS8701) needed for a const member on an
80+
/// interface.</para>
81+
/// </summary>
82+
public const float CullEpsilon = GeometryPredicates.CosineEpsilon;
83+
8184
public static IFaceSorter Create(SortAlgorithm algorithm, ObjGeometry geometry)
8285
{
8386
return algorithm switch

tests/Combobulate.Tests/Sorting/CullEpsilonTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ public void GenuinelyVisibleQuadAtYaw89_IsRendered(SortAlgorithm algo)
8282
public void CullEpsilonIsPositiveAndAboveSinglePrecisionCosNoise()
8383
{
8484
// The whole point: must be > the noise floor of MathF.Cos(MathF.PI/2).
85-
Assert.True(IFaceSorter.CullEpsilon > 1e-6f, "Epsilon too tight; fp noise will leak through");
86-
Assert.True(IFaceSorter.CullEpsilon < 1e-2f, "Epsilon too loose; legitimate near-edge-on faces would be culled");
85+
Assert.True(FaceSorterFactory.CullEpsilon > 1e-6f, "Epsilon too tight; fp noise will leak through");
86+
Assert.True(FaceSorterFactory.CullEpsilon < 1e-2f, "Epsilon too loose; legitimate near-edge-on faces would be culled");
8787
}
8888

8989
/// <summary>

0 commit comments

Comments
 (0)