[gnome-sudoku/multithread_printing] Create an async method for multiple puzzle generation



commit 2bb404fdfd95bbb61563325af93a2b193be29081
Author: Parin Porecha <parinporecha gmail com>
Date:   Thu Aug 14 14:13:19 2014 +0200

    Create an async method for multiple puzzle generation

 lib/Makefile.am           |    1 +
 lib/sudoku-generator.vala |   22 ++++++++++++
 src/Makefile.am           |    1 -
 src/gnome-sudoku.vala     |   10 +++++-
 src/sudoku-printer.vala   |   85 ++++++++++----------------------------------
 5 files changed, 52 insertions(+), 67 deletions(-)
---
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e0af6eb..f8d67c6 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -26,6 +26,7 @@ libsudoku_la_VALAFLAGS = \
        --pkg gio-2.0 \
        --pkg json-glib-1.0 \
        --pkg posix \
+       --target-glib=2.32      \
        --header=libsudoku.h \
        --vapi=libsudoku.vapi
 
diff --git a/lib/sudoku-generator.vala b/lib/sudoku-generator.vala
index c53a406..c67f4e5 100644
--- a/lib/sudoku-generator.vala
+++ b/lib/sudoku-generator.vala
@@ -22,6 +22,28 @@ public class SudokuGenerator : Object
         return board;
     }
 
+    public async static SudokuBoard[] generate_boards_async (int nboards, DifficultyCategory category) 
throws ThreadError
+    {
+        SourceFunc callback = generate_boards_async.callback;
+        var boards = new SudokuBoard[nboards];
+
+        // Hold reference to closure to keep it from being freed whilst
+        // thread is active.
+        ThreadFunc<void*> generate = () => {
+            for (var i = 0; i < nboards; i++)
+                boards[i] = generate_board (category);
+
+            // Schedule callback
+            Idle.add((owned) callback);
+            return null;
+        };
+        new Thread<void*>("Generator thread", generate);
+
+        // Wait for background thread to schedule our callback
+        yield;
+        return boards;
+    }
+
     public static void print_stats (SudokuBoard board)
     {
         var cells = board.get_cells ();
diff --git a/src/Makefile.am b/src/Makefile.am
index b3c7087..f711496 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,7 +31,6 @@ gnome_sudoku_VALAFLAGS = \
        --pkg gio-2.0 \
        --pkg gtk+-3.0 \
        --pkg gee-0.8 \
-       --target-glib=2.32      \
        $(top_builddir)/lib/libsudoku.vapi
 
 gnome-sudoku-resources.c: gnome-sudoku.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) 
--generate-dependencies gnome-sudoku.gresource.xml)
diff --git a/src/gnome-sudoku.vala b/src/gnome-sudoku.vala
index b0ece3d..fb60af5 100644
--- a/src/gnome-sudoku.vala
+++ b/src/gnome-sudoku.vala
@@ -294,7 +294,15 @@ public class Sudoku : Gtk.Application
         // has been set to integers corresponding to the enums.
         // Following line converts those ints to their DifficultyCategory
         var selected_difficulty = (DifficultyCategory) difficulty.get_int32 ();
-        start_game (SudokuGenerator.generate_board (selected_difficulty));
+
+        SudokuGenerator.generate_boards_async.begin (1, selected_difficulty, (obj, res) => {
+            try {
+                var gen_boards = SudokuGenerator.generate_boards_async.end (res);
+                start_game (gen_boards[0]);
+            } catch (ThreadError e) {
+                error ("Thread error: %s", e.message);
+            }
+        });
     }
 
     private void reset_cb ()
diff --git a/src/sudoku-printer.vala b/src/sudoku-printer.vala
index 85c6251..f55548b 100644
--- a/src/sudoku-printer.vala
+++ b/src/sudoku-printer.vala
@@ -302,13 +302,8 @@ public class GamePrinter: GLib.Object
             return;
         }
 
-        spinner.visible = true;
-        spinner.start ();
-
-        boards_list = new ArrayList<SudokuBoard> ();
         var nsudokus = (int) nsudokus_button.get_adjustment ().get_value ();
         DifficultyCategory level;
-        var boards = new SudokuBoard[nsudokus];
 
         if (simple_button.get_active ())
             level = DifficultyCategory.SIMPLE;
@@ -323,47 +318,29 @@ public class GamePrinter: GLib.Object
 
         settings.set_enum (DIFFICULTY_KEY_NAME, level);
 
-        if (Thread.supported () == false)
-        {
-            for (var i = 0; i < nsudokus; i++)
-                boards[i] = SudokuGenerator.generate_board (level);
-        }
-        else
-        {
-//            var sysinfo = GLibtop.glibtop_sysinfo.get_sysinfo ();
-//            stdout.printf ("ncpus = %d\n", sysinfo.ncpu);
+        SudokuGenerator.generate_boards_async.begin(nsudokus, level, (obj, res) => {
+            try {
+                spinner.visible = true;
+                spinner.start ();
+                spinner.show ();
 
-            var ncpu = 4;
-            var base_nsudokus_each = nsudokus / ncpu;
-            var remainder = nsudokus % ncpu;
-            var nsudokus_per_thread = base_nsudokus_each;
+                var boards = SudokuGenerator.generate_boards_async.end(res);
 
-            for (var i = 0; i < ncpu; i++)
-            {
-                if (i > (ncpu - remainder - 1))
-                    nsudokus_per_thread = base_nsudokus_each + 1;
-                var gen_thread = new GeneratorThread (nsudokus_per_thread, level, i);
-                Thread<int> thread = new Thread<int> ("Generator thread", gen_thread.run);
-                var result = thread.join ();
-                stdout.printf ("Thread #%d exited\n", result);
-            }
-
-            for (var i = 0; i < boards_list.size; i++)
-                boards[i] = boards_list[i];
-        }
-
-        spinner.stop ();
-
-        SudokuPrinter printer = new SudokuPrinter (boards, ref window);
+                SudokuPrinter printer = new SudokuPrinter (boards, ref window);
+                PrintOperationResult result = printer.print_sudoku ();
+                if (result == PrintOperationResult.APPLY)
+                {
+                    dialog.hide ();
+                    foreach (SudokuBoard board in boards)
+                        saver.add_game_to_finished (new SudokuGame (board));
+                }
 
-        PrintOperationResult result = printer.print_sudoku ();
-        if (result == PrintOperationResult.APPLY)
-        {
-            dialog.hide ();
-            foreach (SudokuBoard board in boards)
-                saver.add_game_to_finished (new SudokuGame (board));
-        }
-        boards_list = null;
+                boards_list = null;
+                spinner.stop ();
+            } catch (ThreadError e) {
+                error ("Thread error: %s\n", e.message);
+            }
+        });
     }
 
     public void run_dialog ()
@@ -372,25 +349,3 @@ public class GamePrinter: GLib.Object
     }
 
 }
-
-public class GeneratorThread : Object
-{
-    private int nsudokus;
-    private DifficultyCategory level;
-    private int id;
-
-    public GeneratorThread (int nsudokus, DifficultyCategory level, int id) {
-        this.nsudokus = nsudokus;
-        this.level = level;
-        this.id = id;
-    }
-
-    public int run ()
-    {
-        stdout.printf ("generating %d puzzles\n", nsudokus);
-        for (var i = 0; i < nsudokus; i++)
-            boards_list.add (SudokuGenerator.generate_board (level));
-
-        return id;
-    }
-}


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