Coverage report

  %line %branch
tsukuba_bunko.peko.PekoSystem
0% 
0% 

 1  
 /*
 2  
  * All Rights Reserved.
 3  
  * Copyright (C) 1999-2005 Tsukuba Bunko.
 4  
  *
 5  
  * Licensed under the BSD License ("the License"); you may not use
 6  
  * this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *       http://www.tsukuba-bunko.org/licenses/LICENSE.txt
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  *
 17  
  * $Id: PekoSystem.java,v 1.5 2005/11/23 05:41:43 ppoi Exp $
 18  
  */
 19  
 package tsukuba_bunko.peko;
 20  
 
 21  
 import java.awt.Point;
 22  
 
 23  
 import java.awt.event.WindowEvent;
 24  
 import java.awt.event.WindowAdapter;
 25  
 
 26  
 import java.io.BufferedReader;
 27  
 import java.io.IOException;
 28  
 import java.io.InputStream;
 29  
 import java.io.InputStreamReader;
 30  
 
 31  
 import java.net.URL;
 32  
 
 33  
 import java.util.List;
 34  
 
 35  
 import javax.swing.Icon;
 36  
 import javax.swing.ImageIcon;
 37  
 import javax.swing.JFrame;
 38  
 import javax.swing.JOptionPane;
 39  
 
 40  
 import tsukuba_bunko.peko.canvas.CanvasManager;
 41  
 
 42  
 import tsukuba_bunko.peko.resource.ResourceManager;
 43  
 
 44  
 import tsukuba_bunko.peko.scenario.ScenarioProcessor;
 45  
 
 46  
 import tsukuba_bunko.peko.session.Session;
 47  
 import tsukuba_bunko.peko.session.SessionManager;
 48  
 
 49  
 
 50  
 /**
 51  
  * "Peko" Visual Novel System のメインクラスです。
 52  
  * @author	$Author: ppoi $
 53  
  * @version	$Revision: 1.5 $
 54  
  */
 55  0
 public class PekoSystem	{
 56  
 
 57  
 	/**
 58  
 	 * 唯一の <code>PekoSystem</code> のインスタンス
 59  
 	 */
 60  0
 	private static PekoSystem	_instance = null;
 61  
 
 62  
 
 63  
 	/**
 64  
 	 * <code>PekoSysmtem</code> のバージョン情報
 65  
 	 */
 66  0
 	private Object[]	_versionInfo = null;
 67  
 
 68  
 	/**
 69  
 	 * メインウィンドウ
 70  
 	 */
 71  0
 	private JFrame	_mainWindow = null;
 72  
 
 73  
 	/**
 74  
 	 * CanvasManager
 75  
 	 */
 76  0
 	private CanvasManager	_canvasManager = null;
 77  
 
 78  
 	/**
 79  
 	 * ScenrioProcessor
 80  
 	 */
 81  0
 	private ScenarioProcessor	_scenarioProcessor = null;
 82  
 
 83  
 	/**
 84  
 	 * SessionManager
 85  
 	 */
 86  0
 	private SessionManager	_sessionManager = null;
 87  
 
 88  
 	/**
 89  
 	 * ActionControler
 90  
 	 */
 91  0
 	private ActionControler	_actionControler = null;
 92  
 
 93  
 	/**
 94  
 	 * スタートフラグ
 95  
 	 */
 96  0
 	private boolean	_started = false;
 97  
 
 98  
 
 99  
 	/**
 100  
 	 * <code>PekoSystem</code> のインスタンスを作成します。
 101  
 	 */
 102  
 	protected PekoSystem()
 103  
 	{
 104  0
 		super();
 105  0
 	}
 106  
 
 107  
 
 108  
 	/**
 109  
 	 * PVNS を開始します。
 110  
 	 */
 111  
 	public void start()
 112  
 	{
 113  0
 		if( _started )	{
 114  0
 			return;
 115  
 		}
 116  
 
 117  0
 		Point	location = (Point)_sessionManager.getSystemSaveData().getEntry( "windowLocation" );
 118  0
 		if( location != null )	{
 119  0
 			_mainWindow.setLocation( location );
 120  0
 		}
 121  
 		else	{
 122  0
 			_mainWindow.setLocationRelativeTo( null );
 123  
 		}
 124  
 
 125  0
 		_mainWindow.setVisible( true );
 126  0
 		synchronized( _mainWindow )	{
 127  
 			try	{
 128  0
 				if( !_mainWindow.isShowing() )	{
 129  0
 					_mainWindow.wait();
 130  0
 					Logger.debug( "[system] window opened." );
 131  
 				}
 132  
 			}
 133  0
 			catch( InterruptedException ie )	{
 134  0
 				Logger.debug( "[system] interrupted in waiting for opening window." );
 135  0
 			}
 136  0
 		}
 137  0
 		_actionControler.returnTitle( true );
 138  0
 	}
 139  
 
 140  
 	/**
 141  
 	 * PVNS を終了します。
 142  
 	 */
 143  
 	public void exit()
 144  
 	{
 145  0
 		boolean	last = _actionControler.isActive();
 146  0
 		_actionControler.setActive( false );
 147  0
 		ResourceManager	resources = ResourceManager.getInstance();
 148  0
 		String	title = (String)resources.getResource( "peko.dialog.exit.title" );
 149  0
 		String	message = (String)resources.getResource( "peko.dialog.exit.message" );
 150  0
 		if( JOptionPane.OK_OPTION != JOptionPane.showConfirmDialog(_mainWindow, message, title, JOptionPane.OK_CANCEL_OPTION) )	{
 151  0
 			_actionControler.setActive( last );
 152  0
 			return;
 153  
 		}
 154  0
 		_mainWindow.dispose();
 155  
 
 156  
 		try	{
 157  0
 			_sessionManager.getSystemSaveData().addEntry( "windowLocation", _mainWindow.getLocation() );
 158  0
 			_sessionManager.saveSystemSaveData();
 159  
 		}
 160  0
 		catch( Exception e )	{
 161  0
 			Logger.error( MessageIDs.SYS6001E );
 162  0
 		}
 163  
 
 164  0
 		Logger.info( "Bye!" );
 165  0
 		System.exit( 0 );
 166  0
 	}
 167  
 
 168  
 	/**
 169  
 	 * タイトル画面画像を表示します。
 170  
 	 */
 171  
 	public void showTitle()
 172  
 	{
 173  
 		try	{
 174  0
 			if( _started )	{
 175  0
 				_scenarioProcessor.exit();
 176  0
 				_canvasManager.clearAll();
 177  0
 			}
 178  
 			else	{
 179  0
 				_canvasManager.getStageCanvas().setUsingEffect( false );
 180  0
 				_canvasManager.clearAll();
 181  0
 				_canvasManager.getStageCanvas().setUsingEffect( true );
 182  0
 				_started = true;
 183  
 			}
 184  0
 			gc();
 185  
 
 186  0
 			_mainWindow.setTitle( (String)ResourceManager.getInstance().getResource("game-info.title") );
 187  0
 			boolean	first = true;
 188  
 			while( true )	{
 189  0
 				String	id = _canvasManager.showTitle( first );
 190  0
 				if( id == null )	{
 191  0
 					Logger.debug( "[system] canceled." );
 192  0
 					break;
 193  
 				}
 194  0
 				else if( "start".equals(id) )	{
 195  0
 					ResourceManager	resources = ResourceManager.getInstance();
 196  0
 					String	startPage = (String)resources.getResource( "peko.system.start-scene" );
 197  0
 					if( startPage == null )	{
 198  0
 						Logger.fatal( "[system] not specified scenario.start-scene." );
 199  0
 						throw new InitializationError( "[system] not specified scenario.start-scene." );
 200  
 					}
 201  
 					else	{
 202  0
 						_canvasManager.clearAll();
 203  0
 						_sessionManager.initializeSession();
 204  0
 						gc();
 205  0
 						_scenarioProcessor.playScenario( startPage, _sessionManager.getSession() );
 206  
 					}
 207  0
 					break;
 208  
 				}
 209  0
 				else if( "resume".equals(id) )	{
 210  0
 					if( load() )	{
 211  0
 						break;
 212  
 					}
 213  
 				}
 214  0
 				else if( "exit".equals(id) )	{
 215  0
 					exit();
 216  
 				}
 217  0
 				first = false;
 218  0
 			}
 219  
 		}
 220  0
 		catch( Exception e )	{
 221  0
 			Logger.fatal( "[system] fatal error occured during saving states.", e );
 222  0
 			JOptionPane.showMessageDialog( _mainWindow, "ERROR!", "Error!", JOptionPane.ERROR_MESSAGE );
 223  0
 		}
 224  0
 	}
 225  
 
 226  
 	/**
 227  
 	 * セーブします。
 228  
 	 */
 229  
 	public void save()
 230  
 	{
 231  
 		try	{
 232  0
 			Session	session = _sessionManager.getSession();
 233  0
 			_canvasManager.saveState( session );
 234  0
 			_sessionManager.saveCurrentSession();
 235  
 		}
 236  0
 		catch( Exception e )	{
 237  0
 			Logger.fatal( "[system] fatal error occured during saving states.", e );
 238  0
 			JOptionPane.showMessageDialog( _mainWindow, "[system] fatal error occured during saving states.", "Error!", JOptionPane.ERROR_MESSAGE );
 239  0
 			return;
 240  0
 		}
 241  
 
 242  
 		try	{
 243  0
 			_sessionManager.saveSystemSaveData();
 244  
 		}
 245  0
 		catch( Exception e )	{
 246  0
 			Logger.fatal( "[system] fatal error occured during saving states.", e );
 247  0
 			PekoSystem.showErrorDialog( "A fatal error occured during saving states", e, true );
 248  0
 		}
 249  0
 	}
 250  
 
 251  
 	/**
 252  
 	 * ロードします。
 253  
 	 */
 254  
 	public boolean load()
 255  
 	{
 256  0
 		boolean	result = false;
 257  
 		try	{
 258  0
 			_actionControler.setPlayModeToNormal();
 259  0
 			if( _sessionManager.load() )	{
 260  0
 				_scenarioProcessor.exit();
 261  0
 				_canvasManager.clearAll();
 262  0
 				gc();
 263  
 
 264  0
 				Session	session = _sessionManager.getSession();
 265  0
 				_mainWindow.setTitle( session.getSceneContext().getSceneTitle() + " - " + ResourceManager.getInstance().getResource("game-info.title") );
 266  0
 				_canvasManager.resume( session );
 267  0
 				gc();
 268  0
 				_scenarioProcessor.playScenario( session.getSceneContext().getSceneName(), session );
 269  0
 				result = true;
 270  0
 			}
 271  
 			else	{
 272  0
 				result = false;
 273  
 			}
 274  
 		}
 275  0
 		catch( Exception e )	{
 276  0
 			Logger.fatal( "[system] fatal error occured during saving states.", e );
 277  0
 			JOptionPane.showMessageDialog( _mainWindow, "[system] fatal error occured during saving states.", "Error!", JOptionPane.ERROR_MESSAGE );
 278  0
 		}
 279  0
 		return result;
 280  
 	}
 281  
 
 282  
 	/**
 283  
 	 * システムのバージョン情報ダイアログを表示します。
 284  
 	 */
 285  
 	public void showSystemVersionInfo()
 286  
 	{
 287  0
 		ImageIcon	icon = null;
 288  0
 		URL	iconURL = getClass().getClassLoader().getResource( "pvns-logo.gif" );
 289  0
 		if( iconURL != null )	{
 290  0
 			icon = new ImageIcon( iconURL, "PVNS Logo" );
 291  
 		}
 292  0
 		JOptionPane.showMessageDialog( _mainWindow, _versionInfo, (String)_versionInfo[0], JOptionPane.INFORMATION_MESSAGE, icon );
 293  0
 	}
 294  
 
 295  
 	/**
 296  
 	 * ゲームのバージョン情報ダイアログを表示します。
 297  
 	 */
 298  
 	public void showGameVersionInfo()
 299  
 	{
 300  0
 		ResourceManager	resources = ResourceManager.getInstance();
 301  
 
 302  0
 		Icon	icon = (Icon)resources.getResource( "game-info.logo", true );
 303  0
 		List	texts = new java.util.ArrayList();
 304  0
 		String[]	props = { "game-info.title", "game-info.version", "game-info.publisher", "game-info.copyright" };
 305  0
 		for( int i = 0; i < props.length; ++i )	{
 306  0
 			String	var = (String)resources.getResource( props[i], true );
 307  0
 			if( var != null )	{
 308  0
 				texts.add( var );
 309  
 			}
 310  
 		}
 311  
 
 312  0
 		List	additionalInfo = (List)resources.getResource( "game-info.additional-info", true );
 313  0
 		if( (additionalInfo != null) && !additionalInfo.isEmpty() )	{
 314  0
 			if( !texts.isEmpty() )	{
 315  0
 				texts.add( " " );
 316  
 			}
 317  0
 			texts.addAll( additionalInfo );
 318  
 		}
 319  
 
 320  0
 		if( !texts.isEmpty() )	{
 321  0
 			JOptionPane.showMessageDialog( _mainWindow, texts.toArray(), (String)resources.getResource("game-info.title"), JOptionPane.INFORMATION_MESSAGE, icon );
 322  
 		}
 323  0
 	}
 324  
 
 325  
 	/**
 326  
 	 * PVNS のバージョン情報を取得します.
 327  
 	 * @return	バージョン情報
 328  
 	 */
 329  
 	public Object[] getPekoSystemVersion()
 330  
 	{
 331  0
 		return _versionInfo;
 332  
 	}
 333  
 
 334  
 	/**
 335  
 	 * メインウィンドウを取得します。
 336  
 	 * @return	メインウィンドウ
 337  
 	 */
 338  
 	public JFrame getMainWindow()
 339  
 	{
 340  0
 		return _mainWindow;
 341  
 	}
 342  
 
 343  
 	/**
 344  
 	 * CanvasManager を取得します。
 345  
 	 * @return	CanvasManager
 346  
 	 */
 347  
 	public CanvasManager getCanvasManager()
 348  
 	{
 349  0
 		return _canvasManager;
 350  
 	}
 351  
 
 352  
 	/**
 353  
 	 * ActionControler を取得します。
 354  
 	 * @return	ActionControler
 355  
 	 */
 356  
 	public ActionControler getActionControler()
 357  
 	{
 358  0
 		return _actionControler;
 359  
 	}
 360  
 
 361  
 
 362  
 	/**
 363  
 	 * "Peko" のバージョン情報を準備します。
 364  
 	 */
 365  
 	private void prepareVersionInfo()
 366  
 	{
 367  
 		try	{
 368  0
 			InputStream	is = PekoSystem.class.getResourceAsStream( "version.txt" );
 369  0
 			if( is != null )	{
 370  0
 				BufferedReader	reader = new BufferedReader( class="keyword">new InputStreamReader(is, "Shift_JIS") );
 371  0
 				String	line = reader.readLine();
 372  0
 				List	lines = new java.util.ArrayList();
 373  0
 				while( line != null )	{
 374  0
 					lines.add( line );
 375  0
 					line = reader.readLine();
 376  0
 				}
 377  0
 				reader.close();
 378  0
 				is.close();
 379  0
 				_versionInfo = lines.toArray();
 380  0
 			}
 381  
 			else	{
 382  0
 				Logger.error( "[system] missing version.txt." );
 383  0
 				Logger.debug( "[system] using embeded version info." );
 384  0
 				_versionInfo = new Object[]{ "\"Peko\" Visual Novel System", "version 1.0", "All Rights Reserved.", "(c)Copyright by Tsukuba Bunko." };
 385  
 			}
 386  
 		}
 387  0
 		catch( IOException ioe )	{
 388  0
 			Logger.error( "[system] fail to read version info.", ioe );
 389  0
 			Logger.debug( "[system] using embeded version info." );
 390  0
 			_versionInfo = new Object[]{ "\"Peko\" Visual Novel System", "version 1.0", "All Rights Reserved.", "(c)Copyright by Tsukuba Bunko." };
 391  0
 		}
 392  0
 	}
 393  
 
 394  
 	/**
 395  
 	 * メインウィンドウを準備します。
 396  
 	 */
 397  
 	private void prepareMainWindow()
 398  
 	{
 399  0
 		JFrame	window = new JFrame( (String)_versionInfo[0] );
 400  0
 		_mainWindow = window;
 401  
 
 402  0
 		window.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
 403  0
 		window.addWindowListener( new WindowAdapter()	{
 404  
 				public void windowOpened( WindowEvent ev )
 405  
 				{
 406  
 					synchronized( _mainWindow )	{
 407  
 						_mainWindow.notify();
 408  
 					}
 409  
 				}
 410  
 				public void windowClosing( WindowEvent ev )
 411  
 				{
 412  
 					exit();
 413  
 				}
 414  
 			});
 415  0
 	}
 416  
 
 417  
 	/**
 418  
 	 * ResourceManager を初期化します.
 419  
 	 * @throws	InitializationError	初期化に失敗した場合
 420  
 	 */
 421  
 	private void prepareResources()
 422  
 	{
 423  
 		try	{
 424  0
 			ResourceManager.getInstance();
 425  
 		}
 426  0
 		catch( Exception e )	{
 427  0
 			throw new InitializationError();
 428  0
 		}
 429  0
 	}
 430  
 
 431  
 	/**
 432  
 	 * CanvasManager を初期化します。
 433  
 	 */
 434  
 	private void prepareCanvasManager()
 435  
 	{
 436  0
 		_canvasManager = new CanvasManager();
 437  0
 		_canvasManager.initialize();
 438  0
 	}
 439  
 
 440  
 	/**
 441  
 	 * ScenarioProcessor を準備します。
 442  
 	 */
 443  
 	private void prepareScenarioProcessor()
 444  
 	{
 445  0
 		_scenarioProcessor = new ScenarioProcessor();
 446  0
 	}
 447  
 
 448  
 	/**
 449  
 	 * SessionManager を準備します。
 450  
 	 */
 451  
 	private void prepareSessionManager()
 452  
 	{
 453  0
 		_sessionManager = new SessionManager();
 454  0
 	}
 455  
 
 456  
 	/**
 457  
 	 * ActionControler を準備します。
 458  
 	 */
 459  
 	private void prepareActionControler()
 460  
 	{
 461  0
 		ActionControler	controler = new ActionControler();
 462  0
 		_canvasManager.getTextCanvas().addMouseListener( controler );
 463  0
 		_canvasManager.getStageCanvas().addMouseListener( controler );
 464  0
 		_mainWindow.addKeyListener( controler );
 465  0
 		_actionControler = controler;
 466  0
 	}
 467  
 
 468  
 	/**
 469  
 	 * 強制的にガベッジコレクタを起動します。
 470  
 	 */
 471  
 	private void gc()
 472  
 	{
 473  0
 		Runtime	runtime = Runtime.getRuntime();
 474  0
 		long	before = runtime.freeMemory();
 475  
 
 476  0
 		System.runFinalization();
 477  0
 		System.gc();
 478  
 
 479  0
 		long	after = runtime.freeMemory();
 480  0
 		Logger.debug( "[system] run gc. before=" + before + ", after=" + after );
 481  0
 	}
 482  
 
 483  
 	/**
 484  
 	 * 唯一の <code>PekoSystem</code> のインスタンスを取得します.
 485  
 	 * @return	唯一の <code>PekoSystem</code> のインスタンス
 486  
 	 */
 487  
 	public static PekoSystem getInstance()
 488  
 	{
 489  0
 		if( _instance == null )	{
 490  0
 			synchronized( PekoSystem.class )	{
 491  0
 				if( _instance == null )	{
 492  0
 					_instance = new PekoSystem();
 493  0
 					_instance.prepareVersionInfo();
 494  0
 					_instance.prepareResources();
 495  0
 					_instance.prepareSessionManager();
 496  0
 					_instance.prepareMainWindow();
 497  0
 					_instance.prepareCanvasManager();
 498  0
 					_instance.prepareActionControler();
 499  0
 					_instance.prepareScenarioProcessor();
 500  
 				}
 501  0
 			}
 502  
 		}
 503  0
 		return _instance;
 504  
 	}
 505  
 
 506  
 	/**
 507  
 	 * エラーダイアログを表示します。
 508  
 	 * @param	message	エラーメッセージ
 509  
 	 * @param	e	例外オブジェクト
 510  
 	 * @param	exit	強制終了する場合 <code>true</code>、しない場合 <code>false</code>
 511  
 	 */
 512  
 	public static void showErrorDialog( String message, Throwable e, boolean exit )
 513  
 	{
 514  0
 		if( message == null )	{
 515  0
 			message = e.getMessage();
 516  
 		}
 517  
 
 518  0
 		StackTraceElement[]	stackTrace = e.getStackTrace();
 519  0
 		Object[]	messages = new Object[ stackTrace.length + 2 ];
 520  0
 		for( int i = 0; i < stackTrace.length; ++i )	{
 521  0
 			messages[i + 1] = stackTrace[i];
 522  
 		}
 523  0
 		messages[0] = "Fatal Error :" + message;
 524  0
 		messages[1] = e.getClass().getName() + " : " + e.getMessage();
 525  0
 		JOptionPane.showMessageDialog( null, messages, "FATAL ERROR ! -\"Peko\" Visual Novel System", JOptionPane.ERROR_MESSAGE );
 526  0
 		if( exit )	{
 527  0
 			System.exit( -1 );
 528  
 		}
 529  0
 	}
 530  
 
 531  
 
 532  
 	/**
 533  
 	 * "Peko" Visual Novel System を起動します。
 534  
 	 */
 535  
 	public static void main( String[] args )
 536  
 		throws Exception
 537  
 	{
 538  0
 		Logger.prepare();
 539  
 		try	{
 540  0
 			PekoSystem	system = PekoSystem.getInstance();
 541  0
 			Object[]	versionInfo = system.getPekoSystemVersion();
 542  0
 			Logger.info( (String)versionInfo[0] );
 543  0
 			Logger.info( (String)versionInfo[1] );
 544  
 
 545  0
 			system.start();
 546  
 		}
 547  0
 		catch( Throwable e )	{
 548  0
 			showErrorDialog( null, e, true );
 549  0
 		}
 550  0
 	}
 551  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.