Skip to content

Commit ecc188b

Browse files
authored
develop to main (#44)
* update: drop support for net48 in favor of netstandard2.1 - bumped LangVersion to 11.0 - added basic AGENTS.md * update: drop MessagePack support in favor of MemoryPack * refactor: git actions wo net48 +semver: breaking
1 parent 3a2c9b8 commit ecc188b

35 files changed

Lines changed: 369 additions & 742 deletions

.github/workflows/dotnet.yml

Lines changed: 20 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,45 @@
1-
# This workflow builds and tests the FixedMathSharp .NET project.
2-
# Documentation: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
3-
41
name: .NET CI
52

63
on:
7-
# Run the workflow on all branch pushes and pull requests
84
push:
95
branches-ignore:
10-
- 'dependabot/**' #avoid duplicates: only run the PR, not the push
11-
- 'gh-pages' #github pages do not trigger all tests
6+
- 'dependabot/**'
7+
- 'gh-pages'
128
tags-ignore:
13-
- 'v*' #avoid rerun existing commit on release
9+
- 'v*'
1410
pull_request:
1511
branches:
1612
- 'main'
1713

1814
jobs:
19-
build-and-test-linux:
20-
if: |
21-
(github.event_name != 'pull_request' && !github.event.pull_request.head.repo.fork)
22-
|| (github.event_name == 'pull_request' && (github.event.pull_request.head.repo.fork
23-
|| startsWith(github.head_ref, 'dependabot/')))
24-
runs-on: ubuntu-latest
15+
build-and-test:
16+
runs-on: ${{ matrix.os }}
17+
18+
strategy:
19+
matrix:
20+
os: [ubuntu-latest, windows-latest]
2521

2622
steps:
2723
- name: Checkout repository
2824
uses: actions/checkout@v4
2925
with:
3026
fetch-depth: 0
31-
persist-credentials: false # Ensure credentials aren't retained
27+
persist-credentials: false
3228

3329
- name: Setup .NET
3430
uses: actions/setup-dotnet@v4
3531
with:
3632
dotnet-version: 8.0.x
37-
38-
- name: Install Mono (required for .NET Framework tests on Linux)
39-
run: |
40-
sudo apt update
41-
sudo apt install -y mono-complete
42-
43-
- name: Install GitVersion
33+
34+
- name: Setup GitVersion
4435
uses: gittools/actions/gitversion/setup@v3.1.1
4536
with:
4637
versionSpec: '6.0.x'
4738

39+
- name: Execute GitVersion
40+
id: gitversion
41+
uses: gittools/actions/gitversion/execute@v3.1.1
42+
4843
- name: Cache NuGet packages
4944
uses: actions/cache@v3
5045
with:
@@ -53,82 +48,14 @@ jobs:
5348
restore-keys: |
5449
${{ runner.os }}-nuget-
5550
56-
- name: Determine Version
57-
id: version_step
58-
run: |
59-
chown -R $(whoami) $(pwd)
60-
dotnet-gitversion /output json > version.json
61-
echo "FULL_SEM_VER=$(grep -oP '"FullSemVer":\s*"\K[^"]+' version.json)" >> $GITHUB_ENV
62-
echo "ASSEMBLY_VERSION=$(grep -oP '"AssemblySemFileVer":\s*"\K[^"]+' version.json)" >> $GITHUB_ENV
63-
6451
- name: Restore dependencies
6552
run: dotnet restore
6653

6754
- name: Build Solution
6855
run: |
69-
echo "Version: ${{ env.FULL_SEM_VER }}"
70-
echo "Assembly Version: ${{ env.ASSEMBLY_VERSION }}"
56+
echo "Version: ${{ steps.gitversion.outputs.fullSemVer }}"
57+
echo "Assembly Version: ${{ steps.gitversion.outputs.assemblySemFileVer }}"
7158
dotnet build --configuration Debug --no-restore
7259
73-
- name: Test .NET48
74-
run: |
75-
mono ~/.nuget/packages/xunit.runner.console/2.9.3/tools/net48/xunit.console.exe ${{github.workspace}}/tests/FixedMathSharp.Tests/bin/Debug/net48/FixedMathSharp.Tests.dll
76-
77-
- name: Test .NET8
78-
run: |
79-
dotnet test -f net8 --verbosity normal
80-
81-
build-and-test-windows:
82-
if: |
83-
(github.event_name != 'pull_request' && !github.event.pull_request.head.repo.fork)
84-
|| (github.event_name == 'pull_request' && (github.event.pull_request.head.repo.fork
85-
|| startsWith(github.head_ref, 'dependabot/')))
86-
runs-on: windows-latest
87-
steps:
88-
- name: Checkout repository
89-
uses: actions/checkout@v4
90-
with:
91-
fetch-depth: 0
92-
persist-credentials: false
93-
94-
- name: Setup .NET
95-
uses: actions/setup-dotnet@v4
96-
with:
97-
dotnet-version: 8.0.x
98-
99-
- name: Install GitVersion
100-
uses: gittools/actions/gitversion/setup@v3.1.1
101-
with:
102-
versionSpec: 6.0.x
103-
104-
- name: Cache NuGet packages
105-
uses: actions/cache@v3
106-
with:
107-
path: ~/.nuget/packages
108-
key: '${{ runner.os }}-nuget-${{ hashFiles(''**/*.csproj'', ''**/*.sln'') }}'
109-
restore-keys: |
110-
${{ runner.os }}-nuget-
111-
112-
- name: Determine Version
113-
id: version_step
114-
shell: pwsh
115-
run: |
116-
chown -R $env:USERNAME $(Get-Location)
117-
dotnet-gitversion /output json | Out-File -FilePath version.json
118-
$json = Get-Content version.json | ConvertFrom-Json
119-
echo "FULL_SEM_VER=$($json.FullSemVer)" | Out-File -FilePath $env:GITHUB_ENV -Append
120-
echo "ASSEMBLY_VERSION=$($json.AssemblySemFileVer)" | Out-File -FilePath $env:GITHUB_ENV -Append
121-
122-
- name: Restore dependencies
123-
run: dotnet restore
124-
125-
- name: Build Solution
126-
run: |
127-
echo "Version: ${{ env.FULL_SEM_VER }}"
128-
echo "Assembly Version: ${{ env.ASSEMBLY_VERSION }}"
129-
dotnet build --configuration Debug --no-restore
130-
131-
- name: Test .NET48 & .NET8
132-
run: |
133-
dotnet --info
134-
dotnet test --verbosity normal
60+
- name: Run Tests
61+
run: dotnet test --configuration Debug --no-build --verbosity normal

AGENTS.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# FixedMathSharp agent instructions
2+
3+
## Project intent and architecture
4+
- This repository is a deterministic fixed-point math library centered on `Fixed64` (`src/FixedMathSharp/Numerics/Fixed64.cs`) with Q32.32 representation (`SHIFT_AMOUNT_I = 32` in `src/FixedMathSharp/Core/FixedMath.cs`).
5+
- Most API surface lives in value-type numerics (`Fixed64`, `Vector2d`, `Vector3d`, `FixedQuaternion`, `Fixed3x3`, `Fixed4x4`) plus bounds types (`BoundingBox`, `BoundingSphere`, `BoundingArea`) implementing `IBound`.
6+
- Keep operations deterministic and allocation-light; many methods use `m_rawValue` and `[MethodImpl(MethodImplOptions.AggressiveInlining)]` for hot paths.
7+
- `FixedMath` and `FixedTrigonometry` are the shared algorithm backbones; extension classes in `src/FixedMathSharp/Numerics/Extensions/` are thin forwarding wrappers, not alternate implementations.
8+
9+
## Build and test workflows
10+
- Solution: `FixedMathSharp.sln` with library project and test project.
11+
- Target frameworks are configured in the respective `.csproj` files; `net8.0` is the primary TFM.
12+
- Typical local workflow:
13+
- `dotnet restore`
14+
- `dotnet build --configuration Debug --no-restore`
15+
- `dotnet test --configuration Debug`
16+
- CI detail from `.github/workflows/dotnet.yml`:
17+
- Linux and Windows both run `dotnet test` against the supported TFMs (with `net8.0` as the primary test target).
18+
- Refer to the workflow file for the exact matrix of OS/TFM combinations.
19+
- Packaging/versioning comes from `src/FixedMathSharp/FixedMathSharp.csproj`: GitVersion variables are consumed when present, otherwise version falls back to `0.0.0`.
20+
21+
## Code conventions specific to this repo
22+
- Prefer `Fixed64` constants (`Fixed64.Zero`, `Fixed64.One`, `FixedMath.PI`) over primitive literals in math-heavy code.
23+
- Preserve saturating/guarded semantics in operators and math helpers (for example `Fixed64` add/sub overflow behavior).
24+
- When touching bounds logic, maintain cross-type dispatch shape in `Intersects(IBound)` and shared clamping projection via `IBoundExtensions.ProjectPointWithinBounds`.
25+
- Serialization compatibility is intentional and now uses MemoryPack:
26+
- MemoryPack attributes on serializable structs (for example `[MemoryPackable]`, `[MemoryPackInclude]`) are the source of truth for serialized layouts.
27+
- Tests use MemoryPack-based roundtrips (and `System.Text.Json` where appropriate) instead of legacy `MessagePack`/`BinaryFormatter` serializers.
28+
- `ThreadLocalRandom` is marked `[Obsolete]`; new deterministic RNG work should prefer `DeterministicRandom` and `DeterministicRandom.FromWorldFeature(...)` in `src/FixedMathSharp/Utility/DeterministicRandom.cs`.
29+
30+
## Testing patterns to mirror
31+
- Tests are xUnit (`tests/FixedMathSharp.Tests`). Keep one feature area per test file (e.g., `Vector3d.Tests.cs`, `Bounds/BoundingBox.Tests.cs`).
32+
- Use helper assertions from `tests/FixedMathSharp.Tests/Support/FixedMathTestHelper.cs` for tolerance/range checks rather than ad-hoc epsilon logic.
33+
- For deterministic RNG changes, validate same-seed reproducibility and bounds/argument exceptions like in `DeterministicRandom.Tests.cs`.
34+
35+
## Agent editing guidance
36+
- Keep public API shape stable unless the task explicitly requests API changes.
37+
- Match existing style (regions, XML docs, explicit namespaces, no implicit usings).
38+
- Make focused edits in the relevant numeric/bounds module and update corresponding tests in the parallel test file.

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Ideal for simulations, games, and physics engines requiring reliable arithmetic
2020
- **Bounding Shapes:** Includes `IBound` structs `BoundingBox`, `BoundingSphere`, and `BoundingArea` for lightweight spatial calculations.
2121
- **Advanced Math Functions:** Includes trigonometry and common math utilities.
2222
- **Framework Agnostic:** Works with **.NET, Unity, and other game engines**.
23-
- **Full Serialization Support:** Out-of-the-box round-trip serialization via BinaryFormatter (for .NET Framework 4.8+), System.Text.Json (for .NET 8+), and MessagePack across all serializable structs.
23+
- **Full Serialization Support:** Out-of-the-box round-trip serialization via `MemoryPack` across all serializable structs, with `System.Text.Json` constructor support on .NET 8+.
2424

2525
---
2626

@@ -176,8 +176,8 @@ dotnet test --configuration debug
176176
177177
## 🛠️ Compatibility
178178
179-
- **.NET Framework** 4.7.2+
180-
- **.NET Core / .NET** 6+
179+
- **.NET Standard** 2.1
180+
- **.NET** 8
181181
- **Unity 2020+** (via [FixedMathSharp-Unity](https://github.com/mrdav30/FixedMathSharp-Unity))
182182
- **Cross-Platform Support** (Windows, Linux, macOS)
183183

src/FixedMathSharp/Bounds/BoundingArea.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using MessagePack;
1+
using MemoryPack;
22
using System;
33
using System.Runtime.CompilerServices;
44

@@ -18,21 +18,21 @@ namespace FixedMathSharp
1818
/// </remarks>
1919

2020
[Serializable]
21-
[MessagePackObject]
22-
public struct BoundingArea : IBound, IEquatable<BoundingArea>
21+
[MemoryPackable]
22+
public partial struct BoundingArea : IBound, IEquatable<BoundingArea>
2323
{
2424
#region Fields
2525

2626
/// <summary>
2727
/// One of the corner points of the bounding area.
2828
/// </summary>
29-
[Key(0)]
29+
[MemoryPackOrder(0)]
3030
public Vector3d Corner1;
3131

3232
/// <summary>
3333
/// The opposite corner point of the bounding area.
3434
/// </summary>
35-
[Key(1)]
35+
[MemoryPackOrder(1)]
3636
public Vector3d Corner2;
3737

3838
#endregion
@@ -68,7 +68,7 @@ public BoundingArea(Vector3d corner1, Vector3d corner2)
6868
/// <summary>
6969
/// The minimum corner of the bounding box.
7070
/// </summary>
71-
[IgnoreMember]
71+
[MemoryPackIgnore]
7272
public Vector3d Min
7373
{
7474
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -78,49 +78,49 @@ public Vector3d Min
7878
/// <summary>
7979
/// The maximum corner of the bounding box.
8080
/// </summary>
81-
[IgnoreMember]
81+
[MemoryPackIgnore]
8282
public Vector3d Max
8383
{
8484
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8585
get => new(MaxX, MaxY, MaxZ);
8686
}
8787

88-
[IgnoreMember]
88+
[MemoryPackIgnore]
8989
public Fixed64 MinX
9090
{
9191
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9292
get => Corner1.x < Corner2.x ? Corner1.x : Corner2.x;
9393
}
9494

95-
[IgnoreMember]
95+
[MemoryPackIgnore]
9696
public Fixed64 MaxX
9797
{
9898
[MethodImpl(MethodImplOptions.AggressiveInlining)]
9999
get => Corner1.x > Corner2.x ? Corner1.x : Corner2.x;
100100
}
101101

102-
[IgnoreMember]
102+
[MemoryPackIgnore]
103103
public Fixed64 MinY
104104
{
105105
[MethodImpl(MethodImplOptions.AggressiveInlining)]
106106
get => Corner1.y < Corner2.y ? Corner1.y : Corner2.y;
107107
}
108108

109-
[IgnoreMember]
109+
[MemoryPackIgnore]
110110
public Fixed64 MaxY
111111
{
112112
[MethodImpl(MethodImplOptions.AggressiveInlining)]
113113
get => Corner1.y > Corner2.y ? Corner1.y : Corner2.y;
114114
}
115115

116-
[IgnoreMember]
116+
[MemoryPackIgnore]
117117
public Fixed64 MinZ
118118
{
119119
[MethodImpl(MethodImplOptions.AggressiveInlining)]
120120
get => Corner1.z < Corner2.z ? Corner1.z : Corner2.z;
121121
}
122122

123-
[IgnoreMember]
123+
[MemoryPackIgnore]
124124
public Fixed64 MaxZ
125125
{
126126
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -130,7 +130,7 @@ public Fixed64 MaxZ
130130
/// <summary>
131131
/// Calculates the width (X-axis) of the bounding area.
132132
/// </summary>
133-
[IgnoreMember]
133+
[MemoryPackIgnore]
134134
public Fixed64 Width
135135
{
136136
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -140,7 +140,7 @@ public Fixed64 Width
140140
/// <summary>
141141
/// Calculates the height (Y-axis) of the bounding area.
142142
/// </summary>
143-
[IgnoreMember]
143+
[MemoryPackIgnore]
144144
public Fixed64 Height
145145
{
146146
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -150,7 +150,7 @@ public Fixed64 Height
150150
/// <summary>
151151
/// Calculates the depth (Z-axis) of the bounding area.
152152
/// </summary>
153-
[IgnoreMember]
153+
[MemoryPackIgnore]
154154
public Fixed64 Depth
155155
{
156156
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -163,8 +163,8 @@ public Fixed64 Depth
163163
public bool Contains(Vector3d point)
164164
{
165165
// Check if the point is within the bounds of the area (including boundaries)
166-
return point.x >= MinX && point.x <= MaxX
167-
&& point.y >= MinY && point.y <= MaxY
166+
return point.x >= MinX && point.x <= MaxX
167+
&& point.y >= MinY && point.y <= MaxY
168168
&& point.z >= MinZ && point.z <= MaxZ;
169169
}
170170

@@ -208,7 +208,7 @@ public bool Intersects(IBound other)
208208
return Vector3d.SqrDistance(sphere.Center, this.ProjectPointWithinBounds(sphere.Center)) <= sphere.SqrRadius;
209209

210210
default: return false; // Default case for unknown or unsupported types
211-
};
211+
}
212212
}
213213

214214
/// <summary>

0 commit comments

Comments
 (0)