View Javadoc

1   /*
2    * MBigPipe.java 
3    * Created on 11 nov. 2003
4    * 
5    *   Magic-Project is a turn based strategy simulator
6    *   Copyright (C) 2003-2007 Fabrice Daugan
7    *
8    *   This program is free software; you can redistribute it and/or modify it 
9    * under the terms of the GNU General Public License as published by the Free 
10   * Software Foundation; either version 2 of the License, or (at your option) any
11   * later version.
12   *
13   *   This program is distributed in the hope that it will be useful, but WITHOUT 
14   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15   * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
16   * details.
17   *
18   *   You should have received a copy of the GNU General Public License along  
19   * with this program; if not, write to the Free Software Foundation, Inc., 
20   * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21   */
22  package net.sf.magicproject.network;
23  
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  import java.io.PrintWriter;
28  
29  /***
30   * @author <a href="mailto:fabdouglas@users.sourceforge.net">Fabrice Daugan </a>
31   * @since 0.3
32   */
33  public class MBigPipe extends Thread implements IdMessages {
34  
35  	MBigPipe(InputStream mainIn, OutputStream mainOut, MChat chat) {
36  		this.mainIn = mainIn;
37  		this.mainOut = mainOut;
38  		this.chat = chat;
39  		MSocketListener.init();
40  		ready = new MMiniPipe();
41  		ready.take();
42  		pipeOut = new MMiniPipe();
43  		pipeInSync = new MMiniPipe();
44  		pipeInSync.take();
45  		instance = this;
46  	}
47  
48  	/***
49  	 * Semaphore to indicate a ready stream
50  	 */
51  	public MMiniPipe ready;
52  
53  	/***
54  	 * send a byte sized message to opponent. This message si not displayed in the
55  	 * chat window, but is destined to play triggers.
56  	 * 
57  	 * @param msg
58  	 *          is the message to send
59  	 */
60  	public void sendGameMessage(int... msg) {
61  		pipeOut.take();
62  		try {
63  			synchronized (LOCK) {
64  				mainOut.write(BEGIN_GAME_DATA);
65  				mainOut.write(msg.length);
66  				for (int i : msg) {
67  					mainOut.write(i);
68  				}
69  				mainOut.flush();
70  			}
71  		} catch (IOException e) {
72  			ConnectionManager.notifyDisconnection();
73  			ConnectionManager.closeConnexions();
74  			throw new InternalError("disconnected in sendGameMessage");
75  		} finally {
76  			pipeOut.release();
77  		}
78  	}
79  
80  	/***
81  	 * send a STRING message to opponent. This message will be displayed in the
82  	 * chat window.
83  	 * 
84  	 * @param msg
85  	 *          is the message to send
86  	 */
87  	public void sendChatMessage(String msg) {
88  		pipeOut.take();
89  		try {
90  			synchronized (LOCK) {
91  				mainOut.write(BEGIN_MESSAGE_DATA);
92  				mainOut.flush();
93  				PrintWriter printer = new PrintWriter(mainOut);
94  				printer.println(msg);
95  				printer.flush();
96  			}
97  		} catch (IOException e) {
98  			throw new InternalError("disconnected in sendChatMessage");
99  		} finally {
100 			pipeOut.release();
101 		}
102 	}
103 
104 	/***
105 	 * The main loop allowing to mix 2 data types : the first is the data
106 	 * corresponding to player's action, and the second is the message of chat
107 	 * speaking.
108 	 * 
109 	 * @see IdMessages#BEGIN_GAME_DATA
110 	 * @see IdMessages#BEGIN_MESSAGE_DATA
111 	 */
112 	@Override
113 	public void run() {
114 		try {
115 			while (true) {
116 				int idHead = mainIn.read();
117 				switch (idHead) {
118 				case BEGIN_GAME_DATA:
119 					MSocketListener.getInstance().newMessage(mainIn);
120 					break;
121 				case BEGIN_MESSAGE_DATA:
122 					chat.newMessage(mainIn);
123 					break;
124 				default:
125 					ConnectionManager.notifyDisconnection();
126 					// déconnection
127 					ConnectionManager.closeConnexions();
128 					MSocketListener.getInstance().newMessage(mainIn);
129 					System.out.println(" **disconnected **");
130 					return;
131 				}
132 			}
133 		} catch (IOException e) {
134 			System.out.println(" **disconnected **");
135 			ConnectionManager.notifyDisconnection();
136 			// déconnection
137 			ConnectionManager.closeConnexions();
138 			return;
139 		}
140 	}
141 
142 	/***
143 	 * monitors
144 	 */
145 	private MMiniPipe pipeOut;
146 
147 	private MMiniPipe pipeInSync;
148 
149 	/***
150 	 * Token to split stream for play message and chat message
151 	 */
152 	public static final Object LOCK = new Object();
153 
154 	private MChat chat;
155 
156 	/***
157 	 * main input stream
158 	 */
159 	private InputStream mainIn;
160 
161 	/***
162 	 * main output stream
163 	 */
164 	private OutputStream mainOut;
165 
166 	/***
167 	 * The unique instance
168 	 */
169 	public static MBigPipe instance;
170 }