Skip to content

Commit

Permalink
Fix Reconnection Logic (#168)
Browse files Browse the repository at this point in the history
## Description of Changes
*Describe what has been changed, any new features or bug fixes*

- switched our "already connected" logic to using a reference to a
`MonoBehaviour` instead of just a bool. `MonoBehaviour`s are typically
destroyed when a scene reload happens and in this case we'll want to
allow developers to spawn a new `SpacetimeDBNetworkManager` if the
previous one has been destroyed.

## API

This is *not* an API break.

 - [ ] This is an API breaking change to the SDK

*If the API is breaking, please state below what will break*

## Requires SpacetimeDB PRs
*List any PRs here that are required for this SDK change to work*

- clockworklabs/SpacetimeDB#1869

## Testsuite

SpacetimeDB branch name: master

## Testing
*Write instructions for a test that you performed for this PR*

- [x] I have added in several new tests here, one of which is a
reconnection test. Also, the reason why we couldn't have more than 1
test before this is that it was required for reconnections to be working
in order to have multiple tests running in the testsuite. Now that we
have fixed reconnections I have enabled all of the tests.

Testsuite passes


![image](https://github.com/user-attachments/assets/09ef5835-f2c7-41f1-af6b-e612ac5e0497)

---------

Co-authored-by: John Detter <[email protected]>
Co-authored-by: Mazdak Farrokhzad <[email protected]>
Co-authored-by: Jeremie Pelletier <[email protected]>
Co-authored-by: Zeke Foppa <[email protected]>
  • Loading branch information
5 people authored Oct 31, 2024
1 parent 9a56704 commit 3581ed7
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unity-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
pull_request:

jobs:
test:
unity-testsuite:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/unity-testsuite-bindings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
pull_request:

jobs:
test:
check-testsuite-bindings:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
Expand Down Expand Up @@ -110,7 +110,7 @@ jobs:
- name: Check for changes
run: |
git diff --exit-code
git diff --exit-code unity-tests~/client/Assets/Scripts/autogen
continue-on-error: true

- name: Fail if there are changes
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,4 @@ obj~
# This is used for local paths to SpacetimeDB packages.
/nuget.config
/nuget.config.meta
.idea/
13 changes: 11 additions & 2 deletions src/SpacetimeDBClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public DbConnection Build()
}
conn.Connect(token, uri, nameOrAddress, compression ?? Compression.Brotli);
#if UNITY_5_3_OR_NEWER
SpacetimeDBNetworkManager.ActiveConnections.Add(conn);
if (SpacetimeDBNetworkManager._instance != null)
{
SpacetimeDBNetworkManager._instance.AddConnection(conn);
}
#endif
return conn;
}
Expand Down Expand Up @@ -163,7 +166,13 @@ protected DbConnectionBase()
webSocket.OnMessage += OnMessageReceived;
webSocket.OnSendError += a => onSendError?.Invoke(a);
#if UNITY_5_3_OR_NEWER
webSocket.OnClose += (e) => SpacetimeDBNetworkManager.ActiveConnections.Remove(this);
webSocket.OnClose += (e) =>
{
if (SpacetimeDBNetworkManager._instance != null)
{
SpacetimeDBNetworkManager._instance.RemoveConnection(this);
}
};
#endif

networkMessageProcessThread = new Thread(PreProcessMessages);
Expand Down
76 changes: 47 additions & 29 deletions src/SpacetimeDBNetworkManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,56 @@

namespace SpacetimeDB
{
// This class is only used in Unity projects.
// Attach this to a gameobject in your scene to use SpacetimeDB.
public class SpacetimeDBNetworkManager : MonoBehaviour
{
private static bool _alreadyInitialized;
// This class is only used in Unity projects.
// Attach this to a GameObject in your scene to use SpacetimeDB.
public class SpacetimeDBNetworkManager : MonoBehaviour
{
internal static SpacetimeDBNetworkManager? _instance;

public void Awake()
{
// Ensure that users don't create several SpacetimeDBNetworkManager instances.
// We're using a global (static) list of active connections and we don't want several instances to walk over it several times.
if (_alreadyInitialized)
{
throw new InvalidOperationException("SpacetimeDBNetworkManager is a singleton and should only be attached once.");
}
else
{
_alreadyInitialized = true;
}
}
public void Awake()
{
// Ensure that users don't create several SpacetimeDBNetworkManager instances.
// We're using a global (static) list of active connections and we don't want several instances to walk over it several times.
if (_instance != null)
{
throw new InvalidOperationException("SpacetimeDBNetworkManager is a singleton and should only be attached once.");
}
else
{
_instance = this;
}
}

internal static HashSet<IDbConnection> ActiveConnections = new();
private readonly List<IDbConnection> activeConnections = new();

private void ForEachConnection(Action<IDbConnection> action)
{
foreach (var conn in ActiveConnections)
{
action(conn);
}
}
public bool AddConnection(IDbConnection conn)
{
if (activeConnections.Contains(conn))
{
return false;
}
activeConnections.Add(conn);
return true;

private void Update() => ForEachConnection(conn => conn.FrameTick());
private void OnDestroy() => ForEachConnection(conn => conn.Disconnect());
}
}

public bool RemoveConnection(IDbConnection conn)
{
return activeConnections.Remove(conn);
}

private void ForEachConnection(Action<IDbConnection> action)
{
// It's common to call disconnect from Update, which will then modify the ActiveConnections collection,
// therefore we must reverse-iterate the list of connections.
for (var x = activeConnections.Count - 1; x >= 0; x--)
{
action(activeConnections[x]);
}
}

private void Update() => ForEachConnection(conn => conn.FrameTick());
private void OnDestroy() => ForEachConnection(conn => conn.Disconnect());
}
}
#endif
2 changes: 1 addition & 1 deletion unity-tests~
Submodule unity-tests~ updated 80 files
+1 −0 client/.gitignore
+0 −5 client/.vscode/extensions.json
+0 −10 client/.vscode/launch.json
+0 −60 client/.vscode/settings.json
+8 −0 client/Assets/PlayModeTests.meta
+284 −0 client/Assets/PlayModeTests/PlayModeExampleTest.cs
+11 −0 client/Assets/PlayModeTests/PlayModeExampleTest.cs.meta
+25 −0 client/Assets/PlayModeTests/PlayModeTests.asmdef
+7 −0 client/Assets/PlayModeTests/PlayModeTests.asmdef.meta
+8 −0 client/Assets/Scripts.meta
+0 −0 client/Assets/Scripts/ArenaController.cs
+0 −0 client/Assets/Scripts/ArenaController.cs.meta
+0 −0 client/Assets/Scripts/BugFixKludge.cs
+0 −0 client/Assets/Scripts/BugFixKludge.cs.meta
+2 −1 client/Assets/Scripts/CenterOnPlayer.cs
+0 −0 client/Assets/Scripts/CenterOnPlayer.cs.meta
+0 −0 client/Assets/Scripts/CircleController.cs
+0 −0 client/Assets/Scripts/CircleController.cs.meta
+4 −1 client/Assets/Scripts/FoodController.cs
+0 −0 client/Assets/Scripts/FoodController.cs.meta
+31 −6 client/Assets/Scripts/GameManager.cs
+0 −0 client/Assets/Scripts/GameManager.cs.meta
+0 −0 client/Assets/Scripts/LeaderboardController.cs
+0 −0 client/Assets/Scripts/LeaderboardController.cs.meta
+0 −0 client/Assets/Scripts/LeaderboardRow.cs
+0 −0 client/Assets/Scripts/LeaderboardRow.cs.meta
+11 −2 client/Assets/Scripts/PlayerController.cs
+0 −0 client/Assets/Scripts/PlayerController.cs.meta
+18 −0 client/Assets/Scripts/SpacetimeDBCircleGame.asmdef
+7 −0 client/Assets/Scripts/SpacetimeDBCircleGame.asmdef.meta
+3 −0 client/Assets/Scripts/UIUsernameChooser.cs
+0 −0 client/Assets/Scripts/UIUsernameChooser.cs.meta
+0 −0 client/Assets/Scripts/autogen.meta
+0 −0 client/Assets/Scripts/autogen/Circle.cs
+0 −0 client/Assets/Scripts/autogen/Circle.cs.meta
+0 −0 client/Assets/Scripts/autogen/CircleDecayReducer.cs
+0 −0 client/Assets/Scripts/autogen/CircleDecayReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/CircleDecayTimer.cs
+0 −0 client/Assets/Scripts/autogen/CircleDecayTimer.cs.meta
+0 −0 client/Assets/Scripts/autogen/Config.cs
+0 −0 client/Assets/Scripts/autogen/Config.cs.meta
+0 −0 client/Assets/Scripts/autogen/CreatePlayerReducer.cs
+0 −0 client/Assets/Scripts/autogen/CreatePlayerReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/Entity.cs
+0 −0 client/Assets/Scripts/autogen/Entity.cs.meta
+0 −0 client/Assets/Scripts/autogen/Food.cs
+0 −0 client/Assets/Scripts/autogen/Food.cs.meta
+0 −0 client/Assets/Scripts/autogen/LoggedOutCircle.cs
+0 −0 client/Assets/Scripts/autogen/LoggedOutCircle.cs.meta
+0 −0 client/Assets/Scripts/autogen/LoggedOutPlayer.cs
+0 −0 client/Assets/Scripts/autogen/LoggedOutPlayer.cs.meta
+0 −0 client/Assets/Scripts/autogen/MoveAllPlayersReducer.cs
+0 −0 client/Assets/Scripts/autogen/MoveAllPlayersReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/MoveAllPlayersTimer.cs
+0 −0 client/Assets/Scripts/autogen/MoveAllPlayersTimer.cs.meta
+0 −0 client/Assets/Scripts/autogen/Player.cs
+0 −0 client/Assets/Scripts/autogen/Player.cs.meta
+0 −0 client/Assets/Scripts/autogen/PlayerSplitReducer.cs
+0 −0 client/Assets/Scripts/autogen/PlayerSplitReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/RespawnReducer.cs
+0 −0 client/Assets/Scripts/autogen/RespawnReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/SpawnFoodReducer.cs
+0 −0 client/Assets/Scripts/autogen/SpawnFoodReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/SpawnFoodTimer.cs
+0 −0 client/Assets/Scripts/autogen/SpawnFoodTimer.cs.meta
+0 −0 client/Assets/Scripts/autogen/UpdatePlayerInputReducer.cs
+0 −0 client/Assets/Scripts/autogen/UpdatePlayerInputReducer.cs.meta
+0 −0 client/Assets/Scripts/autogen/Vector2.cs
+0 −0 client/Assets/Scripts/autogen/Vector2.cs.meta
+0 −0 client/Assets/Scripts/autogen/_Globals.meta
+0 −0 client/Assets/Scripts/autogen/_Globals/SpacetimeDBClient.cs
+0 −0 client/Assets/Scripts/autogen/_Globals/SpacetimeDBClient.cs.meta
+2 −1 client/Packages/manifest.json
+20 −4 client/Packages/packages-lock.json
+5 −0 client/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json
+5 −3 client/ProjectSettings/ProjectSettings.asset
+0 −0 client/SpacetimeDB.BSATN.Codegen/SpacetimeDB.Codegen.Type/SpacetimeDB.Types.ScheduleAt.cs
+1 −1 server/Cargo.toml
+1 −1 server/generate.sh
+5 −0 server/publish.sh

0 comments on commit 3581ed7

Please sign in to comment.