/** * 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 java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import net.ctdp.rfdynhud.editor.EditorPresets; import net.ctdp.rfdynhud.util.RFDHLog; /** * * @author Marvin Froehlich (CTDP) */ public abstract class CommentaryRequestInfo { private long updateTimestamp = -1L; private long updateId = 0L; private boolean updatedInTimeScope = false; protected final LiveGameData gameData; public static interface CommentaryInfoUpdateListener extends LiveGameData.GameDataUpdateListener { public void onCommentaryInfoUpdated( LiveGameData gameData, boolean isEditorMode ); } private CommentaryInfoUpdateListener[] updateListeners = null; public void registerListener( CommentaryInfoUpdateListener l ) { if ( updateListeners == null ) { updateListeners = new CommentaryInfoUpdateListener[] { l }; } else { for ( int i = 0; i < updateListeners.length; i++ ) { if ( updateListeners[i] == l ) return; } CommentaryInfoUpdateListener[] tmp = new CommentaryInfoUpdateListener[ updateListeners.length + 1 ]; System.arraycopy( updateListeners, 0, tmp, 0, updateListeners.length ); updateListeners = tmp; updateListeners[updateListeners.length - 1] = l; } gameData.registerDataUpdateListener( l ); } public void unregisterListener( CommentaryInfoUpdateListener 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 ( updateListeners.length == 1 ) { updateListeners = null; return; } CommentaryInfoUpdateListener[] tmp = new CommentaryInfoUpdateListener[ 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; gameData.unregisterDataUpdateListener( l ); } public abstract void readFromStream( InputStream in, EditorPresets editorPresets ) throws IOException; /** * Read default values. This is usually done in editor mode. * * @param editorPresets <code>null</code> in non editor mode */ public abstract void loadDefaultValues( EditorPresets editorPresets ); public abstract void writeToStream( OutputStream out ) throws IOException; /** * Gets the system nano time for the last data update. * * @return the system nano time for the last data update. */ public final long getUpdateTimestamp() { return ( updateTimestamp ); } /** * This is incremented every time the info is updated. * * @return the current update id. */ public final long getUpdateId() { return ( updateId ); } /** * Gets, whether these {@link CommentaryRequestInfo} have at least been updated once. * * @return whether these {@link CommentaryRequestInfo} have at least been updated once. */ public final boolean isValid() { return ( updateId > 0L ); } /** * Gets, whether the last update of these data has been done while in the cockpit. * @return whether the last update of these data has been done while in the cockpit. */ public final boolean isUpdatedInTimeScope() { return ( updatedInTimeScope ); } /** * * @param userObject * @param timestamp */ protected void prepareDataUpdate( Object userObject, long timestamp ) { } /** * @param userObject (could be an instance of {@link EditorPresets}), if in editor mode * @param timestamp */ protected void onDataUpdatedImpl( Object userObject, long timestamp ) { } /** * @param userObject (could be an instance of {@link EditorPresets}), if in editor mode * @param timestamp */ protected final void onDataUpdated( Object userObject, long timestamp ) { this.updatedInTimeScope = gameData.isInCockpit(); this.updateTimestamp = timestamp; this.updateId++; if ( userObject instanceof EditorPresets ) applyEditorPresets( (EditorPresets)userObject ); if ( updateListeners != null ) { for ( int i = 0; i < updateListeners.length; i++ ) { try { updateListeners[i].onCommentaryInfoUpdated( gameData, userObject instanceof EditorPresets ); } catch ( Throwable t ) { RFDHLog.exception( t ); } } } try { onDataUpdatedImpl( userObject, timestamp ); } catch ( Throwable t ) { RFDHLog.exception( t ); } } protected abstract void updateDataImpl( Object userObject, long timestamp ); protected void applyEditorPresets( EditorPresets editorPresets ) { if ( editorPresets == null ) return; } protected void updateData( Object userObject, long timestamp ) { prepareDataUpdate( userObject, timestamp ); updateDataImpl( userObject, timestamp ); onDataUpdated( userObject, timestamp ); } /** * Gets one of the event names in the commentary INI file * * @return one of the event names in the commentary INI file */ public abstract String getName(); /** * Gets first value to pass in (if any) * * @return first value to pass in (if any) */ public abstract double getInput1(); /** * Gets second value to pass in (if any) * * @return second value to pass in (if any) */ public abstract double getInput2(); /** * Gets third value to pass in (if any) * * @return third value to pass in (if any) */ public abstract double getInput3(); /** * @return ignores commentary detail and random probability of event */ public abstract boolean getSkipChecks(); protected CommentaryRequestInfo( LiveGameData gameData ) { this.gameData = gameData; } }