-
Notifications
You must be signed in to change notification settings - Fork 10
/
Program.fs
91 lines (77 loc) · 2.75 KB
/
Program.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
module Live.Avalonia.FuncUI.Sample.Program
open System
open System.Text.Json
open System.Text.Json.Serialization
open Avalonia.Themes.Fluent
open Elmish
open Avalonia
open Avalonia.Controls
open Avalonia.Controls.ApplicationLifetimes
open Live.Avalonia
open Avalonia.FuncUI
open Avalonia.FuncUI.Elmish
let transferState<'t> oldState =
let jsonOptions = JsonSerializerOptions()
jsonOptions.Converters.Add(JsonFSharpConverter())
try
let json = JsonSerializer.Serialize(oldState, jsonOptions)
let state = JsonSerializer.Deserialize<'t>(json, jsonOptions)
match box state with
| null -> None
| _ -> Some state
with ex ->
Console.Write $"Error restoring state: {ex}"
None
let isProduction =
#if DEBUG
false
#else
true
#endif
type MainControl(window: Window) as this =
inherit Hosts.HostControl()
do
// Instead of just creating default init state, try to recover state from window.DataContext
let hotInit () =
match transferState<Counter.State> window.DataContext with
| Some newState ->
Console.WriteLine $"Restored state %O{newState}"
newState
| None -> Counter.init
Elmish.Program.mkSimple hotInit Counter.update Counter.view
|> Program.withHost this
// Every time state changes, save state to window.DataContext
|> Program.withTrace (fun model state ->
let setDataContext (subIds: SubId list) =
window.DataContext <- state
() // return unit
setDataContext)
|> Program.run
type App() =
inherit Application()
interface ILiveView with
member _.CreateView(window: Window) =
MainControl(window) :> obj
override this.Initialize() =
this.Styles.Add (FluentTheme())
override this.OnFrameworkInitializationCompleted() =
match this.ApplicationLifetime with
| :? IClassicDesktopStyleApplicationLifetime as desktopLifetime ->
// Disable live reload in production
if isProduction then
let window = Window()
window.Content <- (this :> ILiveView).CreateView(window)
window.Show()
else
let window = new LiveViewHost(this, fun msg -> printfn $"%s{msg}")
window.StartWatchingSourceFilesForHotReloading()
window.Show()
base.OnFrameworkInitializationCompleted()
| _ -> ()
[<EntryPoint>]
let main (args: string array) =
AppBuilder
.Configure<App>()
.UsePlatformDetect()
.UseSkia()
.StartWithClassicDesktopLifetime(args)