diff --git a/CHANGELOG.md b/CHANGELOG.md index 2333354fc..097518365 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 _No unreleased changes_ +## [2.5.0-pre9] - 2024-02-12 + +### Fixed +- Improve handling of messages after Runner gets disposed + ## [2.5.0-pre8] - 2024-01-30 ### Changed @@ -95,7 +100,8 @@ _No unreleased changes_ ### Changed - Fabulous.XamarinForms & Fabulous.MauiControls have been moved been out of the Fabulous repository. Find them in their own repositories: [https://github.com/fabulous-dev/Fabulous.XamarinForms](https://github.com/fabulous-dev/Fabulous.XamarinForms) / [https://github.com/fabulous-dev/Fabulous.MauiControls](https://github.com/fabulous-dev/Fabulous.MauiControls) -[unreleased]: https://github.com/fabulous-dev/Fabulous/compare/2.5.0-pre8...HEAD +[unreleased]: https://github.com/fabulous-dev/Fabulous/compare/2.5.0-pre9...HEAD +[2.5.0-pre9]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre9 [2.5.0-pre8]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre8 [2.5.0-pre7]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre7 [2.5.0-pre6]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre6 diff --git a/src/Fabulous/MvuComponent.fs b/src/Fabulous/MvuComponent.fs index 379e89e5f..a93978a72 100644 --- a/src/Fabulous/MvuComponent.fs +++ b/src/Fabulous/MvuComponent.fs @@ -28,8 +28,14 @@ module MvuComponent = let ctx = new ComponentContext(1) - let runner = - new Runner((fun () -> ctx.TryGetValue(0).Value), (fun v -> ctx.SetValue(0, v)), data.Program) + let getModel () = + match ctx.TryGetValue(0) with + | ValueNone -> failwith("Model not found in ComponentContext " + ctx.Id.ToString()) + | ValueSome model -> model + + let setModel v = ctx.SetValue(0, v) + + let runner = new Runner(getModel, setModel, data.Program) ctx.LinkDisposable(runner) diff --git a/src/Fabulous/Runner.fs b/src/Fabulous/Runner.fs index 910f230a8..ba24bd339 100644 --- a/src/Fabulous/Runner.fs +++ b/src/Fabulous/Runner.fs @@ -10,6 +10,7 @@ open System.Collections.Concurrent type Runner<'arg, 'model, 'msg>(getState: unit -> 'model, setState: 'model -> unit, program: Program<'arg, 'model, 'msg>) = let mutable _activeSubs = Sub.Internal.empty let mutable _reentering = false + let mutable _stopped = false let queue = ConcurrentQueue<'msg>() let onError (message, exn) = @@ -21,7 +22,7 @@ type Runner<'arg, 'model, 'msg>(getState: unit -> 'model, setState: 'model -> un let processMsgs dispatch msg = let mutable lastMsg = ValueSome msg - while lastMsg.IsSome do + while not _stopped && lastMsg.IsSome do let model = getState() let newModel, cmd = program.Update(lastMsg.Value, model) let subs = program.Subscribe(newModel) @@ -39,7 +40,9 @@ type Runner<'arg, 'model, 'msg>(getState: unit -> 'model, setState: 'model -> un let rec dispatch msg = try - if _reentering then + if _stopped then + () // Message arrived after Runner got disposed, simply discard it + else if _reentering then queue.Enqueue(msg) else _reentering <- true @@ -74,7 +77,8 @@ type Runner<'arg, 'model, 'msg>(getState: unit -> 'model, setState: 'model -> un let stop () = try - _reentering <- true + _stopped <- true + queue.Clear() Sub.Internal.Fx.stop onError _activeSubs _activeSubs <- Sub.Internal.empty with ex ->