Skip to content

Commit f076b4e

Browse files
committed
add electron mode
1 parent 2a301aa commit f076b4e

File tree

4 files changed

+125
-24
lines changed

4 files changed

+125
-24
lines changed

NetworkDynamicsInspector/Project.toml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,38 @@ OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
1515
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
1616
WGLMakie = "276b4fcb-3e11-5398-bf8b-a0c2d153d008"
1717

18+
[weakdeps]
19+
Electron = "a1bb12fb-d4d1-54b4-b10a-ee7951ef7ad3"
20+
1821
[sources]
1922
NetworkDynamics = {path = ".."}
2023

24+
[extensions]
25+
ElectronExt = ["Electron"]
26+
2127
[compat]
2228
Aqua = "0.8.9"
2329
Bonito = "4.0.0"
2430
ColorSchemes = "3.29.0"
2531
Colors = "0.13.0"
32+
Electron = "6"
2633
ExplicitImports = "1.10.1"
2734
GraphMakie = "0.5.14"
2835
Graphs = "1.12.0"
2936
NetworkDynamics = "0.9.13"
3037
Observables = "0.5.5"
3138
OrderedCollections = "1.8.0"
3239
SciMLBase = "2.75.1"
33-
WGLMakie = "0.11"
3440
Test = "1"
41+
WGLMakie = "0.11"
3542
julia = "1.10"
3643

3744
[extras]
3845
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3946
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
47+
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
48+
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
4049
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4150

4251
[targets]
43-
test = ["Aqua", "ExplicitImports", "Test"]
52+
test = ["Aqua", "Electron", "ExplicitImports", "ModelingToolkit", "OrdinaryDiffEqTsit5", "Test"]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
module ElectronExt
2+
3+
using NetworkDynamicsInspector: NetworkDynamicsInspector as NDI
4+
using Electron: Electron
5+
using Bonito: Bonito
6+
7+
function NDI.display_electron_app()
8+
webapp = NDI.get_webapp()
9+
# disp = Bonito.use_electron_display()
10+
disp = Bonito.use_electron_display(devtools = true)
11+
display(disp, webapp)
12+
nothing
13+
end
14+
15+
end

NetworkDynamicsInspector/src/NetworkDynamicsInspector.jl

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,25 @@ function start_server!(restart=true)
145145
error("No appstate to restart")
146146
end
147147

148-
app = APPSTATE[]
148+
webapp = get_webapp()
149+
150+
SERVER[] = Bonito.Server(webapp, "localhost", 8080)
151+
url = SERVER[].url
152+
port = SERVER[].port
153+
@info "Visit $url:$port to launch App"
154+
end
149155

156+
function start_electron()
157+
if isempty(methods(display_electron_app))
158+
@error "Electron.jl not available. Please install Electron.jl and `using Electron` before calling this function."
159+
else
160+
display_electron_app()
161+
end
162+
end
163+
function display_electron_app end
164+
165+
function get_webapp()
166+
app = APPSTATE[]
150167
webapp = Bonito.App() do session
151168
@info "New GUI Session started"
152169
if !isnothing(SESSION[]) && Base.isopen(SESSION[])
@@ -210,24 +227,20 @@ function start_server!(restart=true)
210227
class="maingrid"
211228
)
212229
end;
213-
214-
SERVER[] = Bonito.Server(webapp, "localhost", 8080)
215-
url = SERVER[].url
216-
port = SERVER[].port
217-
@info "Visit $url:$port to launch App"
218230
end
219231

220232
"""
221-
inspect(sol; restart=false, reset=false)
233+
inspect(sol; restart=false, reset=false, electron=false)
222234
223235
Main entry point for gui. Starts the server and serves the app for
224236
soution `sol`.
225237
226238
- `restart`: If `true`, stop the server if it is running and start a new one.
227239
- `reset`: If `true`, reset the appstate with the new solution `sol`.
240+
- `electron`: If `true`, start the app in an electron window (only possible after `using Electron`).
228241
"""
229-
function inspect(sol; restart=false, reset=false)
230-
if restart && server_running()
242+
function inspect(sol; restart=false, reset=false, electron=false)
243+
if (restart || electron) && server_running()
231244
stop_server!()
232245
end
233246
if isnothing(APPSTATE[]) || reset
@@ -236,10 +249,14 @@ function inspect(sol; restart=false, reset=false)
236249
APPSTATE[].sol[] = sol
237250
end
238251

239-
if !server_running()
240-
start_server!()
252+
if electron
253+
start_electron()
241254
else
242-
@info "App still served at $(SERVER[].url):$(SERVER[].port)"
255+
if !server_running()
256+
start_server!()
257+
else
258+
@info "App still served at $(SERVER[].url):$(SERVER[].port)"
259+
end
243260
end
244261
nothing
245262
end
Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,79 @@
11
using Test
22
using NetworkDynamics
33
using NetworkDynamicsInspector
4+
using NetworkDynamicsInspector: NetworkDynamicsInspector as NDI
45
using ExplicitImports
56
using Aqua
7+
using Electron
8+
using Bonito
9+
using OrdinaryDiffEqTsit5
10+
using NetworkDynamics.Graphs
611

7-
@testset "Package Quality Tests" begin
8-
@test check_no_implicit_imports(NetworkDynamicsInspector) === nothing
9-
@test check_no_stale_explicit_imports(NetworkDynamicsInspector) === nothing
12+
include(joinpath(pkgdir(NetworkDynamics), "test", "ComponentLibrary.jl"))
1013

11-
Aqua.test_all(NetworkDynamicsInspector;
12-
ambiguities=false,
13-
stale_deps=true,
14-
persistent_tasks=false,
15-
piracies = (;treat_as_own = [NetworkDynamics.extract_nw])
16-
)
14+
function get_sol()
15+
g = SimpleGraph([0 1 1 0 1;
16+
1 0 1 1 0;
17+
1 1 0 1 0;
18+
0 1 1 0 1;
19+
1 0 0 1 0])
20+
vs = [Lib.swing_mtk() for _ in 1:5];
21+
set_default!(vs[1], :Pmech, -1)
22+
set_default!(vs[2], :Pmech, 1.5)
23+
set_default!(vs[3], :Pmech, -1)
24+
set_default!(vs[4], :Pmech, -1)
25+
set_default!(vs[5], :Pmech, 1.5)
26+
ls = [Lib.line_mtk() for _ in 1:7];
27+
nw = Network(g, vs, ls)
28+
sinit = NWState(nw)
29+
s0 = find_fixpoint(nw)
30+
set_defaults!(nw, s0)
31+
32+
# set_position!(vs[1], (0.0, 0.0))
33+
set_marker!(vs[1], :dtriangle)
34+
set_marker!(vs[2], :utriangle)
35+
set_marker!(vs[3], :dtriangle)
36+
set_marker!(vs[4], :dtriangle)
37+
set_marker!(vs[5], :utriangle)
38+
39+
cond = ComponentCondition([:P, :₋P, :srcθ], [:limit, :K]) do u, p, t
40+
abs(u[:P]) - p[:limit]
41+
end
42+
affect = ComponentAffect([],[:active]) do u, p, ctx
43+
@info "Trip line $(ctx.eidx) between $(ctx.src) and $(ctx.dst) at t=$(ctx.t)"
44+
p[:active] = 0
45+
end
46+
cb = ContinousComponentCallback(cond, affect)
47+
set_callback!.(ls, Ref(cb))
48+
49+
tripfirst = PresetTimeComponentCallback(1.0, affect) # reuse the same affect
50+
add_callback!(nw[EIndex(5)], tripfirst)
51+
52+
nwcb = NetworkDynamics.get_callbacks(nw);
53+
s0 = NWState(nw)
54+
prob = ODEProblem(nw, uflat(s0), (0,6), copy(pflat(s0)), callback=nwcb)
55+
sol = solve(prob, Tsit5())
56+
end
57+
58+
@testset "NetworkDynamicsInspector.jl Tests" begin
59+
@testset "Package Quality Tests" begin
60+
@test check_no_implicit_imports(NetworkDynamicsInspector) === nothing
61+
@test check_no_stale_explicit_imports(NetworkDynamicsInspector) === nothing
62+
63+
Aqua.test_all(NetworkDynamicsInspector;
64+
ambiguities=false,
65+
stale_deps=true,
66+
persistent_tasks=false,
67+
piracies = (;treat_as_own = [NetworkDynamics.extract_nw])
68+
)
69+
70+
@test_broken isempty(Docs.undocumented_names(NetworkDynamicsInspector))
71+
end
72+
73+
@testset "Test simple app creation" begin
74+
sol = get_sol()
75+
inspect(sol; electron=true)
76+
end
77+
end
1778

18-
@test_broken isempty(Docs.undocumented_names(NetworkDynamicsInspector))
1979
end

0 commit comments

Comments
 (0)