diff --git a/RLBotCS/ManagerTools/ConfigParser.cs b/RLBotCS/ManagerTools/ConfigParser.cs index 82712fc..3bfcdc6 100644 --- a/RLBotCS/ManagerTools/ConfigParser.cs +++ b/RLBotCS/ManagerTools/ConfigParser.cs @@ -27,6 +27,7 @@ public static class Fields public const string MatchStateSetting = "enable_state_setting"; public const string MatchAutoSaveReplays = "auto_save_replays"; public const string MatchFreePlay = "freeplay"; + public const string MatchPerformanceMonitor = "performance_monitor"; public const string MutatorsTable = "mutators"; public const string MutatorsMatchLength = "match_length"; @@ -749,6 +750,11 @@ public MatchConfigurationT LoadMatchConfig(string path) Fields.RlBotWaitForAgents, true ); + matchConfig.PerformanceMonitor = GetEnum( + rlbotTable, + Fields.MatchPerformanceMonitor, + PerformanceMonitor.ShowWhenSuboptimal + ); } TomlTableArray players = GetValue(outerTable, Fields.CarsList, []); diff --git a/RLBotCS/ManagerTools/MatchStarter.cs b/RLBotCS/ManagerTools/MatchStarter.cs index dd01036..3c92999 100644 --- a/RLBotCS/ManagerTools/MatchStarter.cs +++ b/RLBotCS/ManagerTools/MatchStarter.cs @@ -349,7 +349,7 @@ private void LoadMatch(MatchConfigurationT matchConfig, PlayerSpawner spawner) private bool IsDifferentFromLast(MatchConfigurationT matchConfig) { - // Don't consider rendering/state setting because that can be enabled/disabled without restarting the match + // Don't consider rendering/state setting/perf monitor because they can be toggled without restarting the match var lastMatchConfig = _matchConfig; if (lastMatchConfig == null) diff --git a/RLBotCS/ManagerTools/PerfMonitor.cs b/RLBotCS/ManagerTools/PerfMonitor.cs index 76ed230..780658f 100644 --- a/RLBotCS/ManagerTools/PerfMonitor.cs +++ b/RLBotCS/ManagerTools/PerfMonitor.cs @@ -11,14 +11,14 @@ public class PerfMonitor private const int _maxSamples = 120; private const float _timeSkip = 0.5f; - private static readonly ColorT TextColor = new ColorT() + private static readonly ColorT TextColor = new() { A = 255, R = 255, G = 255, B = 255, }; - private static readonly ColorT BackColor = new ColorT() + private static readonly ColorT BackColor = new() { A = 100, R = 0, @@ -27,7 +27,8 @@ public class PerfMonitor }; private readonly CircularBuffer _rlbotSamples = new(_maxSamples); - private readonly SortedDictionary> _samples = new(); + private readonly SortedDictionary> _samples = []; + private PerformanceMonitor _displayMode = PerformanceMonitor.ShowWhenSuboptimal; private float time = 0; public void AddRLBotSample(Deltas deltas) @@ -37,12 +38,10 @@ public void AddRLBotSample(Deltas deltas) public void AddSample(string name, bool gotInput) { - if (!_samples.ContainsKey(name)) - { + if (_samples.TryGetValue(name, out var buffer)) + buffer.AddLast(gotInput); + else _samples[name] = new(_maxSamples); - } - - _samples[name].AddLast(gotInput); } public void RemoveBot(string name) @@ -50,6 +49,8 @@ public void RemoveBot(string name) _samples.Remove(name); } + public void SetDisplayMode(PerformanceMonitor mode) => _displayMode = mode; + public static float GetPercentile(IEnumerable data, float p) { var sorted = data.OrderBy(x => x).ToList(); @@ -66,6 +67,12 @@ public static float GetPercentile(IEnumerable data, float p) public void RenderSummary(Rendering rendering, GameState gameState, float deltaTime) { + if (_displayMode == PerformanceMonitor.NeverShow) + { + rendering.RemoveRenderGroup(ClientId, RenderGroupId); + return; + } + time += deltaTime; if (time < _timeSkip) return; @@ -99,7 +106,7 @@ public void RenderSummary(Rendering rendering, GameState gameState, float deltaT 0.99f ) * 1000f:0.0}ms """; - bool shouldRender = misses120 > 0; + bool shouldRender = _displayMode == PerformanceMonitor.AlwaysShow || misses120 > 0; foreach (var (name, samples) in _samples) { @@ -124,10 +131,10 @@ public void RenderSummary(Rendering rendering, GameState gameState, float deltaT VAlign = TextVAlign.Top, }; - var renderMessages = new List() - { - new RenderMessageT() { Variety = RenderTypeUnion.FromString2D(renderText) }, - }; + List renderMessages = + [ + new() { Variety = RenderTypeUnion.FromString2D(renderText) }, + ]; if (shouldRender) rendering.AddRenderGroup(ClientId, RenderGroupId, renderMessages, gameState); diff --git a/RLBotCS/Server/BridgeMessage/StartMatch.cs b/RLBotCS/Server/BridgeMessage/StartMatch.cs index 755b58d..1e63cc1 100644 --- a/RLBotCS/Server/BridgeMessage/StartMatch.cs +++ b/RLBotCS/Server/BridgeMessage/StartMatch.cs @@ -16,6 +16,7 @@ public void HandleMessage(BridgeContext context) context.AgentMapping.SetAgents(MatchConfig); context.MatchStarter.StartMatch(MatchConfig, context.GetPlayerSpawner()); // May modify the match config context.UpdateTimeMutators(); + context.PerfMonitor.SetDisplayMode(MatchConfig.PerformanceMonitor); // Handle messages that required a match config foreach (var infoRequest in context.WaitingAgentRequests) diff --git a/RLBotCS/Server/BridgeMessage/UpdatePerformanceMonitor.cs b/RLBotCS/Server/BridgeMessage/UpdatePerformanceMonitor.cs new file mode 100644 index 0000000..d43e673 --- /dev/null +++ b/RLBotCS/Server/BridgeMessage/UpdatePerformanceMonitor.cs @@ -0,0 +1,11 @@ +using RLBot.Flat; + +namespace RLBotCS.Server.BridgeMessage; + +readonly struct UpdatePerformanceMonitor(PerformanceMonitor Mode) : IBridgeMessage +{ + public void HandleMessage(BridgeContext context) + { + context.PerfMonitor.SetDisplayMode(Mode); + } +} diff --git a/RLBotCS/Server/FlatBuffersSession.cs b/RLBotCS/Server/FlatBuffersSession.cs index cd49832..747f01e 100644 --- a/RLBotCS/Server/FlatBuffersSession.cs +++ b/RLBotCS/Server/FlatBuffersSession.cs @@ -315,6 +315,14 @@ await _bridge.WriteAsync( await _rlbotServer.WriteAsync(new UpdateRendering(renderingStatus)); break; + case InterfaceMessage.UpdatePerformanceMonitor: + var updatePerformanceMonitor = msg.MessageAsUpdatePerformanceMonitor() + .UnPack(); + await _rlbotServer.WriteAsync( + new ServerMessage.UpdatePerformanceMonitor(updatePerformanceMonitor.Show) + ); + break; + case InterfaceMessage.PingRequest: _incomingMessages.Writer.TryWrite( new SessionMessage.PingResponse(msg.MessageAsPingRequest().UnPack().Cookie) diff --git a/RLBotCS/Server/ServerMessage/UpdatePerformanceMonitor.cs b/RLBotCS/Server/ServerMessage/UpdatePerformanceMonitor.cs new file mode 100644 index 0000000..c2b02fc --- /dev/null +++ b/RLBotCS/Server/ServerMessage/UpdatePerformanceMonitor.cs @@ -0,0 +1,16 @@ +using RLBot.Flat; + +namespace RLBotCS.Server.ServerMessage; + +readonly struct UpdatePerformanceMonitor(PerformanceMonitor Mode) : IServerMessage +{ + public ServerAction Execute(ServerContext context) + { + if (context.MatchConfig is { } matchConfig) + matchConfig.PerformanceMonitor = Mode; + + context.Bridge.TryWrite(new BridgeMessage.UpdatePerformanceMonitor(Mode)); + + return ServerAction.Continue; + } +} diff --git a/RLBotCS/Server/ServerMessage/UpdateRendering.cs b/RLBotCS/Server/ServerMessage/UpdateRendering.cs index 02f5ded..43577ab 100644 --- a/RLBotCS/Server/ServerMessage/UpdateRendering.cs +++ b/RLBotCS/Server/ServerMessage/UpdateRendering.cs @@ -14,7 +14,7 @@ public ServerAction Execute(ServerContext context) // Distribute to all sessions; // they will figure out on their own if rendering should be enable/disabled - foreach (var (id, (writer, _)) in context.Sessions) + foreach (var (_, (writer, _)) in context.Sessions) { writer.TryWrite(message); } diff --git a/flatbuffers-schema b/flatbuffers-schema index e6f1341..a77d8d7 160000 --- a/flatbuffers-schema +++ b/flatbuffers-schema @@ -1 +1 @@ -Subproject commit e6f134151dc84a7e1780b515bdac57ec1dd098de +Subproject commit a77d8d7dbf5d7570f45ff34ebaeca6ed940b0927