public FakeRemote() { runtime = new InputTestRuntime(); var manager = new InputManager(); manager.m_Settings = ScriptableObject.CreateInstance <InputSettings>(); manager.InitializeData(); manager.InstallRuntime(runtime); manager.ApplySettings(); local = new InputRemoting(InputSystem.s_Manager); remote = new InputRemoting(manager); var remoteInstaller = new GlobalsInstallerObserver(manager); var localInstaller = new GlobalsInstallerObserver(InputSystem.s_Manager); // The installers will ensure the globals environment is prepared right before // the receiver processes the message. There are some static fields, such as // the layouts collection, that needs to be set to that InputManager's version. // After processing, the environment will be reverted back to the local manager // to keep it the default. local.Subscribe(remoteInstaller); local.Subscribe(remote); local.Subscribe(localInstaller); remote.Subscribe(localInstaller); remote.Subscribe(local); local.StartSending(); }
public void Remote_CanConnectTwoInputSystemsOverNetwork() { // Add some data to the local input system. InputSystem.AddDevice("Gamepad"); InputSystem.RegisterControlLayout(@"{ ""name"" : ""MyGamepad"", ""extend"" : ""Gamepad"" }"); var localGamepad = (Gamepad)InputSystem.AddDevice("MyGamepad"); // Now create another input system instance and connect it // to our "local" instance. // NOTE: This relies on internal APIs. We want remoting as such to be available // entirely from user land but having multiple input systems in the same // application isn't something that we necessarily want to expose (we do // have global state so it can easily lead to surprising results). var secondInputRuntime = new InputTestRuntime(); var secondInputManager = new InputManager(); secondInputManager.InstallRuntime(secondInputRuntime); secondInputManager.InitializeData(); var local = new InputRemoting(InputSystem.s_Manager); var remote = new InputRemoting(secondInputManager); // We wire the two directly into each other effectively making function calls // our "network transport layer". In a real networking situation, we'd effectively // have an RPC-like mechanism sitting in-between. local.Subscribe(remote); remote.Subscribe(local); local.StartSending(); var remoteGamepadLayout = string.Format("{0}0::{1}", InputRemoting.kRemoteLayoutNamespacePrefix, localGamepad.layout); // Make sure that our "remote" system now has the data we initially // set up on the local system. Assert.That(secondInputManager.devices, Has.Exactly(1).With.Property("layout").EqualTo(remoteGamepadLayout)); Assert.That(secondInputManager.devices, Has.Exactly(2).TypeOf <Gamepad>()); Assert.That(secondInputManager.devices, Has.All.With.Property("remote").True); // Send state event to local gamepad. InputSystem.QueueStateEvent(localGamepad, new GamepadState { leftTrigger = 0.5f }); InputSystem.Update(); // Make second input manager process the events it got. // NOTE: This will also switch the system to the state buffers from the second input manager. secondInputManager.Update(); var remoteGamepad = (Gamepad)secondInputManager.devices.First(x => x.layout == remoteGamepadLayout); Assert.That(remoteGamepad.leftTrigger.ReadValue(), Is.EqualTo(0.5).Within(0.0000001)); secondInputRuntime.Dispose(); }
public void Receiver() { var receiver = new Receiver(_channel1); var receiverInput = new InputRemoting(receiver); var receiverDisposer = receiverInput.Subscribe(receiverInput); receiverInput.StartSending(); receiverInput.StopSending(); receiverDisposer.Dispose(); }
public void Sender() { var sender = new Sender(); var senderInput = new InputRemoting(sender); var senderDisposer = senderInput.Subscribe(new Observer(_channel1)); senderInput.StartSending(); senderInput.StopSending(); senderDisposer.Dispose(); }
public void Receiver() { var receiver = new Receiver(_channel1); Assert.That(receiver.remoteDevices, Is.Empty); Assert.That(receiver.remoteLayouts, Is.Empty); var receiverInput = new InputRemoting(receiver); var receiverDisposer = receiverInput.Subscribe(receiverInput); receiverInput.StartSending(); receiverInput.StopSending(); receiverDisposer.Dispose(); }
public void Remote_CanConnectInputSystemsOverEditorPlayerConnection() { var connectionToEditor = ScriptableObject.CreateInstance <RemoteInputPlayerConnection>(); var connectionToPlayer = ScriptableObject.CreateInstance <RemoteInputPlayerConnection>(); connectionToEditor.name = "ConnectionToEditor"; connectionToPlayer.name = "ConnectionToPlayer"; var fakeEditorConnection = new FakePlayerConnection { playerId = 0 }; var fakePlayerConnection = new FakePlayerConnection { playerId = 1 }; fakeEditorConnection.otherEnd = fakePlayerConnection; fakePlayerConnection.otherEnd = fakeEditorConnection; var observer = new RemoteTestObserver(); // In the Unity API, "PlayerConnection" is the connection to the editor // and "EditorConnection" is the connection to the player. Seems counter-intuitive. connectionToEditor.Bind(fakePlayerConnection, true); connectionToPlayer.Bind(fakeEditorConnection, true); // Bind a local remote on the player side. var local = new InputRemoting(InputSystem.s_Manager); local.Subscribe(connectionToEditor); local.StartSending(); connectionToPlayer.Subscribe(observer); var device = InputSystem.AddDevice("Gamepad"); InputSystem.QueueStateEvent(device, new GamepadState()); InputSystem.Update(); InputSystem.RemoveDevice(device); ////TODO: make sure that we also get the connection sequence right and send our initial layouts and devices Assert.That(observer.messages, Has.Count.EqualTo(4)); Assert.That(observer.messages[0].type, Is.EqualTo(InputRemoting.MessageType.Connect)); Assert.That(observer.messages[1].type, Is.EqualTo(InputRemoting.MessageType.NewDevice)); Assert.That(observer.messages[2].type, Is.EqualTo(InputRemoting.MessageType.NewEvents)); Assert.That(observer.messages[3].type, Is.EqualTo(InputRemoting.MessageType.RemoveDevice)); ////TODO: test disconnection ScriptableObject.Destroy(connectionToEditor); ScriptableObject.Destroy(connectionToPlayer); }
public void Sender() { var sender = new Sender(); Assert.That(sender.layouts, Is.Not.Empty); Assert.That(sender.devices, Is.Not.Empty); var senderInput = new InputRemoting(sender); var senderDisposer = senderInput.Subscribe(new Observer(_channel1)); senderInput.StartSending(); senderInput.StopSending(); senderDisposer.Dispose(); sender.Dispose(); }
public IEnumerator AddDevice() { var sender = new Sender(); var senderInput = new InputRemoting(sender); var senderSubscriberDisposer = senderInput.Subscribe(new Observer(_channel1)); var receiver = new Receiver(_channel2); var receiverInput = new InputRemoting(receiver); var receiverSubscriberDisposer = receiverInput.Subscribe(receiverInput); InputDevice device = null; InputDeviceChange change = default; receiver.onDeviceChange += (_device, _change) => { device = _device; change = _change; }; string layoutName = null; InputControlLayoutChange layoutChange = default; receiver.onLayoutChange += (_name, _change) => { layoutName = _name; layoutChange = _change; }; receiverInput.StartSending(); senderInput.StartSending(); yield return(new WaitUntil(() => device != null)); yield return(new WaitUntil(() => layoutName != null)); Assert.That(device, Is.Not.Null); Assert.That(change, Is.EqualTo(InputDeviceChange.Added)); Assert.That(layoutName, Is.Not.Null); Assert.That(layoutChange, Is.EqualTo(InputControlLayoutChange.Added)); Assert.That(receiver.remoteLayouts, Is.Not.Empty); Assert.That(receiver.remoteDevices, Is.Not.Empty); Assert.That(receiver.remoteDevices, Has.All.Matches <InputDevice>(d => d.remote)); senderInput.StopSending(); receiverInput.StopSending(); senderSubscriberDisposer.Dispose(); receiverSubscriberDisposer.Dispose(); sender.Dispose(); receiver.Dispose(); }
public FakeRemote() { runtime = new InputTestRuntime(); manager = new InputManager(); manager.InstallRuntime(runtime); manager.InitializeData(); local = new InputRemoting(InputSystem.s_Manager); remote = new InputRemoting(manager); local.Subscribe(remote); remote.Subscribe(local); local.StartSending(); }
public void Remote_ChangingLayoutsWhileRemoting_WillSendChangesToRemote() { var secondInputSystem = new InputManager(); secondInputSystem.InitializeData(); var local = new InputRemoting(InputSystem.s_Manager); var remote = new InputRemoting(secondInputSystem); local.Subscribe(remote); remote.Subscribe(local); local.StartSending(); const string jsonV1 = @" { ""name"" : ""MyLayout"", ""extend"" : ""Gamepad"" } "; // Add layout. InputSystem.RegisterControlLayout(jsonV1); var layout = secondInputSystem.TryLoadControlLayout(new InternedString("remote0::MyLayout")); Assert.That(layout, Is.Not.Null); Assert.That(layout.extendsLayout, Is.EqualTo("remote0::Gamepad")); const string jsonV2 = @" { ""name"" : ""MyLayout"", ""extend"" : ""Keyboard"" } "; // Change layout. InputSystem.RegisterControlLayout(jsonV2); layout = secondInputSystem.TryLoadControlLayout(new InternedString("remote0::MyLayout")); Assert.That(layout.extendsLayout, Is.EqualTo("remote0::Keyboard")); // Remove layout. InputSystem.RemoveControlLayout("MyLayout"); Assert.That(secondInputSystem.TryLoadControlLayout(new InternedString("remote0::MyLayout")), Is.Null); }
public FakeRemote() { runtime = new InputTestRuntime(); manager = new InputManager(); manager.m_Settings = ScriptableObject.CreateInstance <InputSettings>(); manager.InstallRuntime(runtime); manager.InitializeData(); manager.ApplySettings(); local = new InputRemoting(InputSystem.s_Manager); remote = new InputRemoting(manager); local.Subscribe(remote); remote.Subscribe(local); local.StartSending(); }
public void Remote_ChangingDevicesWhileRemoting_WillSendChangesToRemote() { var secondInputRuntime = new InputTestRuntime(); var secondInputManager = new InputManager(); secondInputManager.InstallRuntime(secondInputRuntime); secondInputManager.InitializeData(); var local = new InputRemoting(InputSystem.s_Manager); var remote = new InputRemoting(secondInputManager); local.Subscribe(remote); remote.Subscribe(local); local.StartSending(); // Add device. var localGamepad = InputSystem.AddDevice("Gamepad"); secondInputManager.Update(); Assert.That(secondInputManager.devices, Has.Count.EqualTo(1)); var remoteGamepad = secondInputManager.devices[0]; Assert.That(remoteGamepad, Is.TypeOf <Gamepad>()); Assert.That(remoteGamepad.remote, Is.True); Assert.That(remoteGamepad.layout, Contains.Substring("Gamepad")); // Change usage. InputSystem.SetUsage(localGamepad, CommonUsages.LeftHand); secondInputManager.Update(); Assert.That(remoteGamepad.usages, Has.Exactly(1).EqualTo(CommonUsages.LeftHand)); // Bind and disconnect are events so no need to test those. // Remove device. InputSystem.RemoveDevice(localGamepad); secondInputManager.Update(); Assert.That(secondInputManager.devices, Has.Count.Zero); secondInputRuntime.Dispose(); }
public void Remote_CanConnectInputSystemsOverEditorPlayerConnection() { #if UNITY_EDITOR // In the editor, RemoteInputPlayerConnection is a scriptable singleton. Creating multiple instances of it // will cause an error messages - but will work nevertheless, so we expect those errors to let us run the test. // We call RemoteInputPlayerConnection.instance once to make sure that we an instance is created, and we get // a deterministic number of two errors. var instance = RemoteInputPlayerConnection.instance; UnityEngine.TestTools.LogAssert.Expect(LogType.Error, "ScriptableSingleton already exists. Did you query the singleton in a constructor?"); UnityEngine.TestTools.LogAssert.Expect(LogType.Error, "ScriptableSingleton already exists. Did you query the singleton in a constructor?"); #endif var connectionToEditor = ScriptableObject.CreateInstance <RemoteInputPlayerConnection>(); var connectionToPlayer = ScriptableObject.CreateInstance <RemoteInputPlayerConnection>(); connectionToEditor.name = "ConnectionToEditor"; connectionToPlayer.name = "ConnectionToPlayer"; var fakeEditorConnection = new FakePlayerConnection { playerId = 0 }; var fakePlayerConnection = new FakePlayerConnection { playerId = 1 }; fakeEditorConnection.otherEnd = fakePlayerConnection; fakePlayerConnection.otherEnd = fakeEditorConnection; var observerEditor = new RemoteTestObserver(); var observerPlayer = new RemoteTestObserver(); // In the Unity API, "PlayerConnection" is the connection to the editor // and "EditorConnection" is the connection to the player. Seems counter-intuitive. connectionToEditor.Bind(fakePlayerConnection, true); connectionToPlayer.Bind(fakeEditorConnection, true); // Bind a local remote on the player side. var local = new InputRemoting(InputSystem.s_Manager); local.Subscribe(connectionToEditor); connectionToEditor.Subscribe(local); connectionToPlayer.Subscribe(observerEditor); connectionToEditor.Subscribe(observerPlayer); fakeEditorConnection.Send(RemoteInputPlayerConnection.kStartSendingMsg, null); var device = InputSystem.AddDevice <Gamepad>(); InputSystem.QueueStateEvent(device, new GamepadState()); InputSystem.Update(); InputSystem.RemoveDevice(device); fakeEditorConnection.Send(RemoteInputPlayerConnection.kStopSendingMsg, null); // We should not obseve any messages for these, as we stopped sending! device = InputSystem.AddDevice <Gamepad>(); InputSystem.QueueStateEvent(device, new GamepadState()); InputSystem.Update(); InputSystem.RemoveDevice(device); fakeEditorConnection.DisconnectAll(); ////TODO: make sure that we also get the connection sequence right and send our initial layouts and devices Assert.That(observerEditor.messages, Has.Count.EqualTo(5)); Assert.That(observerEditor.messages[0].type, Is.EqualTo(InputRemoting.MessageType.Connect)); Assert.That(observerEditor.messages[1].type, Is.EqualTo(InputRemoting.MessageType.NewDevice)); Assert.That(observerEditor.messages[2].type, Is.EqualTo(InputRemoting.MessageType.NewEvents)); Assert.That(observerEditor.messages[3].type, Is.EqualTo(InputRemoting.MessageType.RemoveDevice)); Assert.That(observerEditor.messages[4].type, Is.EqualTo(InputRemoting.MessageType.Disconnect)); Assert.That(observerPlayer.messages, Has.Count.EqualTo(3)); Assert.That(observerPlayer.messages[0].type, Is.EqualTo(InputRemoting.MessageType.Connect)); Assert.That(observerPlayer.messages[1].type, Is.EqualTo(InputRemoting.MessageType.StartSending)); Assert.That(observerPlayer.messages[2].type, Is.EqualTo(InputRemoting.MessageType.StopSending)); Object.Destroy(connectionToEditor); Object.Destroy(connectionToPlayer); }