/** * Copyright (C) 2009-2014 Cars and Tracks Development Project (CTDP). * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package net.ctdp.rfdynhud.gamedata; import net.ctdp.rfdynhud.editor.EditorPresets; import net.ctdp.rfdynhud.util.RFDHLog; import net.ctdp.rfdynhud.util.__UtilHelper; /** * Complete model of live game data. * * @author Marvin Froehlich (CTDP) */ public class LiveGameData { private final String gameId; private final _LiveGameDataObjectsFactory gdFactory; private final GameFileSystem fileSystem; private final GameResolution gameResolution; private boolean gamePaused = false; private boolean isInCockpit = false; private final VehiclePhysics physics; private final VehicleSetup setup; private final DrivingAids drivingAids; private final TelemetryData telemetryData; private final ScoringInfo scoringInfo; private final WeatherInfo weatherInfo; private final GraphicsInfo graphicsInfo; private final CommentaryRequestInfo commentaryInfo; private final ProfileInfo profileInfo; private final ModInfo modInfo; private final VehicleInfo vehicleInfo; private final TrackInfo trackInfo; private LiveGameDataController controller = null; public static interface GameDataUpdateListener { public void onSessionStarted( LiveGameData gameData, boolean isEditorMode ); public void onCockpitEntered( LiveGameData gameData, boolean isEditorMode ); public void onGamePauseStateChanged( LiveGameData gameData, boolean isEditorMode, boolean isPaused ); public void onCockpitExited( LiveGameData gameData, boolean isEditorMode ); } private GameDataUpdateListener[] updateListeners = null; private int[] updateListenerCounts = null; GameEventsListener[] gameEventsListeners = null; public void registerDataUpdateListener( GameDataUpdateListener l ) { if ( updateListeners == null ) { updateListeners = new GameDataUpdateListener[] { l }; updateListenerCounts = new int[] { 1 }; } else { int index = -1; for ( int i = 0; i < updateListeners.length; i++ ) { if ( updateListeners[i] == l ) { index = i; break; } } if ( index >= 0 ) { updateListenerCounts[index]++; return; } GameDataUpdateListener[] tmp = new GameDataUpdateListener[ updateListeners.length + 1 ]; System.arraycopy( updateListeners, 0, tmp, 0, updateListeners.length ); updateListeners = tmp; updateListeners[updateListeners.length - 1] = l; int[] tmp2 = new int[ updateListenerCounts.length + 1 ]; System.arraycopy( updateListenerCounts, 0, tmp2, 0, updateListenerCounts.length ); updateListenerCounts = tmp2; updateListenerCounts[updateListenerCounts.length - 1] = 1; } } public void unregisterDataUpdateListener( GameDataUpdateListener l ) { if ( updateListeners == null ) return; int index = -1; for ( int i = 0; i < updateListeners.length; i++ ) { if ( updateListeners[i] == l ) { index = i; break; } } if ( index < 0 ) return; if ( updateListenerCounts[index] > 1 ) { updateListenerCounts[index]--; return; } if ( updateListeners.length == 1 ) { updateListeners = null; updateListenerCounts = null; return; } GameDataUpdateListener[] tmp = new GameDataUpdateListener[ updateListeners.length - 1 ]; if ( index > 0 ) System.arraycopy( updateListeners, 0, tmp, 0, index ); if ( index < updateListeners.length - 1 ) System.arraycopy( updateListeners, index + 1, tmp, index, updateListeners.length - index - 1 ); updateListeners = tmp; int[] tmp2 = new int[ updateListenerCounts.length - 1 ]; if ( index > 0 ) System.arraycopy( updateListenerCounts, 0, tmp2, 0, index ); if ( index < updateListenerCounts.length - 1 ) System.arraycopy( updateListenerCounts, index + 1, tmp2, index, updateListenerCounts.length - index - 1 ); updateListenerCounts = tmp2; } public void registerGameEventsListener( GameEventsListener l ) { if ( gameEventsListeners == null ) { gameEventsListeners = new GameEventsListener[] { l }; } else { for ( int i = 0; i < gameEventsListeners.length; i++ ) { if ( gameEventsListeners[i] == l ) return; } GameEventsListener[] tmp = new GameEventsListener[ gameEventsListeners.length + 1 ]; System.arraycopy( gameEventsListeners, 0, tmp, 0, gameEventsListeners.length ); gameEventsListeners = tmp; gameEventsListeners[gameEventsListeners.length - 1] = l; } } public void unregisterGameEventsListener( GameEventsListener l ) { if ( gameEventsListeners == null ) return; int index = -1; for ( int i = 0; i < gameEventsListeners.length; i++ ) { if ( gameEventsListeners[i] == l ) { index = i; break; } } if ( index < 0 ) return; if ( gameEventsListeners.length == 1 ) { gameEventsListeners = null; return; } GameEventsListener[] tmp = new GameEventsListener[ gameEventsListeners.length - 1 ]; if ( index > 0 ) System.arraycopy( gameEventsListeners, 0, tmp, 0, index ); if ( index < gameEventsListeners.length - 1 ) System.arraycopy( gameEventsListeners, index + 1, tmp, index, gameEventsListeners.length - index - 1 ); gameEventsListeners = tmp; } public final String getGameID() { return ( gameId ); } final _LiveGameDataObjectsFactory getGameDataObjectsFactory() { return ( gdFactory ); } public final GameFileSystem getFileSystem() { return ( fileSystem ); } /** * Gets game resolution and viewport information. * * @return game resolution and viewport information. */ public final GameResolution getGameResolution() { return ( gameResolution ); } /** * Sets the controller. * * @param controller */ public void setLiveGameDataController( LiveGameDataController controller ) { this.controller = controller; } /** * Gets the controller. * * @return the controller. */ public final LiveGameDataController getLiveGameDataController() { return ( controller ); } void setGamePaused( boolean paused, boolean isEditorMode ) { if ( paused == this.gamePaused ) return; this.gamePaused = paused; if ( updateListeners != null ) { for ( int i = 0; i < updateListeners.length; i++ ) { try { updateListeners[i].onGamePauseStateChanged( this, isEditorMode, paused ); } catch ( Throwable t ) { RFDHLog.exception( t ); } } } } /** * Gets whether the game is paused. Since rFactor1 doesn't tell its plugins about the paused state, * this can only be a guess based on the last TelemetryData update. So this info can be up to some splitss of a second late. * * @return whether the game is paused. */ public final boolean isGamePaused() { return ( gamePaused ); } /** * * @param timestamp * @param isEditorMode */ void onSessionStarted2( long timestamp, boolean isEditorMode ) { if ( updateListeners != null ) { for ( int i = 0; i < updateListeners.length; i++ ) { try { updateListeners[i].onSessionStarted( this, isEditorMode ); } catch ( Throwable t ) { RFDHLog.exception( t ); } } } } void setInCockpit( boolean isInCockpit, long timestamp, boolean isEditorMode ) { boolean was = this.isInCockpit; this.isInCockpit = isInCockpit; if ( !was && isInCockpit ) { if ( updateListeners != null ) { for ( int i = 0; i < updateListeners.length; i++ ) { try { updateListeners[i].onCockpitEntered( this, isEditorMode ); } catch ( Throwable t ) { RFDHLog.exception( t ); } } } getTelemetryData().onCockpitEntered( timestamp ); getScoringInfo().onCockpitEntered( timestamp ); getWeatherInfo().onCockpitEntered( timestamp ); getSetup().onCockpitEntered( timestamp ); } else if ( was && !isInCockpit ) { if ( updateListeners != null ) { for ( int i = 0; i < updateListeners.length; i++ ) { try { updateListeners[i].onCockpitExited( this, isEditorMode ); } catch ( Throwable t ) { RFDHLog.exception( t ); } } } getTelemetryData().onCockpitExited( timestamp ); getScoringInfo().onCockpitExited( timestamp ); getWeatherInfo().onCockpitExited( timestamp ); getSetup().onCockpitExited( timestamp ); } } /** * Gets whether we're in the cockpit. * * @return whether we're in the cockpit. */ public final boolean isInCockpit() { return ( isInCockpit ); } /** * Gets whether we're in realtime mode (cockpit). * * @return whether we're in realtime mode (cockpit). * * @deprecated replaced by {@link #isInCockpit()} */ @Deprecated public final boolean isInRealtimeMode() { return ( isInCockpit() ); } /** * Gets the vehicle physics model. * * @return the vehicle physics model. */ public final VehiclePhysics getPhysics() { return ( physics ); } /** * Gets the vehicle setup model. * * @return the vehicle setup model. */ public final VehicleSetup getSetup() { return ( setup ); } public final DrivingAids getDrivingAids() { return ( drivingAids ); } /** * Gets the telemetry data. * * @return the telemetry data. */ public final TelemetryData getTelemetryData() { return ( telemetryData ); } /** * Gets the scoring info. * * @return the scoring info. */ public final ScoringInfo getScoringInfo() { return ( scoringInfo ); } /** * Gets the weather info. * * @return the weather info. */ public final WeatherInfo getWeatherInfo() { return ( weatherInfo ); } /** * Gets the graphics info. * * @return the graphics info. */ public final GraphicsInfo getGraphicsInfo() { return ( graphicsInfo ); } /** * Gets the commentary request info. * * @return the commentary request info. */ public final CommentaryRequestInfo getCommentaryRequestInfo() { return ( commentaryInfo ); } /** * Gets the mod info. * * @return the mod info. */ public final ModInfo getModInfo() { return ( modInfo ); } /** * Gets the vehicle info. * * @return the vehicle info. */ public final VehicleInfo getVehicleInfo() { return ( vehicleInfo ); } /** * Gets the profile info. * * @return the profile info. */ public final ProfileInfo getProfileInfo() { return ( profileInfo ); } /** * Gets the track info. * * @return the track info. */ public final TrackInfo getTrackInfo() { return ( trackInfo ); } void applyEditorPresets( EditorPresets editorPresets ) { drivingAids.applyEditorPresets( editorPresets ); graphicsInfo.applyEditorPresets( editorPresets ); telemetryData.applyEditorPresets( editorPresets ); scoringInfo.applyEditorPresets( editorPresets ); weatherInfo.applyEditorPresets( editorPresets ); commentaryInfo.applyEditorPresets( editorPresets ); setup.applyEditorPresets( editorPresets ); } /** * Creates an instance of LiveGameData. * * @param eventsManager * @param gdFactory */ public LiveGameData( GameEventsManager eventsManager, _LiveGameDataObjectsFactory gdFactory ) { registerDataUpdateListener( DataCache.INSTANCE ); this.gameId = gdFactory.getGameId(); this.gdFactory = gdFactory; this.fileSystem = gdFactory.newGameFileSystem( __UtilHelper.PLUGIN_INI ); this.gameResolution = ( eventsManager == null ) ? null : eventsManager.getWidgetsManager().getWidgetsConfiguration().getGameResolution(); this.physics = gdFactory.newVehiclePhysics( this ); this.setup = gdFactory.newVehicleSetup( this ); this.drivingAids = gdFactory.newDrivingAids( this ); this.telemetryData = gdFactory.newTelemetryData( this ); this.scoringInfo = gdFactory.newScoringInfo( this ); this.weatherInfo = gdFactory.newWeatherInfo( this ); this.graphicsInfo = gdFactory.newGraphicsInfo( this ); this.commentaryInfo = gdFactory.newCommentaryRequestInfo( this ); this.profileInfo = gdFactory.newProfileInfo( this ); this.modInfo = gdFactory.newModInfo( this ); this.vehicleInfo = gdFactory.newVehicleInfo( this ); this.trackInfo = gdFactory.newTrackInfo( this ); gdFactory.loadVehicleSetupDefaults( this ); } }