Skip to content

Commit

Permalink
Enable ViewAdapter to attach to an existing view
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLariviere committed Jan 6, 2023
1 parent 53401a7 commit f18af9f
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/Fabulous.Tests/APISketchTests/TestUI.Widgets.fs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ module TestUI_Widgets =
let oldWidget: Widget voption = ValueNone

Reconciler.update context.CanReuseView oldWidget widget viewNode
struct (viewNode :> IViewNode, box view) }
struct (viewNode :> IViewNode, box view)
AttachView = fun (_widget, _context, _parentNode, _view) -> failwith "not implemented" }

WidgetDefinitionStore.set key definition
key
Expand Down
3 changes: 2 additions & 1 deletion src/Fabulous/Memo.fs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ module Memo =
// store widget that was used to produce this node
// to pass it to reconciler later on
node.MemoizedWidget <- Some memoizedWidget
struct (node, view) }
struct (node, view)
AttachView = fun (_widget, _context, _parentNode, _view) -> failwith "Memo widget cannot be attached" }

WidgetDefinitionStore.set MemoWidgetKey widgetDefinition
21 changes: 21 additions & 0 deletions src/Fabulous/Runners.fs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ type IViewAdapter =
inherit IDisposable
/// Instantiates a new view using the current state associated with this ViewAdapter
abstract CreateView: unit -> obj
/// Attaches to the existing view and updates it with the current state associated with this ViewAdapter
abstract Attach: obj -> unit

module RunnerStore =
let private _runners = Dictionary<StateKey, IRunner>()
Expand Down Expand Up @@ -183,6 +185,24 @@ module ViewAdapters =
_root <- root
_root

member _.Attach(root) =
let state = unbox(StateStore.get stateKey)
let widget = (view state).Compile()
_widget <- widget

let treeContext =
{ CanReuseView = canReuseView
GetViewNode = getViewNode
Logger = logger
Dispatch = this.Dispatch }

let definition = WidgetDefinitionStore.get widget.Key

let _node =
definition.AttachView(widget, treeContext, ValueNone, root)

_root <- root

/// Listens for StateStore changes and updates the view if necessary
member _.OnStateChanged(args) =
try
Expand Down Expand Up @@ -211,6 +231,7 @@ module ViewAdapters =
interface IViewAdapter with
member x.Dispose() = x.Dispose()
member x.CreateView() = x.CreateView()
member x.Attach(root) = x.Attach(root)

/// Create a new ViewAdapter for the component
let create<'arg, 'model, 'msg, 'marker>
Expand Down
3 changes: 2 additions & 1 deletion src/Fabulous/WidgetDefinitions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ type WidgetDefinition =
{ Key: WidgetKey
Name: string
TargetType: Type
CreateView: Widget * ViewTreeContext * IViewNode voption -> struct (IViewNode * obj) }
CreateView: Widget * ViewTreeContext * IViewNode voption -> struct (IViewNode * obj)
AttachView: Widget * ViewTreeContext * IViewNode voption * obj -> IViewNode }

module WidgetDefinitionStore =
let private _widgets = ResizeArray<WidgetDefinition>()
Expand Down

0 comments on commit f18af9f

Please sign in to comment.