Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
5a06a7b
Receive messages
arthurkehrwald Oct 11, 2024
e2d09e2
Improve perfomance and reliability
arthurkehrwald Oct 12, 2024
59f2d85
Add custom inspector for BcpInterface
arthurkehrwald Oct 12, 2024
bc85f3c
Parse messages
arthurkehrwald Oct 14, 2024
5ada366
Add command dispatcher
arthurkehrwald Oct 15, 2024
faf1ae5
Add ability to send messages
arthurkehrwald Oct 15, 2024
a40c114
Add hello response
arthurkehrwald Oct 15, 2024
c341be2
Move hello message to new file
arthurkehrwald Oct 15, 2024
b90b6f4
Disconnect on goodbye
arthurkehrwald Oct 15, 2024
ba5a62e
Rename from BcpServer to MediaController
arthurkehrwald Oct 16, 2024
b0205c7
Lowercase and trim commands and param names
arthurkehrwald Oct 16, 2024
51b3ea6
Change BcpMessage to string conversion process
arthurkehrwald Oct 16, 2024
c9921a7
Refactor message handling
arthurkehrwald Oct 17, 2024
70ab7af
Make sure message handlers are initialized
arthurkehrwald Oct 17, 2024
e089c6b
Safely remove message handlers
arthurkehrwald Oct 17, 2024
52e26e0
Restructure files
arthurkehrwald Oct 17, 2024
eb8902a
Send error on bcp spec mismatch
arthurkehrwald Oct 18, 2024
8f96868
Fix incorrect receive end reason on cancellation
arthurkehrwald Oct 18, 2024
abe11f0
Ignore messages that start with # or are empty
arthurkehrwald Oct 18, 2024
9e66882
Add wrong parser exception
arthurkehrwald Oct 19, 2024
273661a
Fix receiving messages
arthurkehrwald Oct 19, 2024
ebd8fa6
Refactor message handling again
arthurkehrwald Oct 19, 2024
0eea6bf
Improve parsing exceptions
arthurkehrwald Oct 19, 2024
c54fba7
Fix message encoding
arthurkehrwald Oct 20, 2024
c9443fe
Handle reset
arthurkehrwald Oct 20, 2024
49ec73b
Minor fixes
arthurkehrwald Oct 20, 2024
67ac703
Use enum for monitoring categories
arthurkehrwald Oct 20, 2024
0d85d45
Handle ball start and end messages
arthurkehrwald Oct 20, 2024
1037e91
Add interface prefab
arthurkehrwald Oct 20, 2024
f6dc914
Add reverse mapping to string enum
arthurkehrwald Oct 20, 2024
28cbc6b
Replace some properties with read-only fields
arthurkehrwald Oct 20, 2024
239ff28
Add device message parsing
arthurkehrwald Oct 24, 2024
6da11bc
Add GetParamValue and TryGetParamValue variants
arthurkehrwald Oct 25, 2024
c64473d
Refactor parameter parsing
arthurkehrwald Oct 27, 2024
8044c90
Fix get param value for jtoken types
arthurkehrwald Oct 27, 2024
e01b0d7
Add machine message parsing
arthurkehrwald Oct 27, 2024
c12c0ee
Rename parameter string conversion methods
arthurkehrwald Oct 27, 2024
6ac4127
Only monitor machine vars when necessary
arthurkehrwald Oct 27, 2024
eb5b3a6
Add primitive machine var handling
arthurkehrwald Oct 27, 2024
ff212f3
Fix compile error
arthurkehrwald Oct 27, 2024
d17de87
Add rudimentary settings message parser
arthurkehrwald Oct 27, 2024
ef62a01
Save machine vars
arthurkehrwald Oct 27, 2024
92e1c80
Add mode handling
arthurkehrwald Oct 27, 2024
601e1f8
Add monitoring category to settings message handler
arthurkehrwald Oct 27, 2024
d28379e
Add null check in PrimitiveMachineVarMonitor
arthurkehrwald Oct 27, 2024
2d99745
Add player added message handling
arthurkehrwald Oct 27, 2024
fd32bf3
Add player turn start message handling
arthurkehrwald Oct 27, 2024
74f03e9
Add player variable message handling
arthurkehrwald Oct 27, 2024
2c45d33
Reset monitored variables when requested
arthurkehrwald Oct 29, 2024
e495e40
Rename PlayerVariableMonitorBase to PlayerVariableMonitor
arthurkehrwald Oct 29, 2024
5f0d163
Fix null exception
arthurkehrwald Oct 29, 2024
b77bebf
Fix machine variable type issue
arthurkehrwald Oct 29, 2024
825b965
Add mpf event listener
arthurkehrwald Oct 29, 2024
3e3f9c6
Enqueue messages regardless of connection status
arthurkehrwald Oct 29, 2024
fc52ec0
Remove colon from BcpInterface inspector
arthurkehrwald Oct 29, 2024
efdfdd0
Remove connection state event from BcpInterface
arthurkehrwald Oct 29, 2024
a4a056b
Add switch message handling
arthurkehrwald Oct 29, 2024
01f4413
Rename SharedEventListener to MpfEventRequester
arthurkehrwald Oct 29, 2024
833d688
Add parameters to ball start message
arthurkehrwald Oct 31, 2024
7ee7d7b
Remove duplicate machine var message handler
arthurkehrwald Oct 31, 2024
0664bf9
Expand monitoring functions
arthurkehrwald Nov 13, 2024
2884610
Formatting
arthurkehrwald Jan 29, 2025
df93c62
await Task.WhenAll in server message loop
arthurkehrwald Jan 29, 2025
836e499
Handle MPF early shutdown because of BCP
arthurkehrwald Feb 16, 2025
05d23c0
Add newtonsoft.json to deps
arthurkehrwald Feb 16, 2025
630d528
Replace legacy IMGUI with UiToolkit inspector
arthurkehrwald Feb 16, 2025
a61c36e
Use readonly instead of properties in ConnectionStateEventArgs
arthurkehrwald Feb 16, 2025
7528d64
Reduce default frame time budget for receiving
arthurkehrwald Feb 16, 2025
1e24e15
Say goodbye on shutdown
arthurkehrwald Feb 16, 2025
eaa47a3
Rename disconnect on goodbye behaviour
arthurkehrwald Feb 16, 2025
9a8e961
Run bcp server on main thread
arthurkehrwald Feb 16, 2025
9cdede0
Refactor connection state management in BcpServer
arthurkehrwald Feb 16, 2025
24c6d0c
Prefix all type parameters with T
arthurkehrwald Feb 18, 2025
5f2e950
Format code
arthurkehrwald Feb 18, 2025
4d24f74
Rename _event parameter to @event
arthurkehrwald Feb 18, 2025
d49e7e3
Do not prematurely send stop listening messages
arthurkehrwald Feb 18, 2025
64b4e6d
Do not use null propagation for Unity objects
arthurkehrwald Feb 18, 2025
4607e42
Specify message terminator only once
arthurkehrwald Feb 18, 2025
8251713
Add _ prefix to private and protected fields
arthurkehrwald Feb 18, 2025
17f11dd
Always use pascal case for constants
arthurkehrwald Feb 18, 2025
5f9d08b
Merge media controller code
arthurkehrwald Feb 18, 2025
b8a0049
Future Box -> VPE
arthurkehrwald Feb 18, 2025
1f60ede
Add license preamble to all new code files
arthurkehrwald Feb 18, 2025
1b15a4b
Integrate media controller
arthurkehrwald Feb 22, 2025
3c5d214
Remove unused methods
arthurkehrwald Feb 23, 2025
901b203
Add comments
arthurkehrwald Feb 23, 2025
6a58e3e
Add more comments
arthurkehrwald Feb 23, 2025
ba5fb71
Derive SpecificDeviceMessageHandler from MonitorBase
arthurkehrwald Feb 23, 2025
a8819c0
Fix order of exception args
arthurkehrwald Feb 23, 2025
c84eea9
Prevent null error
arthurkehrwald Feb 24, 2025
b6f813b
Only handle attribute changes for matching device messages
arthurkehrwald Feb 24, 2025
e8eddb6
Rename device message handlers to device monitors
arthurkehrwald Feb 24, 2025
8d2dcd2
Dispose old MpfWrangler when replaced
arthurkehrwald Feb 25, 2025
76b4abd
Remove many MonoBehaviour inheritances
arthurkehrwald Feb 25, 2025
547961c
Rename Ui namespace to Text
arthurkehrwald Feb 25, 2025
3ba2cec
Use TryGet pattern to get BcpInterface from GLE
arthurkehrwald Feb 25, 2025
bbc7d3d
Add sound support
arthurkehrwald Feb 25, 2025
c2b4a21
BinaryEventSoundComponentInspector ->BinaryEventSoundInspector
arthurkehrwald Mar 16, 2025
32f4f6a
Add icons to MPF sound components
arthurkehrwald Mar 16, 2025
6178eec
Merge remote-tracking branch 'upstream/master' into feature/media-con…
arthurkehrwald Mar 29, 2025
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
34 changes: 34 additions & 0 deletions Editor/Inspector/MpfEventSoundInspector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Visual Pinball Engine
// Copyright (C) 2025 freezy and VPE Team
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using VisualPinball.Engine.Mpf.Unity.MediaController.Sound;
using VisualPinball.Unity.Editor;

namespace VisualPinball.Engine.Mpf.Unity.Editor
{
[CustomEditor(typeof(MpfEventSound)), CanEditMultipleObjects]
public class MpfEventSoundInspector : SoundComponentInspector
{
[SerializeField]
private VisualTreeAsset mpfEventSoundInspectorXml;

public override VisualElement CreateInspectorGUI()
{
var root = base.CreateInspectorGUI();
var inspectorUi = mpfEventSoundInspectorXml.Instantiate();
root.Add(inspectorUi);
return root;
}
}
}
15 changes: 15 additions & 0 deletions Editor/Inspector/MpfEventSoundInspector.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Editor/Inspector/MpfEventSoundInspector.uxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xsi="http://www.w3.org/2001/XMLSchema-instance" engine="UnityEngine.UIElements" editor="UnityEditor.UIElements" noNamespaceSchemaLocation="../UIElementsSchema/UIElements.xsd" editor-extension-mode="True">
<uie:PropertyField binding-path="_eventName" label="Event" tooltip="The name of the MPF event that should trigger the sound" />
</ui:UXML>
10 changes: 10 additions & 0 deletions Editor/Inspector/MpfEventSoundInspector.uxml.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 73 additions & 19 deletions Editor/Inspector/MpfGamelogicEngineInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
using System.Linq;
using System.Threading;
using Grpc.Core;
using Mono.Cecil;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
using VisualPinball.Engine.Mpf.Unity.MediaController;
using VisualPinball.Unity;

namespace VisualPinball.Engine.Mpf.Unity.Editor
Expand All @@ -38,6 +38,9 @@ public class MpfGamelogicEngineInspector : UnityEditor.Editor
private PropertyField _connectDelayField;
private VisualElement _commandLineOptionsContainer;
private VisualElement _startupBehaviorOptionsContainer;
private TextField _mpfStateField;
private TextField _mediaControllerStateField;
private VisualElement _bcpOptionsContainer;

public override VisualElement CreateInspectorGUI()
{
Expand All @@ -63,12 +66,9 @@ public override VisualElement CreateInspectorGUI()

if (!string.IsNullOrWhiteSpace(path))
{
path = path.Replace("\\", "/");
if (path.Contains("StreamingAssets/"))
path = "./StreamingAssets/" + path.Split("StreamingAssets/")[1];

path = MpfWranglerOptions.RealPathToSerializedPath(path);
var machineFolderProp = serializedObject.FindProperty(
$"_mpfWrangler._machineFolder"
$"_wranglerOptions._machineFolder"
);
machineFolderProp.stringValue = path;
serializedObject.ApplyModifiedProperties();
Expand All @@ -77,21 +77,21 @@ public override VisualElement CreateInspectorGUI()
);

var getDescBtn = root.Q<Button>("get-machine-description");
var optionsBox = root.Q<GroupBox>("options");
var optionsBox = root.Q<VisualElement>("options");
if (Application.isPlaying)
getDescBtn.SetEnabled(false);

var getDescBtnDefaultText = getDescBtn.text;

getDescBtn.clicked += async () =>
{
Undo.RecordObject(_mpfEngine, "Get machine description");
PrefabUtility.RecordPrefabInstancePropertyModifications(_mpfEngine);
if (_getMachineDescCts == null)
{
_getMachineDescCts = new CancellationTokenSource();
Undo.RecordObject(_mpfEngine, "Get machine description");
PrefabUtility.RecordPrefabInstancePropertyModifications(_mpfEngine);
getDescBtn.text = "Cancel";
optionsBox.SetEnabled(false);
_getMachineDescCts = new CancellationTokenSource();

try
{
Expand All @@ -110,17 +110,15 @@ ex is RpcException exception
{
optionsBox.SetEnabled(true);
getDescBtn.text = getDescBtnDefaultText;
getDescBtn.SetEnabled(true);
_getMachineDescCts?.Dispose();
_getMachineDescCts = null;
}
}
else
{
getDescBtn.SetEnabled(false);
_getMachineDescCts?.Cancel();
_getMachineDescCts?.Dispose();
_getMachineDescCts = null;
optionsBox.SetEnabled(true);
getDescBtn.text = getDescBtnDefaultText;
}
};

Expand All @@ -133,7 +131,8 @@ ex is RpcException exception
if (
EditorUtility.DisplayDialog(
"Mission Pinball Framework",
"This will clear all linked switches, coils and lamps and re-populate them. Are you sure you want to do that?",
"This will clear all linked switches, coils and lamps and re-populate "
+ "them. Are you sure you want to do that?",
"Yes",
"No"
)
Expand Down Expand Up @@ -177,7 +176,7 @@ ex is RpcException exception

var startupBehaviorField = root.Q<PropertyField>("startup-behavior");
var startupBehaviorProp = serializedObject.FindProperty(
"_mpfWrangler._startupBehavior"
"_wranglerOptions._startupBehavior"
);
_connectTimeoutField = root.Q<PropertyField>("connect-timeout");
_connectDelayField = root.Q<PropertyField>("connect-delay");
Expand All @@ -188,7 +187,7 @@ ex is RpcException exception
_commandLineOptionsContainer = root.Q<VisualElement>("command-line-options");
_startupBehaviorOptionsContainer = root.Q<VisualElement>("startup-behavior-options");
var executableSourceProp = serializedObject.FindProperty(
"_mpfWrangler._executableSource"
"_wranglerOptions._executableSource"
);
OnExecutableSourceChanged(executableSourceProp);
_commandLineOptionsContainer.TrackPropertyValue(
Expand All @@ -198,11 +197,31 @@ ex is RpcException exception

MachineFolderValidationBoxes(machineFolderField);

_mpfStateField = root.Q<TextField>("mpf-state");
UpdateMpfStateField(_mpfEngine.MpfState);
_mpfEngine.MpfStateChanged += OnMpfStateChanged;

_mediaControllerStateField = root.Q<TextField>("media-controller-state");
UpdateBcpStateField(_mpfEngine.BcpState);
_mpfEngine.BcpStateChanged += OnBcpStateChanged;

_bcpOptionsContainer = root.Q<VisualElement>("bcp-options");
var mediaControllerProp = serializedObject.FindProperty(
"_wranglerOptions._mediaController"
);
UpdateMediaControllerUiVisibility(mediaControllerProp);
_bcpOptionsContainer.TrackPropertyValue(
mediaControllerProp,
UpdateMediaControllerUiVisibility
);

return root;
}

private void OnDisable()
{
_mpfEngine.MpfStateChanged -= OnMpfStateChanged;
_mpfEngine.BcpStateChanged -= OnBcpStateChanged;
_getMachineDescCts?.Cancel();
_getMachineDescCts?.Dispose();
_getMachineDescCts = null;
Expand Down Expand Up @@ -259,9 +278,42 @@ private void UpdateGameItemList(VisualElement parent, IEnumerable<string> itemId
}
}

private void OnMpfStateChanged(object sender, StateChangedEventArgs<MpfState> args)
{
UpdateMpfStateField(args.CurrentState);
}

private void UpdateMpfStateField(MpfState state)
{
_mpfStateField.value = state.ToString();
}

private void OnBcpStateChanged(
object sender,
StateChangedEventArgs<BcpConnectionState> args
)
{
UpdateBcpStateField(args.CurrentState);
}

private void UpdateBcpStateField(BcpConnectionState state)
{
_mediaControllerStateField.value = state.ToString();
}

private void UpdateMediaControllerUiVisibility(SerializedProperty mediaControllerProp)
{
var mediaController = (MpfMediaController)mediaControllerProp.enumValueIndex;
var usingIncludedMediaController = mediaController == MpfMediaController.Included;
_mediaControllerStateField.SetEnabled(usingIncludedMediaController);
_bcpOptionsContainer.SetEnabled(usingIncludedMediaController);
}

private void MachineFolderValidationBoxes(VisualElement machineFolderField)
{
var machineFolderProp = serializedObject.FindProperty($"_mpfWrangler._machineFolder");
var machineFolderProp = serializedObject.FindProperty(
"_wranglerOptions._machineFolder"
);
var notAMachineFolderErrorBox = new HelpBox(
"The machine folder is not valid. It must contain a folder called 'config' "
+ "with at least one .yaml file inside.",
Expand All @@ -281,7 +333,9 @@ private void MachineFolderValidationBoxes(VisualElement machineFolderField)

void UpdateVisibility(SerializedProperty _)
{
var machineFolder = _mpfEngine.MachineFolder;
var options = (MpfWranglerOptions)
serializedObject.FindProperty("_wranglerOptions").boxedValue;
var machineFolder = options.MachineFolder;
var isMachineFolderInStreamingAssets = machineFolder.StartsWith(
Application.streamingAssetsPath
);
Expand Down
Loading