diff --git a/src/dialogs.bjo b/src/dialogs.bjo index 96c632e..c32e409 100644 --- a/src/dialogs.bjo +++ b/src/dialogs.bjo @@ -29,9 +29,6 @@ (import/class (Object (: System.Object)) - (DispatcherOpBase (: Avalonia.Threading.DispatcherOperation)) - (ClrType (: System.Type)) - (PropertyInfo (: System.Reflection.PropertyInfo)) (ClrString (: System.String)) ((ReadOnlyList %a) (: System.Collections.Generic.IReadOnlyList)) ((EventHandler %a) (: System.EventHandler)) @@ -77,20 +74,12 @@ ;; The UI thread, and the window a dialog belongs to. (ui-dispatcher (: Avalonia.Threading.Dispatcher.UIThread #:get)) (ui-post (: Avalonia.Threading.Dispatcher.InvokeAsync (-> Dispatcher (-> Unit) (DispatcherOp Unit)))) - ;; Runs a function on the UI thread. + ;; Runs a function that starts a Task on the UI thread, and waits for the + ;; Task. Avalonia's dialogs take no CancellationToken, so this cannot be + ;; cancelled: a cancelled command stops waiting, and the dialog stays until + ;; it is answered. (on-ui (: Avalonia.Threading.Dispatcher.InvokeAsync - (-> Dispatcher (-> Unit) (DispatcherOp Unit)))) - (op-task (: Avalonia.Threading.DispatcherOperation.GetTask (-> DispatcherOpBase Task))) - ;; Waits for Tasks. Avalonia's dialogs take no CancellationToken, so this - ;; cannot be cancelled: a cancelled command stops at its next sync, and the - ;; dialog stays until it is answered. - (await-tasks (: System.Threading.Tasks.Task.WhenAll (-> (Array Task) void) - #:async #:uncancellable)) - ;; What a finished Task answers. By reflection, because Bjolang reads no - ;; Task's Result: on a Task that is not finished, that would block. - (type-of (: System.Object.GetType (-> Object ClrType))) - (property-of (: System.Type.GetProperty (-> ClrType string PropertyInfo))) - (value-of (: System.Reflection.PropertyInfo.GetValue (-> PropertyInfo Object Object))) + (-> Dispatcher (-> (Task %a)) %a) #:async #:uncancellable)) (answered (: System.Threading.Tasks.Task.FromResult (-> %a (Task %a)))) (current-app (: Avalonia.Application.Current #:get)) (app-lifetime (: Avalonia.Application.ApplicationLifetime (-> Application ILifetime) #:get)) @@ -171,16 +160,10 @@ ;; Task it makes. `none` is the answer when there is no window. (: (-bjo-> (-> Window (Task %a)) %a %a)) (defbjo (run-on-ui start none) - (def/mutable task (: (clr-default) Task)) - (def op (on-ui ui-dispatcher - (fun () - (set! task (cast Task (cast Object (match (owner) - ((Some w) (start w)) - (None (answered none)))))) - unit))) - (await-tasks #[(op-task (cast DispatcherOpBase (cast Object op)))]) - (await-tasks #[task]) - (cast %a (value-of (property-of (type-of (cast Object task)) "Result") (cast Object task)))) + (on-ui ui-dispatcher + (fun () (match (owner) + ((Some w) (start w)) + (None (answered none)))))) ;; The event of what the Task that `start` makes answers, at each sync. ;; `none` is the answer when there is no window, or the Task fails.