[gnome-games/wip/exalm/subprocess: 13/13] display-view: Handle runner crashes



commit ed6fe0e2c03e88987291a0d947950c621b8cbffc
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Fri Jan 10 18:58:29 2020 +0500

    display-view: Handle runner crashes

 data/ui/display-box.ui      |  1 +
 src/core/runner.vala        |  1 +
 src/retro/retro-runner.vala | 18 ++++++++++++++----
 src/ui/display-box.vala     | 12 ++++++++++++
 src/ui/display-view.vala    | 24 ++++++++++++++++++++++++
 5 files changed, 52 insertions(+), 4 deletions(-)
---
diff --git a/data/ui/display-box.ui b/data/ui/display-box.ui
index 0e2044ff..452a2849 100644
--- a/data/ui/display-box.ui
+++ b/data/ui/display-box.ui
@@ -21,6 +21,7 @@
             <child>
               <object class="GamesErrorDisplay" id="error_display">
                 <property name="visible">True</property>
+                <signal name="restart" handler="restart_cb"/>
               </object>
               <packing>
                 <property name="name">error</property>
diff --git a/src/core/runner.vala b/src/core/runner.vala
index 7a10160b..98d23542 100644
--- a/src/core/runner.vala
+++ b/src/core/runner.vala
@@ -3,6 +3,7 @@
 public interface Games.Runner : Object {
        public signal void new_savestate_created ();
        public signal void stopped ();
+       public signal void crash (string message);
 
        public abstract bool can_fullscreen { get; }
        public abstract bool can_resume { get; }
diff --git a/src/retro/retro-runner.vala b/src/retro/retro-runner.vala
index 6cb16bb4..659d32ff 100644
--- a/src/retro/retro-runner.vala
+++ b/src/retro/retro-runner.vala
@@ -62,6 +62,7 @@ public class Games.RetroRunner : Object, Runner {
 
        private bool is_initialized;
        private bool is_ready;
+       private bool is_error;
 
        public RetroRunnerBuilder builder {
                construct {
@@ -271,6 +272,10 @@ public class Games.RetroRunner : Object, Runner {
                _input_mode = input_manager.input_mode;
 
                core.shutdown.connect (stop);
+               core.crashed.connect ((core, error) => {
+                       is_error = true;
+                       crash (error);
+               });
 
                core.run (); // Needed to finish preparing some cores.
 
@@ -286,8 +291,11 @@ public class Games.RetroRunner : Object, Runner {
                settings.changed["video-filter"].disconnect (on_video_filter_changed);
 
                core = null;
-               view.set_core (null);
-               view = null;
+
+               if (view != null) {
+                       view.set_core (null);
+                       view = null;
+               }
 
                input_manager = null;
 
@@ -351,8 +359,10 @@ public class Games.RetroRunner : Object, Runner {
                if (!running)
                        return;
 
-               current_state_pixbuf = view.get_pixbuf ();
-               core.stop ();
+               if (!is_error) {
+                       current_state_pixbuf = view.get_pixbuf ();
+                       core.stop ();
+               }
 
                //FIXME:
                // In the future here there will be code which updates the currently
diff --git a/src/ui/display-box.vala b/src/ui/display-box.vala
index 412002bd..1891b0b3 100644
--- a/src/ui/display-box.vala
+++ b/src/ui/display-box.vala
@@ -3,6 +3,7 @@
 [GtkTemplate (ui = "/org/gnome/Games/ui/display-box.ui")]
 private class Games.DisplayBox : Gtk.Bin {
        public signal void back ();
+       public signal void restart ();
 
        private bool _is_fullscreen;
        public bool is_fullscreen {
@@ -83,6 +84,12 @@ private class Games.DisplayBox : Gtk.Bin {
                error_display.running_game_failed (game, error_message);
        }
 
+       public void display_game_crashed (Game game, string error_message) {
+               stack.visible_child = error_display;
+               savestates_list_state.is_revealed = false;
+               error_display.game_crashed (game, error_message);
+       }
+
        [GtkCallback]
        private void on_fullscreen_header_bar_back () {
                back ();
@@ -140,4 +147,9 @@ private class Games.DisplayBox : Gtk.Bin {
        private void on_savestates_list_size_allocate (Gtk.Allocation allocation) {
                display_bin.horizontal_offset = -allocation.width / 2;
        }
+
+       [GtkCallback]
+       private void restart_cb () {
+               restart ();
+       }
 }
diff --git a/src/ui/display-view.vala b/src/ui/display-view.vala
index b718e707..d134d1b0 100644
--- a/src/ui/display-view.vala
+++ b/src/ui/display-view.vala
@@ -55,6 +55,7 @@ private class Games.DisplayView : Object, UiView {
        private SavestatesListState savestates_list_state;
 
        private long focus_out_timeout_id;
+       private Game game;
 
        public DisplayView (Gtk.Window window) {
                Object (window: window);
@@ -67,6 +68,7 @@ private class Games.DisplayView : Object, UiView {
 
                savestates_list_state.on_revealer_transition_end.connect (on_savestates_list_transition_end);
                box.back.connect (on_display_back);
+               box.restart.connect (restart_cb);
                header_bar.back.connect (on_display_back);
 
                settings = new Settings ("org.gnome.Games");
@@ -134,6 +136,9 @@ private class Games.DisplayView : Object, UiView {
                }
 
                // Shortcuts for the Savestates manager
+               if (box.runner == null)
+                       return false;
+
                if (!box.runner.supports_savestates)
                        return false;
 
@@ -249,11 +254,17 @@ private class Games.DisplayView : Object, UiView {
                back ();
        }
 
+       private void restart_cb () {
+               run_game (game);
+       }
+
        public void run_game (Game game) {
                // If there is a game already running we have to quit it first
                if (box.runner != null && !quit_game ())
                        return;
 
+               this.game = game;
+
                if (run_game_cancellable != null)
                        run_game_cancellable.cancel ();
 
@@ -286,6 +297,19 @@ private class Games.DisplayView : Object, UiView {
                header_bar.media_set = runner.media_set;
                box.header_bar.media_set = runner.media_set;
 
+               runner.crash.connect (message => {
+                       runner.stop ();
+                       reset_display_page ();
+
+                       if (run_game_cancellable != null)
+                               run_game_cancellable.cancel ();
+
+                       if (quit_game_cancellable != null)
+                               quit_game_cancellable.cancel ();
+
+                       box.display_game_crashed (game, message);
+               });
+
                is_fullscreen = settings.get_boolean ("fullscreen") && runner.can_fullscreen;
 
                if (!runner.can_resume) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]