Skip to content

Commit

Permalink
Merge pull request #1047 from fabulous-dev/type-safe-events
Browse files Browse the repository at this point in the history
Remove ambiguity when declaring event attributes
  • Loading branch information
TimLariviere committed Aug 7, 2023
2 parents 8073849 + afef778 commit 203440e
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

_No unreleased changes_

## [2.4.0] - 2023-08-07

### Changed
- Remove ambiguity when declaring event attributes by using MsgValue instead of obj by @TimLariviere (https://github.com/fabulous-dev/Fabulous/pull/1047)

## [2.3.2] - 2023-06-01

### Changed
Expand Down
19 changes: 13 additions & 6 deletions src/Fabulous/Attributes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ type SmallScalarExtensions() =
) =
this.WithValue(value, SmallScalars.IntEnum.encode)

type MsgValue = MsgValue of obj

[<Extension>]
type SimpleScalarAttributeDefinitionExtensions() =
[<Extension>]
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)
Expand Down Expand Up @@ -276,11 +283,11 @@ module Attributes =
{ Key = key; Name = name }

/// Define an attribute for EventHandler
let inline defineEventNoArg name ([<InlineIfLambda>] getEvent: obj -> IEvent<EventHandler, EventArgs>) : SimpleScalarAttributeDefinition<obj> =
let inline defineEventNoArg name ([<InlineIfLambda>] getEvent: obj -> IEvent<EventHandler, EventArgs>) : SimpleScalarAttributeDefinition<MsgValue> =
let key =
SimpleScalarAttributeDefinition.CreateAttributeData(
ScalarAttributeComparers.noCompare,
(fun _ newValueOpt node ->
(fun _ (newValueOpt: MsgValue voption) node ->
let event = getEvent node.Target

match node.TryGetHandler(name) with
Expand All @@ -290,7 +297,7 @@ module Attributes =
match newValueOpt with
| ValueNone -> node.SetHandler(name, ValueNone)

| ValueSome msg ->
| ValueSome(MsgValue msg) ->
let handler = EventHandler(fun _ _ -> Dispatcher.dispatch node msg)

event.AddHandler handler
Expand All @@ -305,11 +312,11 @@ module Attributes =
let inline defineEvent<'args>
name
([<InlineIfLambda>] getEvent: obj -> IEvent<EventHandler<'args>, 'args>)
: SimpleScalarAttributeDefinition<'args -> obj> =
: SimpleScalarAttributeDefinition<'args -> MsgValue> =
let key =
SimpleScalarAttributeDefinition.CreateAttributeData(
ScalarAttributeComparers.noCompare,
(fun _ (newValueOpt: ('args -> obj) voption) (node: IViewNode) ->
(fun _ (newValueOpt: ('args -> MsgValue) voption) (node: IViewNode) ->
let event = getEvent node.Target

match node.TryGetHandler(name) with
Expand All @@ -322,7 +329,7 @@ module Attributes =
| ValueSome fn ->
let handler =
EventHandler<'args>(fun _ args ->
let r = fn args
let (MsgValue r) = fn args
Dispatcher.dispatch node r)

node.SetHandler(name, ValueSome handler)
Expand Down

0 comments on commit 203440e

Please sign in to comment.