From 8cf6f767973825bfafb761276c2c74a74448bf32 Mon Sep 17 00:00:00 2001 From: Friedrich von Never Date: Sun, 28 May 2023 13:51:10 +0200 Subject: [PATCH] (#13) More code review fixes --- O21.Game/Loading/LoadingLoop.fs | 22 ++++++++++++++++++---- O21.Game/Loading/LoadingSceneBase.fs | 3 +-- O21.Game/Program.fs | 5 ++--- O21.Game/U95/U95Data.fs | 4 ++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/O21.Game/Loading/LoadingLoop.fs b/O21.Game/Loading/LoadingLoop.fs index ffedbdf..c7679f3 100644 --- a/O21.Game/Loading/LoadingLoop.fs +++ b/O21.Game/Loading/LoadingLoop.fs @@ -12,9 +12,23 @@ open O21.Game.U95 type private CustomSynchronizationContext(queue: ConcurrentQueue unit>) = inherit SynchronizationContext() - override this.CreateCopy() = CustomSynchronizationContext(queue) - override this.Post(callback, state) = queue.Enqueue(fun () -> callback.Invoke state) - override this.Send(_, _) = failwith "Cannot use synchronous send on custom context." + let mutable locker = obj() + let mutable isDisposed = false + + override this.CreateCopy() = this + override this.Post(callback, state) = + lock locker (fun () -> + if isDisposed then failwith $"{this} has been disposed and cannot accept any more tasks." + queue.Enqueue(fun () -> callback.Invoke state) + ) + override this.Send(_, _) = failwith "It's forbidden to use synchronous send on custom context." + + interface IDisposable with + member this.Dispose() = + lock locker (fun () -> isDisposed <- true) + let count = queue.Count + if count > 0 then + failwith $"{this}'s queue contains {count} tasks after dispose. These tasks will never be processed." type private Result<'a> = | Success of 'a @@ -35,7 +49,7 @@ with let private processWithPumping(scene: ILoadingScene<_, _>, input) = let queue = ConcurrentQueue() - let context = CustomSynchronizationContext(queue) + use context = new CustomSynchronizationContext(queue) let prevContext = SynchronizationContext.Current try SynchronizationContext.SetSynchronizationContext context diff --git a/O21.Game/Loading/LoadingSceneBase.fs b/O21.Game/Loading/LoadingSceneBase.fs index 6d4aeb6..8a06b5f 100644 --- a/O21.Game/Loading/LoadingSceneBase.fs +++ b/O21.Game/Loading/LoadingSceneBase.fs @@ -28,8 +28,7 @@ type LoadingSceneBase<'Output>(config: Config) = let font = content.UiFontRegular let fontSize = 24f - let mutable progressString = (loadingProgress * 100.0).ToString("##", CultureInfo.InvariantCulture) - if progressString = "" then progressString <- "00" + let progressString = (loadingProgress * 100.0).ToString("00", CultureInfo.InvariantCulture) let text = $"{loadingStatus} {progressString}%%" let textRect = MeasureTextEx(font, text, fontSize, 0f) diff --git a/O21.Game/Program.fs b/O21.Game/Program.fs index 4a4f0c5..07bbef0 100644 --- a/O21.Game/Program.fs +++ b/O21.Game/Program.fs @@ -83,9 +83,8 @@ let main(args: string[]): int = } RaylibEnvironment.Run(config, fun () -> - match LoadingLoop.Run config with - | Some(content, data) -> GameLoop.Run(content, data) - | None -> () + LoadingLoop.Run config + |> Option.iter GameLoop.Run ) | _ -> printfn "Usage:\nexport : export resources\n: start the game" diff --git a/O21.Game/U95/U95Data.fs b/O21.Game/U95/U95Data.fs index 5eb144c..a52fec2 100644 --- a/O21.Game/U95/U95Data.fs +++ b/O21.Game/U95/U95Data.fs @@ -47,10 +47,10 @@ type U95Data private (sprites: Sprites, sounds: Map, help: Lan MarkdownHelp.Load hlpFilePath markdownFilePath loadController.ReportProgress(translation.LoadingData, 0.6) - let! sounds = Async.AwaitTask <| Sound.Load directory + let! sounds = Sound.Load directory loadController.ReportProgress(translation.LoadingData, 0.8) - let! level = Async.AwaitTask <| Level.Load directory 1 2 + let! level = Level.Load directory 1 2 loadController.ReportProgress(translation.CatchingUp, 1.0) return new U95Data(sprites, sounds, help, [| level |])