From 16e03cd3ada09a6c80582201789c6153aa5de327 Mon Sep 17 00:00:00 2001
From: Jonathan Wilkes <jon.w.wilkes@gmail.com>
Date: Thu, 19 Nov 2015 21:52:56 -0500
Subject: [PATCH] abstract out the socket client so that the GUI can be the
 server when it needs to spawn Pd itself

---
 pd/nw/index.js | 152 +++++++++++++++++++++++++++++--------------------
 pd/nw/pdgui.js |  30 +++++++---
 2 files changed, 112 insertions(+), 70 deletions(-)

diff --git a/pd/nw/index.js b/pd/nw/index.js
index 88dbacdf4..42e6f1f4c 100644
--- a/pd/nw/index.js
+++ b/pd/nw/index.js
@@ -1,19 +1,9 @@
 "use strict";
 var gui = require("nw.gui");
-console.log("foo is foo");
-console.log("gurgle is " + gui.App.argv);
 var pdgui = require("./pdgui.js");
-var port_no = gui.App.argv[0]; // fed to us by the Pd process
-var gui_dir = gui.App.argv[3];
+
+// we're using pwd in fileDialog
 var pwd = process.env.PWD;
-pdgui.set_port(port_no);
-pdgui.set_pwd(pwd);
-pdgui.set_gui_dir(gui_dir);
-pdgui.set_pd_window(this);
-pdgui.set_app_quitfn(app_quit);
-pdgui.set_open_html_fn(open_html);
-pdgui.set_open_textfile_fn(open_textfile);
-pdgui.set_open_external_doc_fn(open_external_doc);
 
 // gui preset
 pdgui.skin.apply(this);
@@ -21,7 +11,49 @@ pdgui.skin.apply(this);
 // For translations
 var l = pdgui.get_local_string;
 
-function app_quit () {
+// Set up the Pd Window
+set_vars(this);
+add_events();
+nw_create_pd_window_menus();
+gui.Window.get().setMinimumSize(350,250);
+// This part depends on whether the GUI is starting Pd, or whether it's
+// the other way around.
+connect();
+
+function have_args() {
+    return !!gui.App.argv.length;
+}
+
+function set_vars(global) {
+    var port_no, gui_dir;
+    // If the GUI was started by Pd, our port number is going to be
+    // the first argument. If the GUI is supposed to start Pd, we won't
+    // have any arguments and need to set it here.
+    if (have_args()) {
+        port_no = gui.App.argv[0]; // fed to us by the Pd process
+        // looks like this is the same as pwd below
+        gui_dir = gui.App.argv[3];
+    } else {
+        // If we're starting Pd, this is the first port number to try. (We'll
+        // increment it if that port happens to be taken.
+        port_no = 5400; 
+        gui_dir = pwd;
+    }
+    pdgui.set_port(port_no);
+    pdgui.set_pwd(pwd);
+    pdgui.set_gui_dir(gui_dir);
+    pdgui.set_pd_window(global);
+    pdgui.set_app_quitfn(app_quit);
+    pdgui.set_open_html_fn(open_html);
+    pdgui.set_open_textfile_fn(open_textfile);
+    pdgui.set_open_external_doc_fn(open_external_doc);
+
+    // nw context callbacks (mostly just creating/destroying windows)
+    pdgui.set_new_window_fn(nw_create_window);
+    pdgui.set_close_window_fn(nw_close_window);
+}
+
+function app_quit() {
     console.log("quitting Pd...");
     gui.App.quit();
 }
@@ -38,51 +70,53 @@ function open_external_doc(target) {
     gui.Shell.openExternal(target);
 }
 
-document.getElementById("dsp_control").addEventListener("click",
-    function(evt) {
-        var dsp_state = this.checked ? 1 : 0;
-        pdgui.pdsend("pd dsp", dsp_state);
-    }
-);
-
-var find_bar = document.getElementById("console_find_text");
-find_bar.addEventListener("keydown",
-    function(e) {
-        return console_find_keydown(this, e);
-    }, false
-);
-
-find_bar.addEventListener("keypress",
-    function(e) {
-        console_find_keypress(this, e);
-    }, false
-);
-
-find_bar.defaultValue = "Search in Console";
-
-console_find_set_default(find_bar);
-
-
-// Invoke some functions to create main menus, etc.
-gui.Window.get().on("close", function() {
-    pdgui.menu_quit();
-});
-console.log(gui.App.argv); 
-
-document.getElementById("fileDialog").setAttribute("nwworkingdir", pwd);
-document.getElementById("fileDialog").setAttribute("accept",
-    Object.keys(pdgui.pd_filetypes).toString());
-
-nw_create_pd_window_menus();
-
-gui.Window.get().setMinimumSize(350,250);
-
-pdgui.connect();
-pdgui.init_socket_events();
+function add_events() {
+    // Find bar
+    var find_bar = document.getElementById("console_find_text");
+    find_bar.defaultValue = "Search in Console";
+    console_find_set_default(find_bar);
+    find_bar.addEventListener("keydown",
+        function(e) {
+            return console_find_keydown(this, e);
+        }, false
+    );
+    find_bar.addEventListener("keypress",
+        function(e) {
+            console_find_keypress(this, e);
+        }, false
+    );
+    // DSP toggle
+    document.getElementById("dsp_control").addEventListener("click",
+        function(evt) {
+            var dsp_state = this.checked ? 1 : 0;
+            pdgui.pdsend("pd dsp", dsp_state);
+        }
+    );
+    // Browser Window Close
+    gui.Window.get().on("close", function() {
+        pdgui.menu_quit();
+    });
+    // Open dialog
+    document.getElementById("fileDialog").setAttribute("nwworkingdir", pwd);
+    document.getElementById("fileDialog").setAttribute("accept",
+        Object.keys(pdgui.pd_filetypes).toString());
+}
 
-// nw context callbacks (mostly just creating/destroying windows)
-pdgui.set_new_window_fn(nw_create_window);
-pdgui.set_close_window_fn(nw_close_window);
+function connect() {
+    // When the GUI is started by core Pd, it gives it some command
+    // line args. In that case we just need to create a client and
+    // connect to Pd on the port it gave us as an arg.
+    // If we have no command line args, it means we need to create a
+    // server, and also create the Pd process with the command line
+    // arg -guiport and providing the port we are listening on.
+    if (have_args()) {
+        pdgui.create_client();
+    } else {
+        pdgui.post("creating server");
+        pdgui.create_server();
+    }
+    pdgui.init_socket_events();
+}
 
 function console_find_check_default(e) {
     if (e.value === e.defaultValue) {
@@ -717,7 +751,3 @@ function nw_create_window(cid, type, width, height, xpos, ypos, menu_flag,
     });
     return new_win;
 }
-
-function canvasNew(args) {
-    console.log(args);
-}
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index da939de27..03def5906 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -931,23 +931,35 @@ var net = require("net");
 
 var HOST = "127.0.0.1";
 var PORT;
-var client;
+var socket;
 
 exports.set_port = function (port_no) {
     PORT = port_no;
 }
 
-function connect () {
-    client = new net.Socket();
+function create_client() {
+    var client = new net.Socket();
     client.setNoDelay(true);
     // uncomment the next line to use fast_parser (then set its callback below)
     //client.setEncoding("utf8");
     client.connect(PORT, HOST, function() {
         console.log("CONNECTED TO: " + HOST + ":" + PORT);
     });
+    socket = client;
 }
 
-exports.connect = connect;
+exports.create_client = create_client;
+
+function create_server() {
+    var server = net.createServer(function(c) {
+        console.log("server connected");
+    });
+    server.listen(PORT, HOST);
+    console.log("listening on port " + PORT + " on host " + HOST);
+    socket = server;
+}
+
+exports.create_server= create_server;
 
 // Add a 'data' event handler for the client socket
 // data parameter is what the server sent to this socket
@@ -1019,12 +1031,12 @@ function init_socket_events () {
         }
     };
 
-    client.on("data", perfect_parser);
+    socket.on("data", perfect_parser);
 
-    // Add a "close" event handler for the client socket
-    client.on("close", function() {
+    // Add a "close" event handler for the socket
+    socket.on("close", function() {
         //console.log("Connection closed");
-        //client.destroy();
+        //socket.destroy();
         nw_app_quit(); // set a timeout here if you need to debug
     });
 }
@@ -1037,7 +1049,7 @@ function pdsend() {
     // some reason.  But it doesn't look like it makes that much
     // of a difference
     var string = Array.prototype.join.call(arguments, " ");
-    client.write(string + ";");
+    socket.write(string + ";");
     // reprint the outgoing string to the pdwindow
     //post(string + ";", "red");
 }
-- 
GitLab