From da78773d8d0230475868e42927dc9427e46e27a2 Mon Sep 17 00:00:00 2001 From: Ruemena Date: Wed, 3 Jan 2024 18:03:10 -0600 Subject: [PATCH] FIX #1 --- RueI/RueI/CharacterLengths.cs | 4 +- RueI/RueI/Displays/AutoGiving/AutoGivers.cs | 6 +- RueI/RueI/Displays/AutoGiving/Roles.cs | 2 +- RueI/RueI/Displays/DisplayCore.cs | 8 +- RueI/RueI/Displays/Scheduling/Scheduler.cs | 123 +++++++++++--------- RueI/RueI/Displays/ScreenDisplay.cs | 10 +- RueI/RueI/Elements/Element.cs | 1 - RueI/RueI/Elements/Enums/ElementOptions.cs | 2 +- RueI/RueI/Patches/HintPatch.cs | 3 +- 9 files changed, 85 insertions(+), 74 deletions(-) diff --git a/RueI/RueI/CharacterLengths.cs b/RueI/RueI/CharacterLengths.cs index 70ea3ed..402f817 100644 --- a/RueI/RueI/CharacterLengths.cs +++ b/RueI/RueI/CharacterLengths.cs @@ -4,9 +4,9 @@ using System.Runtime.CompilerServices; /// -/// Provides a variety of constant values. +/// Provides lengths for characters in hints. /// -/// This class is mosty designed for internal use within RueI. However, they can still be useful for external use. +/// This class is mosty designed for internal use within RueI. However, it can still be useful for external use. public static class CharacterLengths { /// diff --git a/RueI/RueI/Displays/AutoGiving/AutoGivers.cs b/RueI/RueI/Displays/AutoGiving/AutoGivers.cs index f9660aa..c4d9b93 100644 --- a/RueI/RueI/Displays/AutoGiving/AutoGivers.cs +++ b/RueI/RueI/Displays/AutoGiving/AutoGivers.cs @@ -7,12 +7,14 @@ using RueI.Elements; /// -/// Manages and automatically assigns elements to s meeting a criteria. +/// Manages and automatically assigns elements to instances meeting a criteria. /// public class AutoElement { private record PeriodicUpdate(TimeSpan time, int priority, JobToken token); + private const int AUTOUPDATEPRIORITY = 5; + private static readonly List AutoGivers = new(); private readonly Element? element; @@ -161,7 +163,7 @@ private static void OnRoleChanged(ReferenceHub hub, PlayerRoleBase prevRole, Pla } } - core.Update(35); + core.Update(AUTOUPDATEPRIORITY); } } diff --git a/RueI/RueI/Displays/AutoGiving/Roles.cs b/RueI/RueI/Displays/AutoGiving/Roles.cs index a09d0c2..4ce4ac1 100644 --- a/RueI/RueI/Displays/AutoGiving/Roles.cs +++ b/RueI/RueI/Displays/AutoGiving/Roles.cs @@ -91,7 +91,7 @@ public enum Roles /// /// Gets the Facility Guard role id. /// - FacilityGuard = 1 << RoleTypeId.Tutorial, + FacilityGuard = 1 << RoleTypeId.FacilityGuard, /// /// Gets the SCP-939 role id. diff --git a/RueI/RueI/Displays/DisplayCore.cs b/RueI/RueI/Displays/DisplayCore.cs index 9ce6273..21a6408 100644 --- a/RueI/RueI/Displays/DisplayCore.cs +++ b/RueI/RueI/Displays/DisplayCore.cs @@ -87,15 +87,15 @@ public static IElemReference GetReference() /// /// Updates this . /// - /// The priority of the update - defaults to 100. - public void Update(int priority = 100) + /// The priority of the update - defaults to 10. + public void Update(int priority = 10) { if (IgnoreUpdate) { return; } - Scheduler.Schedule(TimeSpan.Zero, () => { }, priority); + Scheduler.ScheduleUpdate(TimeSpan.Zero, priority); } /// @@ -113,7 +113,7 @@ public void Update(int priority = 100) } else { - return default; + return null; } } diff --git a/RueI/RueI/Displays/Scheduling/Scheduler.cs b/RueI/RueI/Displays/Scheduling/Scheduler.cs index fdd221f..abb24de 100644 --- a/RueI/RueI/Displays/Scheduling/Scheduler.cs +++ b/RueI/RueI/Displays/Scheduling/Scheduler.cs @@ -5,46 +5,49 @@ using eMEC; using RueI.Displays.Scheduling.Records; using RueI.Extensions; -using UnityEngine; /// /// Provides a means of doing batch operations. /// /// /// The is a powerful class that enables "batch operations". This means that multiple updates to a display can happen at once, helping to avoid the hint ratelimit. +/// More detailed information is available at Using the Scheduler. /// public class Scheduler { private static readonly TimeSpan MinimumBatch = TimeSpan.FromMilliseconds(625); - private readonly Cooldown rateLimiter = new(); + private readonly Cooldown hintRateLimit = new(); private readonly List jobs = new(); private readonly UpdateTask performTask = new(); - - private readonly Queue currentBatches = new(4); private readonly DisplayCore core; + private BatchJob? nextBatch; + /// /// Initializes a new instance of the class. /// - /// The to use. - public Scheduler(DisplayCore coordinator) + /// The to use. + public Scheduler(DisplayCore core) { - this.core = coordinator; + this.core = core; } /// /// Gets a value indicating whether or not the rate limit is currently active. /// - internal bool RateLimitActive => rateLimiter.Active; + internal bool RateLimitActive => hintRateLimit.Active; + /// + /// Gets the used by classes for the current timeSChedued. + /// private static DateTimeOffset Now => DateTimeOffset.UtcNow; /// /// Calculates the weighted time for a list of jobs to be performed. /// - /// The jobs. + /// The operations to schedule. /// The weighted of all of the jobs. public static DateTimeOffset CalculateWeighted(IEnumerable jobs) { @@ -66,7 +69,7 @@ public static DateTimeOffset CalculateWeighted(IEnumerable jobs) } /// - /// Schedules a job. + /// Schedules a . /// /// The job to schedule. public void Schedule(ScheduledJob job) @@ -76,27 +79,43 @@ public void Schedule(ScheduledJob job) } /// - /// Schedules multiple jobs. + /// Schedules multiple operations. /// - /// The first job to schedule. - /// The rest of the jobs to schedule. - public void Schedule(ScheduledJob job, params ScheduledJob[] jobs) + /// The jobs to schedule. + /// + /// When scheduling multiple jobs at a time, this method is preferred to calling several + /// times since it only recalculates the batches once. + /// + public void Schedule(IEnumerable jobs) { - ScheduleNoUpdate(job); - - foreach (ScheduledJob newJob in jobs) + // since we must check every job for duplicates using the JobToken, + // AddRange or similar can't be used + foreach (ScheduledJob job in jobs) { - ScheduleNoUpdate(newJob); + ScheduleNoUpdate(job); } UpdateBatches(); } /// - /// Schedules an uncancellable update job. + /// Schedules multiple operations. + /// + /// The first to schedule. + /// The rest of the operations to schedule. + /// + public void Schedule(ScheduledJob job, params ScheduledJob[] jobs) + { + ScheduleNoUpdate(job); + + Schedule(jobs); // unnecessary to call UpdateBatches, since this already does it + } + + /// + /// Schedules an uncancellable update . /// /// How long into the future to update at. - /// The priority of the job, giving it additional weight when calculating. + /// The priority of the , giving it additional weight when calculating. public void ScheduleUpdate(TimeSpan time, int priority) { jobs.Add(new(Now + time, () => { }, priority)); @@ -104,7 +123,7 @@ public void ScheduleUpdate(TimeSpan time, int priority) } /// - /// Schedules a job. + /// Schedules a new . /// /// How long into the future to run the action at. /// The to run. @@ -116,19 +135,7 @@ public void Schedule(TimeSpan time, Action action, int priority, JobToken? token } /// - /// Schedules a job. - /// - /// The to run. - /// How long into the future to run the action at. - /// The priority of the job, giving it additional weight when calculating. - /// An optional token to assign to the . - public void Schedule(Action action, TimeSpan time, int priority, JobToken? token = null) - { - Schedule(new ScheduledJob(Now + time, action, priority, token)); - } - - /// - /// Schedules a job with a priority of 1. + /// Schedules a with a priority of 1. /// /// How long into the future to run the action at. /// The to run. @@ -139,7 +146,7 @@ public void Schedule(TimeSpan time, Action action, JobToken? token = null) } /// - /// Attempts to kill the job with the . + /// Attempts to kill the with the . /// /// The to use as a reference. public void KillJob(JobToken token) @@ -157,9 +164,12 @@ public void KillJob(JobToken token) /// The amount of time to delay for. internal void Delay(TimeSpan time) { - rateLimiter.Start(time.Max(MinimumBatch)); + hintRateLimit.Start(time.Max(MinimumBatch)); } + /// + /// Recalculates the next for this , and potentially starts it. + /// private void UpdateBatches() { if (!jobs.Any()) @@ -168,7 +178,7 @@ private void UpdateBatches() } jobs.Sort(); - currentBatches.Clear(); + nextBatch = null; List currentBatch = new(2); DateTimeOffset currentBatchTime = jobs.First().FinishAt + MinimumBatch; @@ -181,36 +191,39 @@ private void UpdateBatches() } else { - BatchJob finishedBatch = new(currentBatch, CalculateWeighted(currentBatch)); - currentBatches.Enqueue(finishedBatch); - currentBatch = new() - { - job, - }; + break; } } - if (currentBatch.Count != 0) + if (currentBatch.Count == 0) { - BatchJob finishedBatch = new(currentBatch, CalculateWeighted(currentBatch)); - - currentBatches.Enqueue(finishedBatch); + // handle cases where a scheduledjob being removed + // results in nothing to do + performTask.End(); } + else + { + DateTimeOffset dateTimePerform = CalculateWeighted(currentBatch); + nextBatch = new(currentBatch, dateTimePerform); - TimeSpan performAt = (currentBatches.Peek().PerformAt - Now).MaxIf(rateLimiter.Active, rateLimiter.TimeLeft); + TimeSpan performAt = (dateTimePerform - Now).MaxIf(hintRateLimit.Active, hintRateLimit.TimeLeft); - performTask.Start(performAt, PerformFirstBatch); + performTask.Start(performAt, PerformFirstBatch); + } } /// - /// Immediately performs the first batch job. + /// Immediately performs the first . /// private void PerformFirstBatch() { - BatchJob batchJob = currentBatches.Dequeue(); + if (nextBatch == null) + { + return; + } core.IgnoreUpdate = true; - foreach (ScheduledJob job in batchJob.Jobs) + foreach (ScheduledJob job in nextBatch.Jobs) { jobs.Remove(job); job.Action(); @@ -218,12 +231,16 @@ private void PerformFirstBatch() core.IgnoreUpdate = false; - rateLimiter.Start(Constants.HintRateLimit); + hintRateLimit.Start(Constants.HintRateLimit); core.InternalUpdate(); UpdateBatches(); } + /// + /// Schedules a job without recalculating the batches. + /// + /// The to schedule. private void ScheduleNoUpdate(ScheduledJob job) { if (job.Token == null || !jobs.Any(x => x.Token == job.Token)) diff --git a/RueI/RueI/Displays/ScreenDisplay.cs b/RueI/RueI/Displays/ScreenDisplay.cs index 5c9bccd..cc0c48e 100644 --- a/RueI/RueI/Displays/ScreenDisplay.cs +++ b/RueI/RueI/Displays/ScreenDisplay.cs @@ -70,14 +70,6 @@ public void SetScreen(Screen screen) /// public override IEnumerable GetAllElements() { - foreach (Element element in CurrentScreen.Elements.FilterDisabled()) - { - yield return element; - } - - foreach (Element element in GlobalElements.FilterDisabled()) - { - yield return element; - } + return CurrentScreen.Elements.FilterDisabled().Concat(GlobalElements.FilterDisabled()); } } \ No newline at end of file diff --git a/RueI/RueI/Elements/Element.cs b/RueI/RueI/Elements/Element.cs index 0f367e9..4edf224 100644 --- a/RueI/RueI/Elements/Element.cs +++ b/RueI/RueI/Elements/Element.cs @@ -10,7 +10,6 @@ namespace RueI.Elements; /// /// An is how text is displayed within RueI. Each /// acts like an individual , and cannot influence other s. -/// /// public abstract class Element { diff --git a/RueI/RueI/Elements/Enums/ElementOptions.cs b/RueI/RueI/Elements/Enums/ElementOptions.cs index c21f5c5..5287cb4 100644 --- a/RueI/RueI/Elements/Enums/ElementOptions.cs +++ b/RueI/RueI/Elements/Enums/ElementOptions.cs @@ -24,7 +24,7 @@ public enum ElementOptions /// /// Indicates whether or not to automatically use functional positioning for the element. /// - /// + /// UseFunctionalPosition = 1 << 2, /// diff --git a/RueI/RueI/Patches/HintPatch.cs b/RueI/RueI/Patches/HintPatch.cs index b413c30..c03daa9 100644 --- a/RueI/RueI/Patches/HintPatch.cs +++ b/RueI/RueI/Patches/HintPatch.cs @@ -27,6 +27,7 @@ public static class HintPatch { private const float MAXANONYMOUSHINTTIME = 3; + private const int UPDATEPRIORITY = 10; private delegate bool TryGetHub(GameObject player, out ReferenceHub hub); @@ -100,7 +101,7 @@ public static IEnumerable Transpiler(IEnumerable