Code Monkey home page Code Monkey logo

avalonia.funcui.liveview's People

Contributors

silkyfowl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

stjordanis

avalonia.funcui.liveview's Issues

Support for FSAC updates

The current implementation assumes that only the file being edited is Analyzed.
However, the Analyzer's behavior has changed so that every time one source code is edited, the project's files are analyzed.
This has caused a bug.

FuncUiAnalyzer server is not active

Moved from Avalonia.FuncUI issues.

I tried to use LiveView with my https://github.com/JordanMarr/FSharp.ChordParser project, but I have not yet been able to get it to work.

Steps

  • Since I do not use Paket, I used nuget to install the analyzer to packages/analyzers:
nuget install SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer -Version 0.0.1-alpha2 -OutputDirectory packages/analyzers
  • I installed LiveView to my UI project:
<PackageReference Include="SilkyFowl.Avalonia.FuncUI.LiveView" Version="0.0.1-alpha2" />
  • I debugged using the correct launch profile:

image

  • My Program.fs is setup the same as your readme.

  • I added the [<LivePreview>] to my render function:
    image

Results

But the LivePreview window says "the FuncUiAnalyzer server is not active":

image

My changes here in the LivePreview branch:
https://github.com/JordanMarr/FSharp.ChordParser/tree/LivePreview

Commit:
JordanMarr/FSharp.ChordParser@48254bb

eval button causes an exception,

Exception has occurred: CLR/System.TypeInitializationException
An unhandled exception of type 'System.TypeInitializationException' occurred in Avalonia.FuncUI.LiveView.dll: 'The type initializer for '<StartupCode$Avalonia-FuncUI-LiveView>.$LiveView' threw an exception.'
Inner exceptions found, see $exception in variables window for more details.
Innermost exception System.Exception : Error creating evaluation session: StopProcessingExn
at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1448.Invoke(String message)
at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession..ctor(FsiEvaluationSessionHostConfig fsi, String[] argv, TextReader inReader, TextWriter outWriter, TextWriter errorWriter, Boolean fsiCollectible, FSharpOption1 legacyReferenceResolver) at FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.Create(FsiEvaluationSessionHostConfig fsiConfig, String[] argv, TextReader inReader, TextWriter outWriter, TextWriter errorWriter, FSharpOption1 collectible, FSharpOption`1 legacyReferenceResolver)
at Avalonia.FuncUI.LiveView.FsiSession.create()
at <StartupCode$Avalonia-FuncUI-LiveView>.$LiveView..cctor()

Update to new Avalonia.FuncUI NuGet package

Greetings!

Recently, FuncUI has been officially added to the Avalonia family, which has allowed us to change the NuGet package name from JaggerJo.Avalonia.FuncUI to Avalonia.FuncUI.

Would it be possible to release a new version of LiveView that works with the latest Avalonia.FuncUI package?

Separate LiveViewWindow from SilkyFowl.Avalonia.FuncUI.LiveView.

SilkyFowl.Avalonia.FuncUI.LiveView contains a LiveViewWindow that previews a function with a LivePreviewAttribute. Because of this, a dependency of LiveViewWindow, which is not necessary, is mixed into the project that wants to be previewed.
Since LivePreviewAttribute itself has no dependency, it can be solved by separating LiveViewWindow into a separate library.

seems like a version conflict is giving a bug

Hey, I was trying to get this to work, and it seems like it doesn't like a change that's happened in avalonia funcui version 1


Unhandled exception. System.TypeLoadException: Could not load type 'Avalonia.FuncUI.Builder.ViewBuilder' from assembly 'Avalonia.FuncUI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at Avalonia.FuncUI.LiveView.StateStoreModule.init()
   at Avalonia.FuncUI.LiveView.LiveViewWindow..ctor()

how would you recommend working around this?

Consider future policy.

As soon as the contents are finalized, they will be included in README.md.

Plan

Aim to PR in Avalonia.FuncUI.

context:

Things to do in this repository before creating a PR

bug fix

required

  • Add test code.
  • Package size optimization
    • The analyzer is 50 MB, which is too large. Build scripts need to be improved to incorporate only the necessary libraries.

Write Doc

  • Explanation of the LIVEPREVIEW directive
    • Considering that LivePreview is not needed for debugging purposes, should it be managed separately from the DEBUG directive?
  • Example of use outside VScode
  • In theory, it should also work with vim, etc.

Organize network communication process

If you want to achieve PR, you need to do something about the current situation where IP address and Port are fixed.

  • Consider how to set IP address and Port
    • Environment variable is good?

Performance

  • Identify cases where updates are slow. (Add samples)
    • Perhaps Previewing a View that contains complex logic may be slow.
    • Let's verify with Elmish's sample.

Add features

  • Make it possible to complete only with Fsi.
    • Is it appropriate to add Cli? Should we refer to XAML Studio for that?

vNext

If there is a DU in the file that consists entirely of valued case labels, it cannot be previewed

LivePreview cannot be performed if an fsharp code contains a "DU with values in all Cases" such as the following:

type Bar =
    | Hoge of int
    | Fuga of string

// A single valued DU can also cause problems.
type Foo= Foo of id:int

However, if there is more than one Case with no value, there is no problem.

type Foo = Foo

type Bar =
    | Hoge
    | Fuga of string

type Bar<'t> =
    | Hoge
    | Fuga of string
    | A of {|a:int; b:string; c: bool * string|}
    | B of ('t -> unit)

workaround

Make it a DU that includes one or more cases with no value

/// 参考:https://github.com/fsprojects/Avalonia.FuncUI/blob/master/src/Avalonia.FuncUI.ControlCatalog/Views/Tabs/TextBoxDemo.fs
module Sample.ElmishSample.DefineDUInFile
open Avalonia.Controls
open Avalonia.Layout
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.Elmish
open Avalonia.FuncUI.Builder
open Avalonia.FuncUI.LiveView.Core.Types
type State = { watermark: string }
let init = { watermark = "" }
/// LivePreviewを行いたいコードで判別共用体を定義する際は、値のないケースラベルを1つ以上含めないといけない。
/// 全てのケースラベルに値が設定されているとAnalyzerが失敗する。
type Msg =
| SetWatermark of string
| UnSetWatermark
let update msg state =
match msg with
| SetWatermark test -> { state with watermark = test }
| UnSetWatermark -> { state with watermark = "" }
let view state dispatch =
StackPanel.create [
StackPanel.spacing 10.0
StackPanel.children [
TextBox.create [
TextBox.watermark state.watermark
TextBox.horizontalAlignment HorizontalAlignment.Stretch
]
Button.create [
Button.content "Set Watermark"
Button.background "DarkBlue"
Button.onClick (fun _ -> dispatch (SetWatermark "test"))
Button.horizontalAlignment HorizontalAlignment.Stretch
]
Button.create [
Button.content "Unset Watermark"
Button.onClick (fun _ -> dispatch (UnSetWatermark))
Button.horizontalAlignment HorizontalAlignment.Stretch
]
]
]
type Host() as this =
inherit Hosts.HostControl()
do
Elmish.Program.mkSimple (fun () -> init) update view
|> Program.withHost this
|> Elmish.Program.run
[<LivePreview>]
let preview () = ViewBuilder.Create<Host> []

DU are defined in a separate file

module ElmishModule =
type State = { watermark: string }
let init = { watermark = "" }
type Msg =
| SetWatermark of string
let update msg state =
match msg with
| SetWatermark test -> { state with watermark = test }

module Sample.ElmishSample.DefineDUInAnotherFile
open Avalonia.Controls
open Avalonia.Layout
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.FuncUI.Elmish
open Avalonia.FuncUI.Builder
open Avalonia.FuncUI.LiveView.Core.Types
open Sample.ElmishModule
let view (state:State) dispatch =
StackPanel.create [
StackPanel.spacing 10.0
StackPanel.children [
TextBox.create [
TextBox.watermark state.watermark
TextBox.horizontalAlignment HorizontalAlignment.Stretch
]
Button.create [
Button.background "DarkBlue"
Button.content "Set Watermark"
Button.onClick (fun _ -> SetWatermark "test" |> dispatch)
Button.horizontalAlignment HorizontalAlignment.Stretch
]
Button.create [
Button.content "Unset Watermark"
Button.onClick (fun _ -> SetWatermark "" |> dispatch)
Button.horizontalAlignment HorizontalAlignment.Stretch
]
]
]
type Host() as this =
inherit Hosts.HostControl()
do
Elmish.Program.mkSimple (fun () -> init) update view
|> Program.withHost this
|> Elmish.Program.run
[<LivePreview>]
let preview () = ViewBuilder.Create<Host> []

context:

Avalonia.FuncUI.LiveView uses FSharp.Compiler.Service to perform TypedAST pattern matching to determine if Preview is performed.
However, if a DU with values in all cases is included in some fsharp code, the following error occurs.

FSharp.Compiler.Service cannot yet return this kind of pattern match

Originally posted by @SilkyFowl in #1 (comment)

When DU is not at at the end of the code, FSharpChecker.ParseAndCheckProject failed.

Work

// Some code...

type AnyDuHasNoValueLabelCase =
    | Foo
    | Bar of int

Not Work(Error Message: typecheck error Duplicate definition of type, exception or module 'Counter)

// Some code...
// So far, I can analyze it correctly.

type AnyDuHasNoValueLabelCase =
    | Foo
    | Bar of int

// Other some code...
// Not work

Test Code is here.

let module_with_some_value_after_DU =
let baseCode =
sprintf """
open System
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.Controls
open Avalonia.FuncUI.LiveView.Core.Types
%s
module Counter =
open Avalonia.FuncUI
open Avalonia.Controls
open Avalonia.Media
open Avalonia.FuncUI.DSL
open Avalonia.Layout
let view =
Component.create (
"Counter",
fun ctx ->
let state = ctx.useState 0
Grid.create [
Grid.rowDefinitions "test,Auto"
Grid.children [
TextBlock.create [
TextBlock.text "Foo!!"
]
]
]
)
[<LivePreview>]
let preview () =
view
[<LivePreview>]
let preview2 =
let n = 1
view
"""
anyNoValueCaseDUs
|> List.map ( fun du ->
[| (baseCode >> box) du |]
)
let nestedAnyNoValueCaseDUs =
[
"""
type Foo = Foo
"""
"""
type Bar =
| Hoge
| Fuga of string
"""
"""
type Bar<'t> =
| Hoge
| Fuga of string
| A of {|a:int; b:string; c: bool * string|}
| B of ('t -> unit)
"""
]
let module_after_DU_contain_module =
let baseCode =
sprintf """
open System
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.Controls
open Avalonia.FuncUI.LiveView.Core.Types
module DUs =
%s
module Counter =
open Avalonia.FuncUI
open Avalonia.Controls
open Avalonia.Media
open Avalonia.FuncUI.DSL
open Avalonia.Layout
let view =
Component.create (
"Counter",
fun ctx ->
let state = ctx.useState 0
Grid.create [
Grid.rowDefinitions "test,Auto"
Grid.children [
TextBlock.create [
TextBlock.text "Foo!!"
]
]
]
)
[<LivePreview>]
let preview () =
view
[<LivePreview>]
let preview2 =
let n = 1
view
"""
nestedAnyNoValueCaseDUs
|> List.map ( fun du ->
[| (baseCode >> box) du |]
)
[<Theory>]
[<MemberData(nameof module_with_some_value_after_DU)>]
[<MemberData(nameof module_after_DU_contain_module)>]
let ``wont work If module with some value after DU`` code =
let ex =
Assert.Throws<Sdk.EmptyException>(fun _ ->
createTestCode code
|> Helper.runFuncUIAnalysis
|> ignore
)
ex.Message |> shouldContainText "typecheck error Duplicate definition of type, exception or module 'Counter'"

Originally posted by @SilkyFowl in #1 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.