From efa4897a91d0d0ec40548d3fce24d370b8e19fe4 Mon Sep 17 00:00:00 2001 From: Jonathan Wilkes <jon.w.wilkes@gmail.com> Date: Sun, 22 Nov 2015 18:11:15 -0500 Subject: [PATCH] first attempt at starting Pd from the GUI --- pd/nw/index.js | 27 +++++++++++++------------- pd/nw/pdgui.js | 52 ++++++++++++++++++++++++++++++++++---------------- pd/nw/todo.txt | 1 + 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/pd/nw/index.js b/pd/nw/index.js index 42e6f1f4c..8ef53a3fe 100644 --- a/pd/nw/index.js +++ b/pd/nw/index.js @@ -16,8 +16,13 @@ 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. +// Now we create a connection from the GUI to Pd, in one of two ways: +// 1) If the GUI was started by Pd, then we create a tcp client and +// connect on the port Pd fed us in our command line arguments. +// 2) If Pd hasn't started yet, then the GUI creates a tcp server and spawns +// Pd using the "-guiport" flag with the port the GUI is listening on. +// Pd always starts the GUI with a certain set of command line arguments. If +// those arguments aren't present then we assume we need to start Pd. connect(); function have_args() { @@ -103,19 +108,15 @@ function add_events() { } 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(); + if (have_args()) { + // Pd started the GUI, so connect to it on port provided in our args + pdgui.post("Pd has started the GUI"); + pdgui.connect_as_client(); } else { - pdgui.post("creating server"); - pdgui.create_server(); + // create a tcp server, then spawn Pd with "-guiport" flag and port + pdgui.post("GUI is starting Pd..."); + pdgui.connect_as_server(); } - pdgui.init_socket_events(); } function console_find_check_default(e) { diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index 03def5906..f1e9b58d7 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -1,7 +1,5 @@ "use strict"; -// Modules - var pwd; var gui_dir; @@ -29,8 +27,11 @@ exports.get_pd_opendir = function() { } } +// Modules + var fs = require("fs"); // for fs.existsSync var path = require("path"); // for path.dirname path.extname path.join +var cp = require("child_process"); // for starting core Pd from GUI in OSX // local strings var lang = require("./pdlang.js"); @@ -691,6 +692,7 @@ function gui_check_unique (unique) { function gui_startup(version, fontname_from_pd, fontweight_from_pd, apilist, midiapilist) { console.log("Starting up..."); + console.log("gui_startup from GUI..."); // # tb: user defined typefaces // set some global variables pd_myversion = version; @@ -926,18 +928,32 @@ function gui_canvas_erase_all_gobjs(cid) { exports.canvas_map = canvas_map; +// Start Pd + +// If the GUI is started first (as in a Mac OSX Bundle) we use this +// function to actually start the core +function spawn_pd() { + var pd_binary = "/home/user/pd-nw/packages/linux_make/build/usr/bin/pd-l2ork"; + var child = cp.spawn(pd_binary, ["-guiport", PORT, "-nrt"], { + stdio: "inherit", + detached: true + }); + child.unref(); + post("Pd started."); +} + // net stuff var net = require("net"); var HOST = "127.0.0.1"; var PORT; -var socket; +var connection; // the GUI's socket connection to Pd exports.set_port = function (port_no) { PORT = port_no; } -function create_client() { +function connect_as_client() { var client = new net.Socket(); client.setNoDelay(true); // uncomment the next line to use fast_parser (then set its callback below) @@ -945,21 +961,25 @@ function create_client() { client.connect(PORT, HOST, function() { console.log("CONNECTED TO: " + HOST + ":" + PORT); }); - socket = client; + connection = client; + init_socket_events(); } -exports.create_client = create_client; +exports.connect_as_client = connect_as_client; -function create_server() { +function connect_as_server() { var server = net.createServer(function(c) { - console.log("server connected"); + post("incoming connection to GUI"); + connection = c; + init_socket_events(); + }); + server.listen(PORT, HOST, function() { + post("GUI listening on port " + PORT + " on host " + HOST); + spawn_pd(); }); - server.listen(PORT, HOST); - console.log("listening on port " + PORT + " on host " + HOST); - socket = server; } -exports.create_server= create_server; +exports.connect_as_server = connect_as_server; // Add a 'data' event handler for the client socket // data parameter is what the server sent to this socket @@ -1031,12 +1051,12 @@ function init_socket_events () { } }; - socket.on("data", perfect_parser); + connection.on("data", perfect_parser); // Add a "close" event handler for the socket - socket.on("close", function() { + connection.on("close", function() { //console.log("Connection closed"); - //socket.destroy(); + //connection.destroy(); nw_app_quit(); // set a timeout here if you need to debug }); } @@ -1049,7 +1069,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, " "); - socket.write(string + ";"); + connection.write(string + ";"); // reprint the outgoing string to the pdwindow //post(string + ";", "red"); } diff --git a/pd/nw/todo.txt b/pd/nw/todo.txt index b10a98783..69cfa5fa3 100644 --- a/pd/nw/todo.txt +++ b/pd/nw/todo.txt @@ -335,6 +335,7 @@ Everything else: (A [x] means we've fixed it) does _not_ send a key to Pd. Since <ctrl-v> is bound to "paste" and <ctrl-h> isn't bound to anything, that may somehow be causing an inconsistency. +[ ] make GUI server try again if the port is already in use Crashers -------- -- GitLab