Skip to content

Commit 203440e

Browse files
authored
Merge pull request #1047 from fabulous-dev/type-safe-events
Remove ambiguity when declaring event attributes
2 parents 8073849 + afef778 commit 203440e

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
_No unreleased changes_
1111

12+
## [2.4.0] - 2023-08-07
13+
14+
### Changed
15+
- Remove ambiguity when declaring event attributes by using MsgValue instead of obj by @TimLariviere (https://github.com/fabulous-dev/Fabulous/pull/1047)
16+
1217
## [2.3.2] - 2023-06-01
1318

1419
### Changed

src/Fabulous/Attributes.fs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ type SmallScalarExtensions() =
8484
) =
8585
this.WithValue(value, SmallScalars.IntEnum.encode)
8686

87+
type MsgValue = MsgValue of obj
88+
89+
[<Extension>]
90+
type SimpleScalarAttributeDefinitionExtensions() =
91+
[<Extension>]
92+
static member inline WithValue(this: SimpleScalarAttributeDefinition<'args -> MsgValue>, value: 'args -> 'msg) =
93+
this.WithValue(value >> box >> MsgValue)
8794

8895
module Attributes =
8996
/// Define an attribute that can fit into 8 bytes encoded as uint64 (such as float or bool)
@@ -276,11 +283,11 @@ module Attributes =
276283
{ Key = key; Name = name }
277284

278285
/// Define an attribute for EventHandler
279-
let inline defineEventNoArg name ([<InlineIfLambda>] getEvent: obj -> IEvent<EventHandler, EventArgs>) : SimpleScalarAttributeDefinition<obj> =
286+
let inline defineEventNoArg name ([<InlineIfLambda>] getEvent: obj -> IEvent<EventHandler, EventArgs>) : SimpleScalarAttributeDefinition<MsgValue> =
280287
let key =
281288
SimpleScalarAttributeDefinition.CreateAttributeData(
282289
ScalarAttributeComparers.noCompare,
283-
(fun _ newValueOpt node ->
290+
(fun _ (newValueOpt: MsgValue voption) node ->
284291
let event = getEvent node.Target
285292

286293
match node.TryGetHandler(name) with
@@ -290,7 +297,7 @@ module Attributes =
290297
match newValueOpt with
291298
| ValueNone -> node.SetHandler(name, ValueNone)
292299

293-
| ValueSome msg ->
300+
| ValueSome(MsgValue msg) ->
294301
let handler = EventHandler(fun _ _ -> Dispatcher.dispatch node msg)
295302

296303
event.AddHandler handler
@@ -305,11 +312,11 @@ module Attributes =
305312
let inline defineEvent<'args>
306313
name
307314
([<InlineIfLambda>] getEvent: obj -> IEvent<EventHandler<'args>, 'args>)
308-
: SimpleScalarAttributeDefinition<'args -> obj> =
315+
: SimpleScalarAttributeDefinition<'args -> MsgValue> =
309316
let key =
310317
SimpleScalarAttributeDefinition.CreateAttributeData(
311318
ScalarAttributeComparers.noCompare,
312-
(fun _ (newValueOpt: ('args -> obj) voption) (node: IViewNode) ->
319+
(fun _ (newValueOpt: ('args -> MsgValue) voption) (node: IViewNode) ->
313320
let event = getEvent node.Target
314321

315322
match node.TryGetHandler(name) with
@@ -322,7 +329,7 @@ module Attributes =
322329
| ValueSome fn ->
323330
let handler =
324331
EventHandler<'args>(fun _ args ->
325-
let r = fn args
332+
let (MsgValue r) = fn args
326333
Dispatcher.dispatch node r)
327334

328335
node.SetHandler(name, ValueSome handler)

0 commit comments

Comments
 (0)