diff --git a/src/Fabulous/Attributes.Components.fs b/src/Fabulous/Attributes.Components.fs new file mode 100644 index 000000000..ff46d311f --- /dev/null +++ b/src/Fabulous/Attributes.Components.fs @@ -0,0 +1,51 @@ +namespace Fabulous + +open System +open Fabulous +open Fabulous.ScalarAttributeDefinitions + +module ComponentAttributes = + /// Define an attribute for EventHandler + let inline defineEventNoArg name ([] getEvent: obj -> IEvent) : SimpleScalarAttributeDefinition unit> = + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun _ (newValueOpt: (unit -> unit) voption) node -> + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match newValueOpt with + | ValueNone -> node.RemoveHandler(name) + | ValueSome(fn) -> + let event = getEvent node.Target + node.SetHandler(name, event.Subscribe(fun _ -> fn()))) + ) + + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } + + /// Define an attribute for EventHandler<'T> + let inline defineEvent<'args> + name + ([] getEvent: obj -> IEvent, 'args>) + : SimpleScalarAttributeDefinition<'args -> unit> = + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun _ (newValueOpt: ('args -> unit) voption) node -> + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match newValueOpt with + | ValueNone -> node.RemoveHandler(name) + | ValueSome(fn) -> + let event = getEvent node.Target + node.SetHandler(name, event.Subscribe(fun args -> fn args))) + ) + + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } diff --git a/src/Fabulous/Attributes.Mvu.fs b/src/Fabulous/Attributes.Mvu.fs new file mode 100644 index 000000000..972ac0a23 --- /dev/null +++ b/src/Fabulous/Attributes.Mvu.fs @@ -0,0 +1,67 @@ +namespace Fabulous + +open System +open System.Runtime.CompilerServices +open Fabulous +open Fabulous.ScalarAttributeDefinitions + +type MsgValue = MsgValue of obj + +[] +type SimpleScalarAttributeDefinitionExtensions() = + [] + static member inline WithValue(this: SimpleScalarAttributeDefinition<'args -> MsgValue>, value: 'args -> 'msg) = + this.WithValue(value >> box >> MsgValue) + +module MvuAttributes = + + /// Define an attribute for EventHandler + let inline defineEventNoArg name ([] getEvent: obj -> IEvent) : SimpleScalarAttributeDefinition = + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun _ (newValueOpt: MsgValue voption) node -> + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match newValueOpt with + | ValueNone -> node.RemoveHandler(name) + | ValueSome(MsgValue msg) -> + let event = getEvent node.Target + let handler = event.Subscribe(fun _ -> Dispatcher.dispatch node msg) + node.SetHandler(name, handler)) + ) + + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } + + /// Define an attribute for EventHandler<'T> + let inline defineEvent<'args> + name + ([] getEvent: obj -> IEvent, 'args>) + : SimpleScalarAttributeDefinition<'args -> MsgValue> = + let key = + SimpleScalarAttributeDefinition.CreateAttributeData( + ScalarAttributeComparers.noCompare, + (fun _ (newValueOpt: ('args -> MsgValue) voption) (node: IViewNode) -> + match node.TryGetHandler(name) with + | ValueNone -> () + | ValueSome handler -> handler.Dispose() + + match newValueOpt with + | ValueNone -> node.RemoveHandler(name) + | ValueSome fn -> + let event = getEvent node.Target + + let handler = + event.Subscribe(fun args -> + let (MsgValue r) = fn args + Dispatcher.dispatch node r) + + node.SetHandler(name, handler)) + ) + |> AttributeDefinitionStore.registerScalar + + { Key = key; Name = name } diff --git a/src/Fabulous/Attributes.fs b/src/Fabulous/Attributes.fs index a272fe763..5209f03ad 100644 --- a/src/Fabulous/Attributes.fs +++ b/src/Fabulous/Attributes.fs @@ -84,14 +84,6 @@ type SmallScalarExtensions() = ) = this.WithValue(value, SmallScalars.IntEnum.encode) -type MsgValue = MsgValue of obj - -[] -type SimpleScalarAttributeDefinitionExtensions() = - [] - static member inline WithValue(this: SimpleScalarAttributeDefinition<'args -> MsgValue>, value: 'args -> 'msg) = - this.WithValue(value >> box >> MsgValue) - module Attributes = /// Define an attribute that can fit into 8 bytes encoded as uint64 (such as float or bool) let inline defineSmallScalar<'T> @@ -281,100 +273,3 @@ module Attributes = |> AttributeDefinitionStore.registerScalar { Key = key; Name = name } - - /// Define an attribute for EventHandler - let inline defineEventNoArg name ([] getEvent: obj -> IEvent) : SimpleScalarAttributeDefinition = - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun _ (newValueOpt: MsgValue voption) node -> - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match newValueOpt with - | ValueNone -> node.RemoveHandler(name) - | ValueSome(MsgValue msg) -> - let event = getEvent node.Target - let handler = event.Subscribe(fun _ -> Dispatcher.dispatch node msg) - node.SetHandler(name, handler)) - ) - - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } - - /// Define an attribute for EventHandler<'T> - let inline defineEvent<'args> - name - ([] getEvent: obj -> IEvent, 'args>) - : SimpleScalarAttributeDefinition<'args -> MsgValue> = - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun _ (newValueOpt: ('args -> MsgValue) voption) (node: IViewNode) -> - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match newValueOpt with - | ValueNone -> node.RemoveHandler(name) - | ValueSome fn -> - let event = getEvent node.Target - - let handler = - event.Subscribe(fun args -> - let (MsgValue r) = fn args - Dispatcher.dispatch node r) - - node.SetHandler(name, handler)) - ) - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } - - let inline defineEventNoArgNoDispatch - name - ([] getEvent: obj -> IEvent) - : SimpleScalarAttributeDefinition unit> = - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun _ (newValueOpt: (unit -> unit) voption) node -> - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match newValueOpt with - | ValueNone -> node.RemoveHandler(name) - | ValueSome(fn) -> - let event = getEvent node.Target - node.SetHandler(name, event.Subscribe(fun _ -> fn()))) - ) - - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } - - let inline defineEventNoDispatch<'args> - name - ([] getEvent: obj -> IEvent, 'args>) - : SimpleScalarAttributeDefinition<'args -> unit> = - let key = - SimpleScalarAttributeDefinition.CreateAttributeData( - ScalarAttributeComparers.noCompare, - (fun _ (newValueOpt: ('args -> unit) voption) node -> - match node.TryGetHandler(name) with - | ValueNone -> () - | ValueSome handler -> handler.Dispose() - - match newValueOpt with - | ValueNone -> node.RemoveHandler(name) - | ValueSome(fn) -> - let event = getEvent node.Target - node.SetHandler(name, event.Subscribe(fun args -> fn args))) - ) - - |> AttributeDefinitionStore.registerScalar - - { Key = key; Name = name } diff --git a/src/Fabulous/Fabulous.fsproj b/src/Fabulous/Fabulous.fsproj index 313be82b4..532197f33 100644 --- a/src/Fabulous/Fabulous.fsproj +++ b/src/Fabulous/Fabulous.fsproj @@ -40,6 +40,8 @@ + +