Skip to content

Commit cd4b341

Browse files
committed
tweaking the single instance server implementation
1 parent 4e202d2 commit cd4b341

3 files changed

Lines changed: 167 additions & 94 deletions

File tree

app/src/processing/app/Base.java

Lines changed: 3 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import java.awt.*;
2626
import java.awt.event.*;
2727
import java.io.*;
28-
import java.net.*;
2928
import java.text.SimpleDateFormat;
3029
import java.util.*;
3130
import java.util.List;
@@ -162,15 +161,11 @@ static private void createAndShowGUI(String[] args) {
162161
// run static initialization that grabs all the prefs
163162
Preferences.init(null);
164163

165-
String filename = args.length > 1 ? args[0] : null;
166-
if (!(Preferences.get("server.port") == null)
167-
&& sendArgumentsToOtherInstance(filename, 1000)) {
164+
// String filename = args.length > 1 ? args[0] : null;
165+
if (SingleInstance.exists(args)) {
168166
return;
169167
}
170-
createSingleInstanceServer();
171-
172-
// setup the theme coloring fun
173-
// Theme.init();
168+
SingleInstance.createServer(platform);
174169

175170
// Set the look and feel before opening the window
176171
try {
@@ -200,82 +195,6 @@ && sendArgumentsToOtherInstance(filename, 1000)) {
200195
// System.out.println("done creating base...");
201196
}
202197

203-
private static void createSingleInstanceServer() {
204-
try {
205-
final ServerSocket ss = new ServerSocket(0, 0,
206-
InetAddress.getByName(null));
207-
Preferences.set("server.port", "" + ss.getLocalPort());
208-
final String key = "" + Math.random();
209-
Preferences.set("server.key", key);
210-
Preferences.save();
211-
212-
new Thread(new Runnable() {
213-
214-
public void run() {
215-
while (true) {
216-
try {
217-
Socket s = ss.accept();
218-
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
219-
String receivedKey = br.readLine();
220-
221-
if (platform.base == null) continue;
222-
223-
if (key.equals(receivedKey)) {
224-
final String filename = br.readLine();
225-
SwingUtilities.invokeLater(new Runnable() {
226-
public void run() {
227-
if (filename != null) {
228-
platform.base.handleOpen(filename);
229-
} else {
230-
platform.base.handleNew();
231-
}
232-
};
233-
});
234-
}
235-
} catch (IOException e) {
236-
}
237-
}
238-
}
239-
}).start();
240-
} catch (IOException e) {
241-
}
242-
}
243-
244-
static private boolean sendArgumentsToOtherInstance(String filename,
245-
long timeout) {
246-
try {
247-
int port = Integer.parseInt(Preferences.get("server.port"));
248-
String key = Preferences.get("server.key");
249-
250-
long endTime = System.currentTimeMillis() + timeout;
251-
252-
Socket socket = null;
253-
while (socket == null && System.currentTimeMillis() < endTime) {
254-
try {
255-
socket = new Socket(InetAddress.getByName(null), port);
256-
} catch (Exception ioe) {
257-
try {
258-
Thread.sleep(50);
259-
} catch (InterruptedException ie) {
260-
Thread.yield();
261-
}
262-
}
263-
}
264-
265-
if (socket != null) {
266-
BufferedWriter bw = new BufferedWriter(
267-
new OutputStreamWriter(socket.getOutputStream()));
268-
bw.write(key + "\n");
269-
if (filename != null) {
270-
bw.write(filename + "\n");
271-
}
272-
bw.close();
273-
return true;
274-
}
275-
} catch (IOException e) {
276-
}
277-
return false;
278-
}
279198

280199
public static void setCommandLine() {
281200
commandLine = true;
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2+
3+
/*
4+
Part of the Processing project - http://processing.org
5+
6+
Copyright (c) 2011 Ben Fry and Casey Reas
7+
8+
This program is free software; you can redistribute it and/or modify
9+
it under the terms of the GNU General Public License version 2
10+
as published by the Free Software Foundation.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program; if not, write to the Free Software Foundation,
19+
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20+
*/
21+
package processing.app;
22+
23+
import java.io.BufferedReader;
24+
import java.io.IOException;
25+
import java.io.PrintWriter;
26+
import java.net.InetAddress;
27+
import java.net.ServerSocket;
28+
import java.net.Socket;
29+
30+
import javax.swing.SwingUtilities;
31+
32+
import processing.core.PApplet;
33+
34+
35+
/**
36+
* Class that handles a small server that prevents multiple instances of
37+
* Processing from running simultaneously. If there's already an instance
38+
* running, it'll handle opening a new empty sketch, or any files that had
39+
* been passed in on the command line.
40+
*
41+
* @author Peter Kalauskas, Ben Fry
42+
*/
43+
public class SingleInstance {
44+
static final String SERVER_PORT = "instance_server.port";
45+
static final String SERVER_KEY = "instance_server.key";
46+
47+
48+
/**
49+
* Returns true if there's an instance of Processing already running.
50+
* @param filename Path to the PDE file that was opened, null if double-clicked
51+
* @return true if successfully launched on the other instance
52+
*/
53+
static boolean exists(String[] args) {
54+
return (Preferences.get(SERVER_PORT) != null &&
55+
sendArguments(args, 5000));
56+
}
57+
58+
59+
static void createServer(final Platform platform) {
60+
try {
61+
final ServerSocket ss = new ServerSocket(0, 0, InetAddress.getByName(null));
62+
Preferences.set(SERVER_PORT, "" + ss.getLocalPort());
63+
final String key = "" + Math.random();
64+
Preferences.set(SERVER_KEY, key);
65+
Preferences.save();
66+
67+
new Thread(new Runnable() {
68+
public void run() {
69+
while (true) {
70+
try {
71+
Socket s = ss.accept(); // blocks (sleeps) until connection
72+
final BufferedReader reader = PApplet.createReader(s.getInputStream());
73+
String receivedKey = reader.readLine();
74+
75+
if (platform.base != null) {
76+
if (key.equals(receivedKey)) {
77+
SwingUtilities.invokeLater(new Runnable() {
78+
public void run() {
79+
try {
80+
String filename = reader.readLine();
81+
if (filename != null) {
82+
platform.base.handleOpen(filename);
83+
// see if there is more than one file that was passed in
84+
while ((filename = reader.readLine()) != null) {
85+
platform.base.handleOpen(filename);
86+
}
87+
} else {
88+
platform.base.handleNew();
89+
}
90+
} catch (IOException e) {
91+
e.printStackTrace();
92+
}
93+
}
94+
});
95+
}
96+
}
97+
} catch (IOException e) {
98+
e.printStackTrace();
99+
}
100+
}
101+
}
102+
}).start();
103+
104+
} catch (IOException e) {
105+
System.err.println("Could not create single instance server.");
106+
e.printStackTrace();
107+
}
108+
}
109+
110+
111+
static boolean sendArguments(String[] args, long timeout) {
112+
try {
113+
//int port = Integer.parseInt(Preferences.get("server.port"));
114+
//String key = Preferences.get("server.key");
115+
int port = Preferences.getInteger(SERVER_PORT);
116+
String key = Preferences.get(SERVER_KEY);
117+
118+
long endTime = System.currentTimeMillis() + timeout;
119+
120+
Socket socket = null;
121+
while (socket == null && System.currentTimeMillis() < endTime) {
122+
try {
123+
socket = new Socket(InetAddress.getByName(null), port);
124+
} catch (Exception ioe) {
125+
try {
126+
Thread.sleep(50);
127+
} catch (InterruptedException ie) {
128+
Thread.yield();
129+
}
130+
}
131+
}
132+
133+
if (socket != null) {
134+
PrintWriter writer = PApplet.createWriter(socket.getOutputStream());
135+
// bw.write(key + "\n");
136+
writer.println(key);
137+
for (String arg : args) {
138+
// if (filename != null) {
139+
//// bw.write(filename + "\n");
140+
// writer.println(filename);
141+
writer.println(arg);
142+
}
143+
// bw.close();
144+
writer.flush();
145+
writer.close();
146+
return true;
147+
}
148+
} catch (IOException e) {
149+
System.err.println("Error sending commands to other instance.");
150+
e.printStackTrace();
151+
}
152+
return false;
153+
}
154+
}

todo.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ X update to Java 6u29 for Linux and Windows (OS X now updated)
77
X don't show library conflict warning until someone tries to build
88
X with code that actually calls on one of those packages
99
X too many people seem to think this is an error
10+
_ work on code to quit if multiple instances are running
11+
_ need to bring the other instance to front
12+
_ and/or open a new window
1013

1114
fixed in 2.0a3
1215
X Commenting via menu or shortcut does not set sketch to "need save"
@@ -17,17 +20,20 @@ X is there a better way to handle the data folder for apps?
1720
X rather than adding it to the main zip file?
1821
X otherwise ppl are copying really large files into a jar...
1922

23+
fixed earlier
24+
A need to get GLGraphics examples out of the video examples
25+
A Examples > Video > GLGraphics
26+
X write quicktime uncompressed (w/o qtjava)
27+
X wrapped into the new moviemaker tool
28+
X http://www.randelshofer.ch/blog/2010/10/writing-quicktime-movies-in-pure-java/
29+
2030

2131
_ move Movie Maker out to its own separate tool package (with separate build)
2232
_ http://code.google.com/p/processing/issues/detail?id=837
2333

2434
_ bad tool brings down the environment
2535
_ http://code.google.com/p/processing/issues/detail?id=798
2636

27-
_ work on code to quit if multiple instances are running
28-
_ need to bring the other instance to front
29-
_ and/or open a new window
30-
3137
_ --bgcolor shouldn't be in main() unless 'present' is turned on
3238
_ also add option for FSEM or not
3339

@@ -48,9 +54,6 @@ _ http://code.google.com/p/processing/wiki/BuildInstructions
4854
_ sketch.isReadOnly returns false for examples coming from multiple modes
4955
_ http://code.google.com/p/processing/issues/detail?id=734
5056

51-
_ need to get GLGraphics examples out of the video examples
52-
_ Examples > Video > GLGraphics
53-
5457
http://support.microsoft.com/kb/184082
5558
http://msdn.microsoft.com/en-us/library/cc144175%28v=VS.85%29.aspx
5659
http://msdn.microsoft.com/en-us/library/cc144104%28v=VS.85%29.aspx
@@ -88,9 +91,6 @@ _ http://code.google.com/p/processing/issues/detail?id=713
8891
_ play button (and others) no longer highlighting
8992
_ http://code.google.com/p/processing/issues/detail?id=688
9093

91-
_ write quicktime uncompressed (w/o qtjava)
92-
_ http://www.randelshofer.ch/blog/2010/10/writing-quicktime-movies-in-pure-java/
93-
9494
frequent requests/projects
9595
_ nurbs or other architecture stuff
9696
_ force indentation - implement an option for beginners especially

0 commit comments

Comments
 (0)