Skip to content

Commit

Permalink
Added functions for exporting and importing model field values from D…
Browse files Browse the repository at this point in the history
…ict (#306)

* added functions for exporting and importing model field values from Dict

* remove reactive warning
  • Loading branch information
PGimenez authored Dec 11, 2024
1 parent 4d2bb15 commit 8d24049
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 4 deletions.
66 changes: 65 additions & 1 deletion src/ModelStorage.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,68 @@
module ModelStorage
using JSON3
using Stipple
import Stipple: INTERNALFIELDS, AUTOFIELDS, Reactive

const DEFAULT_EXCLUDE = vcat(INTERNALFIELDS, AUTOFIELDS)

"""
model_values(model::M; fields::Vector{Symbol} = Symbol[], exclude::Vector{Symbol} = Symbol[], json::Bool = false) where M
Exports the values of reactive fields from a Stipple model. Returns either a Dict of field-value pairs or a JSON string
if json=true.
### Example
@app TestApp2 begin
@in i = 100
@out s = "Hello"
@private x = 4
end
model = @init TestApp2
exported_values = Stipple.ModelStorage.model_values(model)
"""
function model_values(model::M; fields::Vector{Symbol} = Symbol[], exclude::Vector{Symbol} = Symbol[], json::Bool = false) where M
field_list = isempty(fields) ? fieldnames(M) : fields
excluded_fields = vcat(DEFAULT_EXCLUDE, exclude)

field_dict = Dict(field => getfield(model, field)[] for field in field_list
if field excluded_fields && getfield(model, field) isa Stipple.Reactive)

json ? JSON3.write(field_dict) : field_dict
end

"""
load_model_values!(model::M, values::Dict{Symbol, Any}) where M
load_model_values!(model::M, values::String) where M
Loads values into the fields of a ReactiveModel. Accepts either a Dict of field-value pairs or a JSON string.
### Example
values_dict = Dict(:i => 20, :s => "world", :x => 5)
Stipple.ModelStorage.load_model_values!(model, values_dict)
"""
function load_model_values!(model::M, values::Dict{Symbol, Any}) where M
model_field_list = fieldnames(M)
excluded_fields = DEFAULT_EXCLUDE

for (field, value) in values
if field excluded_fields && field model_field_list
model_field = getfield(model, field)

if model_field isa Reactive
model_field[] = value
end
end
end

return model
end

function load_model_values!(model::M, values::String) where M
load_model_values!(model, Dict(JSON3.read(values)))
end

module Sessions

Expand Down Expand Up @@ -61,4 +125,4 @@ end

end # module Sessions

end # module ModelStorage
end # module ModelStorage
3 changes: 1 addition & 2 deletions src/Stipple.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,9 @@ export setchannel, getchannel
isempty(methods(notify, Observables)) && (Base.notify(observable::AbstractObservable) = Observables.notify!(observable))

include("ParsingTools.jl")
use_model_storage() && include("ModelStorage.jl")
include("NamedTuples.jl")

include("stipple/reactivity.jl")
use_model_storage() && include("ModelStorage.jl")
include("stipple/json.jl")
include("stipple/undefined.jl")
include("stipple/assets.jl")
Expand Down
34 changes: 33 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -559,4 +559,36 @@ end
@test Stipple.Layout.THEMES[][end] == my_css
remove_css(my_css, byname = true)
@test findfirst(==(my_css), Stipple.Layout.THEMES[]) === nothing
end
end

@testset "Exporting and loading model field values" begin
@app TestApp2 begin
@in i = 100
@out s = "Hello"
@private x = 4
end

model = @init TestApp2

exported_values = Stipple.ModelStorage.model_values(model)
@test exported_values[:i] == 100
@test exported_values[:s] == "Hello"
@test exported_values[:x] == 4

values_json = JSON3.write(exported_values)
exported_values_json = Stipple.ModelStorage.model_values(model, json = true)
@test values_json == exported_values_json

values_dict = Dict(:i => 20, :s => "world", :x => 5)
Stipple.ModelStorage.load_model_values!(model, values_dict)
@test model.i[] == 20
@test model.s[] == "world"
@test model.x[] == 5

values_json = Dict(:i => 30, :s => "zero", :x => 50) |> JSON3.write |> string
Stipple.ModelStorage.load_model_values!(model, values_json)
@test model.i[] == 30
@test model.s[] == "zero"
@test model.x[] == 50

end

0 comments on commit 8d24049

Please sign in to comment.