Skip to content

Commit

Permalink
Merge branch 'main' into release/2.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Timothé Larivière committed Jan 18, 2024
2 parents 5d9befe + 1df2578 commit 840e174
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 9 deletions.
8 changes: 7 additions & 1 deletion 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.5.0-pre4] - 2024-01-18

### Changed
- Couple of changes and fixes to the new Component API by @TimLariviere (https://github.com/fabulous-dev/Fabulous/pull/1057)

## [2.5.0-pre3] - 2024-01-16

### Changed
Expand Down Expand Up @@ -65,7 +70,8 @@ _No unreleased changes_
### Changed
- Fabulous.XamarinForms & Fabulous.MauiControls have been moved been out of the Fabulous repository. Find them in their own repositories: [https://github.com/fabulous-dev/Fabulous.XamarinForms](https://github.com/fabulous-dev/Fabulous.XamarinForms) / [https://github.com/fabulous-dev/Fabulous.MauiControls](https://github.com/fabulous-dev/Fabulous.MauiControls)

[unreleased]: https://github.com/fabulous-dev/Fabulous/compare/2.5.0-pre3...HEAD
[unreleased]: https://github.com/fabulous-dev/Fabulous/compare/2.5.0-pre4...HEAD
[2.5.0-pre4]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre4
[2.5.0-pre3]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre3
[2.5.0-pre2]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre2
[2.5.0-pre1]: https://github.com/fabulous-dev/Fabulous/releases/tag/2.5.0-pre1
Expand Down
4 changes: 2 additions & 2 deletions src/Fabulous/Component.fs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ module Component =
/// It will be aggressively inlined by the compiler leaving no overhead, only a pure function that returns a WidgetBuilder
type ComponentBodyBuilder<'marker> = delegate of bindings: int<binding> * context: ComponentContext -> struct (int<binding> * WidgetBuilder<unit, 'marker>)

type ComponentBuilder() =
type ComponentBuilder<'parentMsg>() =
member inline this.Yield(widgetBuilder: WidgetBuilder<unit, 'marker>) =
ComponentBodyBuilder<'marker>(fun bindings ctx -> struct (bindings, widgetBuilder))

Expand All @@ -360,4 +360,4 @@ type ComponentBuilder() =

let data = { Body = compiledBody }

WidgetBuilder<unit, 'marker>(Component.WidgetKey, Component.Data.WithValue(data))
WidgetBuilder<'parentMsg, 'marker>(Component.WidgetKey, Component.Data.WithValue(data))
9 changes: 9 additions & 0 deletions src/Fabulous/ComponentContext.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@ we can leverage the inlining capabilities of the ComponentBuilder to create an a
/// Holds the values for the various states of a component.
/// </summary>
type ComponentContext(initialSize: int) =
static let mutable nextId = 0

static let getNextId () =
nextId <- nextId + 1
nextId

let id = getNextId()
let mutable values = Array.zeroCreate initialSize

let renderNeeded = Event<unit>()

// We assume that most components will have few values, so initialize it with a small array
new() = ComponentContext(3)

member this.Id = id

member this.RenderNeeded = renderNeeded.Publish
member this.NeedsRender() = renderNeeded.Trigger()

Expand Down
13 changes: 9 additions & 4 deletions src/Fabulous/MvuComponent.fs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ type MvuComponentBodyBuilder<'msg, 'marker> =
delegate of bindings: int<binding> * context: ComponentContext -> struct (int<binding> * WidgetBuilder<'msg, 'marker>)

[<Struct>]
type MvuComponentBuilder<'arg, 'msg, 'model, 'marker> =
type MvuComponentBuilder<'arg, 'msg, 'model, 'marker, 'parentMsg> =
val public Program: Program<obj, obj, obj>
val public Arg: obj

Expand Down Expand Up @@ -101,7 +101,7 @@ type MvuComponentBuilder<'arg, 'msg, 'model, 'marker> =
Arg = this.Arg
Body = compiledBody }

WidgetBuilder<unit, 'marker>(MvuComponent.WidgetKey, MvuComponent.Data.WithValue(data))
WidgetBuilder<'parentMsg, 'marker>(MvuComponent.WidgetKey, MvuComponent.Data.WithValue(data))

type MvuStateRequest =
struct
Expand All @@ -115,11 +115,16 @@ type MvuContextExtensions =
[<Extension>]
static member inline Bind
(
_: MvuComponentBuilder<'arg, 'msg, 'model, 'marker>,
_: MvuComponentBuilder<'arg, 'msg, 'model, 'marker, 'parentMsg>,
_: MvuStateRequest,
[<InlineIfLambda>] continuation: 'model -> MvuComponentBodyBuilder<'msg, 'marker>
) =
MvuComponentBodyBuilder<'msg, 'marker>(fun bindings ctx ->
let key = int bindings
let value = ctx.TryGetValue<'model>(key).Value

let value =
match ctx.TryGetValue<'model>(key) with
| ValueSome value -> value
| ValueNone -> failwith $"[MvuComponent.Bind] Model not found in ComponentContext {ctx.Id}"

(continuation value).Invoke((bindings + 1<binding>, ctx)))
2 changes: 1 addition & 1 deletion src/Fabulous/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Program<'arg, 'model, 'msg> =

type Program<'arg, 'model, 'msg, 'marker> =
{
Program: Program<'arg, 'model, 'msg>
State: Program<'arg, 'model, 'msg>
/// Render the application state
View: 'model -> WidgetBuilder<'msg, 'marker>
/// Indicates if a previous Widget's view can be reused
Expand Down
2 changes: 1 addition & 1 deletion src/Fabulous/State.fs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ type StateExtensions =
[<Extension>]
static member inline Bind
(
_: ComponentBuilder,
_: ComponentBuilder<'parentMsg>,
[<InlineIfLambda>] fn: StateRequest<'T>,
[<InlineIfLambda>] continuation: StateValue<'T> -> ComponentBodyBuilder<'marker>
) =
Expand Down

0 comments on commit 840e174

Please sign in to comment.