From a3b4b412752505124460a5f2f096dc37626da16c Mon Sep 17 00:00:00 2001 From: Josua Jaeger Date: Sat, 4 Nov 2023 16:01:03 +0100 Subject: [PATCH] Add `State.map` which returns an `IWritable`. --- .../Components/State/State.Adapters.fs | 27 +++++++++++++------ .../Components/State/State.Functions.fs | 3 +++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.FuncUI/Components/State/State.Adapters.fs b/src/Avalonia.FuncUI/Components/State/State.Adapters.fs index 70e0bf1f..505b8080 100644 --- a/src/Avalonia.FuncUI/Components/State/State.Adapters.fs +++ b/src/Avalonia.FuncUI/Components/State/State.Adapters.fs @@ -75,16 +75,27 @@ type internal ReadValueMapped<'a, 'b> member this.Dispose () = () -type internal ValueMapped<'a, 'b> - ( src: IWritable<'a>, - mapFunc: 'a -> 'b, - mapBackFunc: 'b -> 'a ) = - - inherit ReadValueMapped<'a, 'b>(src, mapFunc) +type internal ValueMapped<'a, 'b>(src: IWritable<'a>, read: 'a -> 'b, write: 'a * 'b -> 'a) = + let mutable current: 'b = read src.Current interface IWritable<'b> with - member this.Set (value: 'b) : unit = - src.Set (mapBackFunc value) + member this.InstanceId with get () = src.InstanceId + member this.InstanceType with get () = InstanceType.Create src + member this.ValueType with get () = typeof<'b> + member this.Current with get () = current + member this.Subscribe (handler: 'b -> unit) = + src.Subscribe (fun value -> + current <- read value + handler current + ) + member this.SubscribeAny (handler: obj -> unit) = + (this :> IReadable<'b>).Subscribe handler + + member this.Set (value: 'b) = + src.Set(write(src.Current, value)) + + member this.Dispose () = + () type internal ReadValueMap<'value, 'key when 'key : comparison> ( src: IReadable<'value list>, diff --git a/src/Avalonia.FuncUI/Components/State/State.Functions.fs b/src/Avalonia.FuncUI/Components/State/State.Functions.fs index 20287488..ea3324ff 100644 --- a/src/Avalonia.FuncUI/Components/State/State.Functions.fs +++ b/src/Avalonia.FuncUI/Components/State/State.Functions.fs @@ -44,6 +44,9 @@ module State = let readMap (mapFunc: 'a -> 'b) (value: IReadable<'a>) : IReadable<'b> = new ReadValueMapped<'a, 'b>(value, mapFunc) :> _ + let map (read: 'a -> 'b) (write: 'a * 'b -> 'a) (state: IWritable<'a>) : IWritable<'b> = + new ValueMapped<'a, 'b>(state, read, write) + let readTryFindByKey (keyPath: 'value -> 'key) (key: IReadable<'key>) (wire: IReadable>) : IReadable<'value option> = let keyedWire: IReadable> = new ReadValueMap<'value, 'key>(wire, keyPath) :> _ let keyFocusedWire: IReadable<'value option> = new ReadKeyFocusedValue<'value, 'key>(keyedWire, key) :> _