@@ -11,8 +11,6 @@ defmodule Scenic.ViewPort do
11
11
alias Scenic.Primitive
12
12
alias Scenic.ViewPort.Context
13
13
14
- # import IEx
15
-
16
14
@ moduledoc """
17
15
18
16
## Overview
@@ -101,7 +99,7 @@ defmodule Scenic.ViewPort do
101
99
@ doc """
102
100
Start a new viewport
103
101
"""
104
- @ spec start ( config :: ViewPort.Config . t ( ) ) :: { :ok , pid }
102
+ @ spec start ( config :: map ) :: { :ok , pid }
105
103
def start ( % ViewPort.Config { } = config ) do
106
104
# start the viewport's supervision tree
107
105
{ :ok , sup_pid } =
@@ -123,15 +121,8 @@ defmodule Scenic.ViewPort do
123
121
{ :ok , viewport_pid }
124
122
end
125
123
126
- # --------------------------------------------------------
127
- @ doc """
128
- query the last recorded viewport status
129
- """
130
- @ spec info ( viewport :: GenServer . server ( ) ) :: { :ok , ViewPort.Status . t ( ) }
131
- def info ( viewport )
132
-
133
- def info ( viewport ) when is_atom ( viewport ) or is_pid ( viewport ) do
134
- GenServer . call ( viewport , :query_info )
124
+ def start ( % { } = config ) do
125
+ start ( struct ( ViewPort.Config , config ) )
135
126
end
136
127
137
128
# --------------------------------------------------------
@@ -146,7 +137,25 @@ defmodule Scenic.ViewPort do
146
137
end
147
138
148
139
def stop ( viewport ) when is_pid ( viewport ) do
149
- DynamicSupervisor . terminate_child ( @ viewports , viewport )
140
+ # dynamic viewports are actually supervised by their own supervisor.
141
+ # so first we have to get that, which is what we actually stop
142
+ [ supervisor_pid | _ ] =
143
+ viewport
144
+ |> Process . info ( )
145
+ |> get_in ( [ :dictionary , :"$ancestors" ] )
146
+
147
+ DynamicSupervisor . terminate_child ( @ viewports , supervisor_pid )
148
+ end
149
+
150
+ # --------------------------------------------------------
151
+ @ doc """
152
+ query the last recorded viewport status
153
+ """
154
+ @ spec info ( viewport :: GenServer . server ( ) ) :: { :ok , ViewPort.Status . t ( ) }
155
+ def info ( viewport )
156
+
157
+ def info ( viewport ) when is_atom ( viewport ) or is_pid ( viewport ) do
158
+ GenServer . call ( viewport , :query_info )
150
159
end
151
160
152
161
# --------------------------------------------------------
@@ -302,7 +311,7 @@ defmodule Scenic.ViewPort do
302
311
# --------------------------------------------------------
303
312
@ doc false
304
313
def init ( { vp_sup , config } ) do
305
- GenServer . cast ( self ( ) , { :after_init , vp_sup , config } )
314
+ GenServer . cast ( self ( ) , { :delayed_init , vp_sup , config } )
306
315
{ :ok , nil }
307
316
end
308
317
@@ -323,14 +332,15 @@ defmodule Scenic.ViewPort do
323
332
_ ,
324
333
% {
325
334
supervisor: vp_supervisor ,
326
- dynamic_supervisor: dyn_sup
335
+ dynamic_supervisor: dyn_sup ,
336
+ size: size
327
337
} = state
328
338
) do
329
339
{
330
340
:reply ,
331
341
DynamicSupervisor . start_child (
332
342
dyn_sup ,
333
- { Scenic.ViewPort.Driver , { vp_supervisor , config } }
343
+ { Scenic.ViewPort.Driver , { vp_supervisor , size , config } }
334
344
) ,
335
345
state
336
346
}
@@ -363,7 +373,7 @@ defmodule Scenic.ViewPort do
363
373
# ============================================================================
364
374
# handle_cast
365
375
366
- def handle_cast ( { :after_init , vp_supervisor , config } , _ ) do
376
+ def handle_cast ( { :delayed_init , vp_supervisor , config } , _ ) do
367
377
# find the viewport and associated pids this driver belongs to
368
378
dyn_sup_pid =
369
379
vp_supervisor
@@ -376,10 +386,15 @@ defmodule Scenic.ViewPort do
376
386
# get the on_close flag or function
377
387
on_close =
378
388
case config . on_close do
379
- nil -> :stop_system
380
- :stop_system -> :stop_system
381
- :stop_viewport -> :stop_viewport
382
- func when is_function ( func , 1 ) -> func
389
+ nil ->
390
+ :stop_system
391
+
392
+ :stop_system ->
393
+ :stop_system
394
+
395
+ :stop_viewport ->
396
+ :stop_viewport
397
+ # func when is_function(func, 1) -> func
383
398
end
384
399
385
400
# extract the viewport global styles. Do this by reusing tools in Primitive.
@@ -461,11 +476,11 @@ defmodule Scenic.ViewPort do
461
476
|> Map . put ( :input_captures , % { } )
462
477
463
478
# fetch the dynamic supervisor
464
- dyn_sup =
465
- case dyn_sup do
466
- nil -> find_dyn_supervisor ( )
467
- dyn_sup -> dyn_sup
468
- end
479
+ # dyn_sup =
480
+ # case dyn_sup do
481
+ # nil -> find_dyn_supervisor()
482
+ # dyn_sup -> dyn_sup
483
+ # end
469
484
470
485
# if the scene being set is dynamic, start it up
471
486
{ scene_pid , scene_ref , dynamic_scene } =
@@ -535,7 +550,7 @@ defmodule Scenic.ViewPort do
535
550
{ :noreply , % { state | root_scene_pid: scene_pid , dynamic_root_pid: scene_pid } }
536
551
end
537
552
538
- def handle_cast ( { :dyn_root_up , _ } , state ) do
553
+ def handle_cast ( { :dyn_root_up , _ , _ } , state ) do
539
554
# ignore stale root_up messages
540
555
{ :noreply , state }
541
556
end
@@ -548,18 +563,20 @@ defmodule Scenic.ViewPort do
548
563
{ :stop_driver , driver_pid } ,
549
564
% {
550
565
drivers: drivers ,
551
- dynamic_supervisor: dyn_sup
566
+ dynamic_supervisor: dyn_sup ,
567
+ driver_registry: registry
552
568
} = state
553
569
) do
554
570
DynamicSupervisor . terminate_child ( dyn_sup , driver_pid )
555
571
drivers = Enum . reject ( drivers , fn pid -> pid == driver_pid end )
556
- { :noreply , % { state | drivers: drivers } }
572
+ registry = Map . delete ( registry , driver_pid )
573
+ { :noreply , % { state | drivers: drivers , driver_registry: registry } }
557
574
end
558
575
559
576
# --------------------------------------------------------
560
577
def handle_cast ( { :driver_cast , msg } , % { drivers: drivers } = state ) do
561
578
# relay the graph_key to all listening drivers
562
- do_driver_cast ( drivers , msg )
579
+ Enum . each ( drivers , & GenServer . cast ( & 1 , msg ) )
563
580
{ :noreply , state }
564
581
end
565
582
@@ -568,28 +585,26 @@ defmodule Scenic.ViewPort do
568
585
{ :driver_ready , driver_pid } ,
569
586
% {
570
587
drivers: drivers ,
571
- # root_graph_key: root_key
572
588
master_graph_key: master_graph_key
573
589
} = state
574
590
) do
575
591
drivers = [ driver_pid | drivers ] |> Enum . uniq ( )
576
- # GenServer.cast(driver_pid, {:set_root, root_key})
577
592
GenServer . cast ( driver_pid , { :set_root , master_graph_key } )
578
593
{ :noreply , % { state | drivers: drivers } }
579
594
end
580
595
581
596
# --------------------------------------------------------
582
- def handle_cast (
583
- { :driver_stopped , driver_pid } ,
584
- % {
585
- drivers: drivers ,
586
- driver_registry: registry
587
- } = state
588
- ) do
589
- drivers = Enum . reject ( drivers , fn d -> d == driver_pid end )
590
- registry = Map . delete ( registry , driver_pid )
591
- { :noreply , % { state | drivers: drivers , driver_registry: registry } }
592
- end
597
+ # def handle_cast(
598
+ # {:driver_stopped, driver_pid},
599
+ # %{
600
+ # drivers: drivers,
601
+ # driver_registry: registry
602
+ # } = state
603
+ # ) do
604
+ # drivers = Enum.reject(drivers, fn d -> d == driver_pid end)
605
+ # registry = Map.delete(registry, driver_pid)
606
+ # {:noreply, %{state | drivers: drivers, driver_registry: registry}}
607
+ # end
593
608
594
609
# --------------------------------------------------------
595
610
# def handle_cast({:request_root, to_pid}, %{root_graph_key: root_key} = state) do
@@ -604,16 +619,17 @@ defmodule Scenic.ViewPort do
604
619
end
605
620
606
621
# --------------------------------------------------------
607
- def handle_cast ( :user_close , % { on_close: on_close } = state ) do
622
+ def handle_cast ( :user_close , % { on_close: on_close , supervisor: vp_sup } = state ) do
608
623
case on_close do
609
624
:stop_viewport ->
610
- case DynamicSupervisor . terminate_child ( @ viewports , self ( ) ) do
611
- :ok -> :ok
612
- { :error , :not_found } -> Process . exit ( self ( ) , :shutdown )
613
- end
625
+ DynamicSupervisor . terminate_child ( @ viewports , vp_sup )
626
+
627
+ # :ok -> :ok
628
+ # {:error, :not_found} -> Process.exit(vp_sup, :shutdown)
629
+ # end
614
630
615
- func when is_function ( func , 1 ) ->
616
- func . ( self ( ) )
631
+ # func when is_function(func, 1) ->
632
+ # func.(self())
617
633
618
634
:stop_system ->
619
635
System . stop ( 0 )
@@ -623,19 +639,19 @@ defmodule Scenic.ViewPort do
623
639
end
624
640
625
641
# --------------------------------------------------------
626
- def handle_cast ( :user_close , state ) do
627
- case DynamicSupervisor . terminate_child ( @ viewports , self ( ) ) do
628
- :ok ->
629
- :ok
630
-
631
- { :error , :not_found } ->
632
- # Process.exit(self(), :normal)
633
- # exit(:shutdown)
634
- System . stop ( 0 )
635
- end
636
-
637
- { :noreply , state }
638
- end
642
+ # def handle_cast(:user_close, state) do
643
+ # case DynamicSupervisor.terminate_child(@viewports, self()) do
644
+ # :ok ->
645
+ # :ok
646
+
647
+ # {:error, :not_found} ->
648
+ # # Process.exit(self(), :normal)
649
+ # # exit(:shutdown)
650
+ # System.stop(0)
651
+ # end
652
+
653
+ # {:noreply, state}
654
+ # end
639
655
640
656
# ==================================================================
641
657
# management casts from scenes
@@ -649,41 +665,41 @@ defmodule Scenic.ViewPort do
649
665
# ============================================================================
650
666
# internal utilities
651
667
652
- defp do_driver_cast ( driver_pids , msg ) do
653
- Enum . each ( driver_pids , & GenServer . cast ( & 1 , msg ) )
654
- end
655
-
656
- defp find_dyn_supervisor ( ) do
657
- # get the scene supervisors
658
- [ supervisor_pid | _ ] =
659
- self ( )
660
- |> Process . info ( )
661
- |> get_in ( [ :dictionary , :"$ancestors" ] )
662
-
663
- # make sure it is a pid and not a name
664
- supervisor_pid =
665
- case supervisor_pid do
666
- name when is_atom ( name ) -> Process . whereis ( name )
667
- pid when is_pid ( pid ) -> pid
668
- end
668
+ # defp do_driver_cast(driver_pids, msg) do
669
+ # Enum.each(driver_pids, &GenServer.cast(&1, msg))
670
+ # end
669
671
670
- case Process . info ( supervisor_pid ) do
671
- nil ->
672
- nil
673
-
674
- info ->
675
- case get_in ( info , [ :dictionary , :"$initial_call" ] ) do
676
- { :supervisor , Scenic.ViewPort.Supervisor , _ } ->
677
- Supervisor . which_children ( supervisor_pid )
678
- # credo:disable-for-next-line Credo.Check.Refactor.Nesting
679
- |> Enum . find_value ( fn
680
- { DynamicSupervisor , pid , :supervisor , [ DynamicSupervisor ] } -> pid
681
- _other -> nil
682
- end )
683
-
684
- _other ->
685
- nil
686
- end
687
- end
688
- end
672
+ # defp find_dyn_supervisor() do
673
+ # # get the scene supervisors
674
+ # [supervisor_pid | _] =
675
+ # self()
676
+ # |> Process.info()
677
+ # |> get_in([:dictionary, :"$ancestors"])
678
+
679
+ # # make sure it is a pid and not a name
680
+ # supervisor_pid =
681
+ # case supervisor_pid do
682
+ # name when is_atom(name) -> Process.whereis(name)
683
+ # pid when is_pid(pid) -> pid
684
+ # end
685
+
686
+ # case Process.info(supervisor_pid) do
687
+ # nil ->
688
+ # nil
689
+
690
+ # info ->
691
+ # case get_in(info, [:dictionary, :"$initial_call"]) do
692
+ # {:supervisor, Scenic.ViewPort.Supervisor, _} ->
693
+ # Supervisor.which_children(supervisor_pid)
694
+ # # credo:disable-for-next-line Credo.Check.Refactor.Nesting
695
+ # |> Enum.find_value(fn
696
+ # {DynamicSupervisor, pid, :supervisor, [DynamicSupervisor]} -> pid
697
+ # _other -> nil
698
+ # end)
699
+
700
+ # _other ->
701
+ # nil
702
+ # end
703
+ # end
704
+ # end
689
705
end
0 commit comments