Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ on:
pull_request:
branches:
- main
paths:
- 'UnityProject/Saneject/**'
- 'Roslyn/**'
- '.github/workflows/tests.yml'
# Do not add a paths filter here. Branch protection requires the matrix
# checks below, so the workflow must create them for every PR to main.
workflow_dispatch:

jobs:
Expand All @@ -19,8 +17,39 @@ jobs:
unity: [2022.3.12f1, 2022.3.62f3, 6000.0.58f2, 6000.0.63f1, 6000.1.17f1, 6000.2.6f2, 6000.2.15f1, 6000.3.0f1, 6000.3.12f1, 6000.4.0f1, 6000.4.1f1]
steps:
- uses: actions/checkout@v4
with:
# Required so git can compare the PR commits below.
fetch-depth: 0

- name: Check if Unity tests are needed
id: test-paths
shell: bash
run: |
# Manual runs should always execute the real Unity tests.
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
echo "run=true" >> "$GITHUB_OUTPUT"
exit 0
fi

# Check the full PR diff. This means docs-only PRs skip tests, while
# PRs that contain any test-relevant changes keep running tests even
# if the latest push only changed docs.
if git diff --quiet "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" -- UnityProject/Saneject Roslyn .github/workflows/tests.yml; then
echo "run=false" >> "$GITHUB_OUTPUT"
else
echo "run=true" >> "$GITHUB_OUTPUT"
fi

- name: Skip tests
# Keep the required matrix job successful when this PR update did not
# touch test-relevant paths.
if: steps.test-paths.outputs.run != 'true'
run: echo "No test-relevant files changed."

- name: EditMode tests
# Do not put this condition on the job itself. Branch protection
# requires these matrix jobs to complete successfully.
if: steps.test-paths.outputs.run == 'true'
uses: game-ci/unity-test-runner@v4
env:
UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }}
Expand Down
31 changes: 26 additions & 5 deletions Docs/docs/core-concepts/runtime-proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,35 @@ If a match exists, it is reused. If not, a new asset is created. This keeps runt

### Generated proxy anatomy

User-written code:

```csharp
using System;
using UnityEngine;

public class GameManager : MonoBehaviour, IGameObservable, IGameStarter
{
// From IGameObservable
public event Action OnGameStarted;

// From IGameObservable
public bool IsGameRunning { get; private set; }

// From IGameStarter
public void StartGame()
{
}
}
```

Auto-generated stub script:

```csharp
using Plugins.Saneject.Runtime.Proxy;
using Plugins.Saneject.Runtime.Attributes;

[GenerateRuntimeProxy]
// GameManager implements IGameObservable, IGameStarter
// Attribute instructs Roslyn generator to generate partial
[GenerateRuntimeProxy]
public partial class GameManagerProxyC5D11084 : RuntimeProxy<GameManager>
{
}
Expand All @@ -248,20 +269,20 @@ public partial class GameManagerProxyC5D11084 : IGameObservable, IGameStarter
private const string ProxyAccessExceptionMessage =
"Saneject: RuntimeProxy instances are serialized placeholders and should not be accessed directly.";

// Inherited from IGameObservable and generated by Roslyn
// From IGameObservable (Roslyn-generated)
public event Action OnGameStarted
{
add => throw new InvalidOperationException(ProxyAccessExceptionMessage);
remove => throw new InvalidOperationException(ProxyAccessExceptionMessage);
}

// Inherited from IGameObservable and generated by Roslyn
// From IGameObservable (Roslyn-generated)
public bool IsGameRunning
{
get => throw new InvalidOperationException(ProxyAccessExceptionMessage);
}

// Inherited from IGameStarter and generated by Roslyn
// From IGameStarter (Roslyn-generated)
public void StartGame()
{
throw new InvalidOperationException(ProxyAccessExceptionMessage);
Expand Down
2 changes: 1 addition & 1 deletion Docs/docs/core-concepts/serialized-interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Unity serialization supports concrete serializable data and `UnityEngine.Object`
An interface is only a contract, not a concrete serializable type.
So a member typed as `IMyService` is skipped by Unity's serializer unless you add an explicit serialization bridge.

In DI-heavy code, this matters because Saneject writes resolved dependencies into serialized members.
This matters because Saneject writes resolved dependencies into serialized members.
If interface members cannot serialize, interface-based injection cannot persist in scenes and prefabs.

## What the Saneject Roslyn generator adds
Expand Down
3 changes: 2 additions & 1 deletion Docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Add this URL to Unity Package Manager (Unity 2022.3.12 or newer):
https://github.com/alexanderlarsen/Saneject.git?path=UnityProject/Saneject/Assets/Plugins/Saneject
```

Or download the [latest release](https://github.com/alexanderlarsen/Saneject/releases) and import the `Saneject` folder into your Unity project.
Or download the [latest release](https://github.com/alexanderlarsen/Saneject/releases) and import it folder into your Unity project.

Then jump to [Quick start](docs/getting-started/quick-start.md).

Expand All @@ -74,5 +74,6 @@ If you try Saneject and something works well, feels unclear, or seems broken, I
- [API](xref:Plugins.Saneject.Editor.Inspectors.SanejectInspector)
- [GitHub repo](https://github.com/alexanderlarsen/Saneject)
- [Releases](https://github.com/alexanderlarsen/Saneject/releases)
- [Changelog](https://github.com/alexanderlarsen/Saneject/blob/main/CHANGELOG.md)
- [MIT license](https://github.com/alexanderlarsen/Saneject/blob/main/LICENSE)

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Add this URL to Unity Package Manager (Unity 2022.3.12 or newer):
https://github.com/alexanderlarsen/Saneject.git?path=UnityProject/Saneject/Assets/Plugins/Saneject
```

Or download the [latest release](https://github.com/alexanderlarsen/Saneject/releases) and import the `Saneject` folder into your Unity project.
Or download the [latest release](https://github.com/alexanderlarsen/Saneject/releases) and import it folder into your Unity project.

Then jump to [Quick start](https://saneject.dev/docs/getting-started/quick-start).

Expand All @@ -72,4 +72,5 @@ If you try Saneject and something works well, feels unclear, or seems broken, I
- [Docs](https://saneject.dev/docs/getting-started/introduction)
- [API](https://saneject.dev/api/Plugins.Saneject.Editor.Inspectors.SanejectInspector)
- [Releases](https://github.com/alexanderlarsen/Saneject/releases)
- [Changelog](https://github.com/alexanderlarsen/Saneject/blob/main/CHANGELOG.md)
- [MIT license](https://github.com/alexanderlarsen/Saneject/blob/main/LICENSE)
Loading