diff --git a/Assets/PlayroomKit/Tests/Editor/PlayerTests.cs b/Assets/PlayroomKit/Tests/Editor/PlayerTests.cs index be690f99..935b96b5 100644 --- a/Assets/PlayroomKit/Tests/Editor/PlayerTests.cs +++ b/Assets/PlayroomKit/Tests/Editor/PlayerTests.cs @@ -257,13 +257,47 @@ public void Kick_CallsInvokeKickInternal_CallbackIsInvoked() public void WaitForState_WhenInitialized_CallsWaitForPlayerStateWrapperWithCorrectParameters() { // Arrange - Action onStateSetCallback = (data) => { Debug.Log("data: " + data); }; + string callbackId = null; + string receivedData = null; + string testData = "TestStateData"; + + Action onStateSetCallback = (data) => + { + receivedData = data; + }; + + Action internalCallback = null; + + // Set up the mock to capture the callback and callbackId when WaitForPlayerStateWrapper is called + _interop.When(x => x.WaitForPlayerStateWrapper( + Arg.Any(), // id + Arg.Any(), // stateKey + Arg.Any>(), // callback + Arg.Any() // callbackId + )) + .Do(callInfo => + { + // Capture the callback and callbackId for later use + internalCallback = callInfo.ArgAt>(2); + callbackId = callInfo.ArgAt(3); + }); // Act _player.WaitForState(testKey, onStateSetCallback); - // Assert - _interop.Received(1).WaitForPlayerStateWrapper(testId, testKey, onStateSetCallback); + // Capture internal callback and callbackId from wrapper + _interop.Received(1).WaitForPlayerStateWrapper( + testId, + testKey, + Arg.Any>(), + Arg.Any() + ); + + // Simulate invoking the callback from the interop layer + internalCallback?.Invoke(testData, callbackId); + + //Assert + Assert.AreEqual(testData, receivedData, "Expected the received data to match the test data."); } } } \ No newline at end of file diff --git a/Assets/PlayroomKit/Tests/Editor/PlayroomKitTest.cs b/Assets/PlayroomKit/Tests/Editor/PlayroomKitTest.cs index 1729af81..7c576f84 100644 --- a/Assets/PlayroomKit/Tests/Editor/PlayroomKitTest.cs +++ b/Assets/PlayroomKit/Tests/Editor/PlayroomKitTest.cs @@ -325,20 +325,55 @@ void Callback2(string data) _interop.Received(1).WaitForStateWrapper("state", Arg.Any>()); } - [Test] public void WaitForPlayerState_ShouldInvokeInternal_WhenCalled() { - void Callback(string data) + // Arrange + string callbackId = null; + string receivedData = null; + string testData = "TestStateData"; + + Action onStateSetCallback = (data) => { - Debug.Log($"Callback called!: " + data); - } + receivedData = data; + }; + + Action internalCallback = null; var playerId = "1234"; var state = "state"; - _playroomKit.WaitForPlayerState(playerId, state, Callback); - _interop.Received(1).WaitForPlayerStateWrapper(playerId, state, Arg.Any>()); + // Set up the mock to capture the callback and callbackId when WaitForPlayerStateWrapper is called + _interop.When(x => x.WaitForPlayerStateWrapper( + Arg.Any(), // id + Arg.Any(), // stateKey + Arg.Any>(), // callback + Arg.Any() // callbackId + )) + .Do(callInfo => + { + // Capture the callback and callbackId for later use + internalCallback = callInfo.ArgAt>(2); + callbackId = callInfo.ArgAt(3); + }); + + + // Act + _playroomKit.WaitForPlayerState(playerId, state, onStateSetCallback); + + // Capture internal callback and callbackId from wrapper + _interop.Received(1).WaitForPlayerStateWrapper( + playerId, + state, + Arg.Any>(), + Arg.Any() + ); + + // Simulate invoking the callback from the interop layer + internalCallback?.Invoke(testData, callbackId); + + //Assert + Assert.AreEqual(testData, receivedData, "Expected the received data to match the test data."); } [Test] diff --git a/Assets/PlayroomKit/modules/Headers.cs b/Assets/PlayroomKit/modules/Headers.cs index 10b7256f..408460e4 100644 --- a/Assets/PlayroomKit/modules/Headers.cs +++ b/Assets/PlayroomKit/modules/Headers.cs @@ -93,7 +93,8 @@ private static extern void InsertCoinInternal(string options, [DllImport("__Internal")] private static extern void WaitForPlayerStateInternal(string playerID, string stateKey, - Action onStateSetCallback = null); + Action onStateSetCallback, string callbackID); + [DllImport("__Internal")] private static extern string GetPlayroomTokenInternal(); diff --git a/Assets/PlayroomKit/modules/Helpers/InternalFunctions/IInternalFunctions.cs b/Assets/PlayroomKit/modules/Helpers/InternalFunctions/IInternalFunctions.cs index b5c8b657..be1fb53f 100644 --- a/Assets/PlayroomKit/modules/Helpers/InternalFunctions/IInternalFunctions.cs +++ b/Assets/PlayroomKit/modules/Helpers/InternalFunctions/IInternalFunctions.cs @@ -50,7 +50,7 @@ void InsertCoinWrapper(string options, void WaitForStateWrapper(string stateKey, Action onStateSetCallback); - void WaitForPlayerStateWrapper(string playerID, string stateKey, Action onStateSetCallback); + void WaitForPlayerStateWrapper(string playerID, string stateKey, Action onStateSetCallback, string callbackID); void ResetStatesWrapper(string keysToExclude = null, Action OnStatesReset = null); diff --git a/Assets/PlayroomKit/modules/Helpers/InternalFunctions/InterlopWrapper.cs b/Assets/PlayroomKit/modules/Helpers/InternalFunctions/InterlopWrapper.cs index 03ee8bd2..9a9815df 100644 --- a/Assets/PlayroomKit/modules/Helpers/InternalFunctions/InterlopWrapper.cs +++ b/Assets/PlayroomKit/modules/Helpers/InternalFunctions/InterlopWrapper.cs @@ -175,9 +175,9 @@ public void KickPlayerWrapper(string playerID, Action onKickCallback = null) // Wrapper for WaitForPlayerStateInternal public void WaitForPlayerStateWrapper(string playerID, string stateKey, - Action onStateSetCallback = null) + Action onStateSetCallback, string callbackID) { - WaitForPlayerStateInternal(playerID, stateKey, onStateSetCallback); + WaitForPlayerStateInternal(playerID, stateKey, onStateSetCallback, callbackID); } // Wrapper for SetPlayerStateByPlayerId (int version) @@ -289,7 +289,6 @@ public void OpenDiscordInviteDialogInternalWrapper(Action callback = null) OpenDiscordInviteDialogInternal(callback); } - #endregion } } diff --git a/Assets/PlayroomKit/modules/Player/PlayerService.cs b/Assets/PlayroomKit/modules/Player/PlayerService.cs index 2198aafa..17bc6a3d 100644 --- a/Assets/PlayroomKit/modules/Player/PlayerService.cs +++ b/Assets/PlayroomKit/modules/Player/PlayerService.cs @@ -196,18 +196,16 @@ private static void InvokeLeaveRoom() IPlayerBase.onKickCallBack?.Invoke(); } - private static Action onSetState; - public void WaitForState(string stateKey, Action onStateSetCallback = null) { - onSetState = onStateSetCallback; - _interop.WaitForPlayerStateWrapper(_id, stateKey, InvokeKickCallBack); + string callbackId = CallbackManager.RegisterCallback(onStateSetCallback); + _interop.WaitForPlayerStateWrapper(_id, stateKey, InvokeOnSetStateCallBack, callbackId); } - [MonoPInvokeCallback(typeof(Action))] - private static void InvokeKickCallBack(string data) + [MonoPInvokeCallback(typeof(Action))] + private static void InvokeOnSetStateCallBack(string data, string callbackId) { - onSetState?.Invoke(data); + CallbackManager.InvokeCallback(callbackId, data); } [MonoPInvokeCallback(typeof(Action))] diff --git a/Assets/PlayroomKit/modules/PlayroomBuildService.cs b/Assets/PlayroomKit/modules/PlayroomBuildService.cs index 66429e08..78f0ff55 100644 --- a/Assets/PlayroomKit/modules/PlayroomBuildService.cs +++ b/Assets/PlayroomKit/modules/PlayroomBuildService.cs @@ -302,12 +302,10 @@ public void WaitForState(string stateKey, Action onStateSetCallback = nu _interop.WaitForStateWrapper(stateKey, IPlayroomBase.InvokeCallback); } - Action WaitForPlayerCallback = null; - public void WaitForPlayerState(string playerID, string stateKey, Action onStateSetCallback = null) { - WaitForPlayerCallback = onStateSetCallback; - _interop.WaitForPlayerStateWrapper(playerID, stateKey, OnStateSetCallback); + string callbackID = CallbackManager.RegisterCallback(onStateSetCallback); + _interop.WaitForPlayerStateWrapper(playerID, stateKey, OnStateSetCallback, callbackID); } public void ResetStates(string[] keysToExclude = null, Action onStatesReset = null) @@ -576,10 +574,10 @@ private static void InvokeInsertCoin(string key) #endif } - [MonoPInvokeCallback(typeof(Action))] - void OnStateSetCallback(string data) + [MonoPInvokeCallback(typeof(Action))] + void OnStateSetCallback(string data, string callbackId) { - WaitForPlayerCallback?.Invoke(data); + CallbackManager.InvokeCallback(callbackId, data); } [MonoPInvokeCallback(typeof(Action))] diff --git a/Assets/PlayroomKit/src/index.js b/Assets/PlayroomKit/src/index.js index 52a930f1..4a5f80aa 100644 --- a/Assets/PlayroomKit/src/index.js +++ b/Assets/PlayroomKit/src/index.js @@ -758,7 +758,8 @@ mergeInto(LibraryManager.library, { WaitForPlayerStateInternal: function ( playerId, stateKey, - onStateSetCallback + onStateSetCallback, + callbackIdPtr ) { if (!window.Playroom) { console.error( @@ -767,7 +768,7 @@ mergeInto(LibraryManager.library, { reject("Playroom library not loaded"); return; } - + const callbackId = UTF8ToString(callbackIdPtr); const players = Playroom.Multiplayer().getPlayers() if (typeof players !== "object" || players === null) { @@ -784,7 +785,7 @@ mergeInto(LibraryManager.library, { stateKey = UTF8ToString(stateKey); Playroom.waitForPlayerState(playerState, stateKey) .then((stateVal) => { - {{{ makeDynCall('vi', 'onStateSetCallback') }}}(stringToNewUTF8(stateVal)) + {{{ makeDynCall('vii', 'onStateSetCallback') }}}(stringToNewUTF8(stateVal), stringToNewUTF8(callbackId)) }) .catch((error) => { console.error("Error waiting for state:", error);