From: Frederick W. <fre...@us...> - 2012-01-30 14:41:33
|
LocalisedText.properties | 1 data/Properties.xml | 1 rails/sound/SoundConfig.java | 15 +++++++++++ rails/sound/SoundContext.java | 4 +- rails/sound/SoundEventInterpreter.java | 41 ++++++++++++++++++++++++++---- rails/sound/SoundManager.java | 8 ++++- rails/sound/SoundPlayer.java | 45 +++++++++++++-------------------- rails/ui/swing/ORUIManager.java | 11 ++++---- rails/ui/swing/StartRoundWindow.java | 4 ++ 9 files changed, 90 insertions(+), 40 deletions(-) New commits: commit e6074467587ead46896cf6a5668a8acf62b88942 Author: Frederick Weld <fre...@gm...> Date: Mon Jan 30 15:34:42 2012 +0100 Refactored SoundPlayer: immediate/deferred sfx play defined declaratively Some sfx are to be played without waiting for the completion of prior sfx (applies to selection / rotate tile sfx). Before, the caller of the SoundPlayer had to specify whether to wait or not. Now, sfx to be immediately played are tagged as such in SoundConfig so that SoundPlayer takes care of scheduling without necessiting that information by the caller. diff --git a/rails/sound/SoundConfig.java b/rails/sound/SoundConfig.java index ecff5cd..849be21 100644 --- a/rails/sound/SoundConfig.java +++ b/rails/sound/SoundConfig.java @@ -1,5 +1,9 @@ package rails.sound; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + import rails.common.parser.Config; /** @@ -41,6 +45,16 @@ public class SoundConfig { public static final String KEY_SFX_OR_BuyTrain = "sound.sfx.or.buyTrain"; public static final String KEY_SFX_OR_BuyPrivate = "sound.sfx.or.buyPrivate"; + /** + * list of sfx which are to be played immediately (without waiting for completion of + * prior sfx threads) + */ + public static final Set<String> KEYS_SFX_IMMEDIATE_PLAYING = new HashSet<String> + (Arrays.asList( new String[] { + KEY_SFX_GEN_Select, + KEY_SFX_OR_RotateTile + })); + //if set to true, sfx is reported not to be enabled irrespective of the configuration private static boolean isSFXDisabled = false; diff --git a/rails/sound/SoundContext.java b/rails/sound/SoundContext.java index 4d4be08..9f4ac58 100644 --- a/rails/sound/SoundContext.java +++ b/rails/sound/SoundContext.java @@ -100,8 +100,8 @@ public class SoundContext { //additionally play stock market opening bell if appropriate if (SoundConfig.isSFXEnabled() && currentRound instanceof StockRound) { - player.playSFXWithFollowupBGM( - SoundConfig.get(SoundConfig.KEY_SFX_SR_OpeningBell), + player.playSFXByConfigKeyWithFollowupBGM( + SoundConfig.KEY_SFX_SR_OpeningBell, newBackgroundMusicFileName); } else { player.playBGM(newBackgroundMusicFileName); diff --git a/rails/sound/SoundEventInterpreter.java b/rails/sound/SoundEventInterpreter.java index d45407c..304c09a 100644 --- a/rails/sound/SoundEventInterpreter.java +++ b/rails/sound/SoundEventInterpreter.java @@ -199,9 +199,7 @@ public class SoundEventInterpreter { if (SoundConfig.isSFXEnabled()) { //play rotate sound if tile has been rotated or is now ready for rotations if (currentStep == ORUIManager.ROTATE_OR_CONFIRM_TILE) { - //don't wait for prior SFX playing end, otherwise quickly repeated - //rotations would lead to a long queue of sequentially played sfx - player.playSFXByConfigKey(SoundConfig.KEY_SFX_OR_RotateTile,false); + player.playSFXByConfigKey(SoundConfig.KEY_SFX_OR_RotateTile); } //play hex selection sound if the follow-up step (select tile/token) is active @@ -209,9 +207,7 @@ public class SoundEventInterpreter { // can also be selected during selectTile/Token) else if ( currentStep == ORUIManager.SELECT_TILE || currentStep == ORUIManager.SELECT_TOKEN ) { - //don't wait for prior SFX playing end, otherwise quickly repeated - //hex selections would lead to a long queue of sequentially played sfx - player.playSFXByConfigKey(SoundConfig.KEY_SFX_GEN_Select,false); + player.playSFXByConfigKey(SoundConfig.KEY_SFX_GEN_Select); } } @@ -224,9 +220,7 @@ public class SoundEventInterpreter { if (SoundConfig.isSFXEnabled()) { if (clickFieldAction instanceof BidStartItem || clickFieldAction instanceof BuyStartItem) { - //don't wait for prior SFX playing end, otherwise quickly repeated - //selections would lead to a long queue of sequentially played sfx - player.playSFXByConfigKey(SoundConfig.KEY_SFX_GEN_Select,false); + player.playSFXByConfigKey(SoundConfig.KEY_SFX_GEN_Select); } } } diff --git a/rails/sound/SoundPlayer.java b/rails/sound/SoundPlayer.java index 45fbf8f..d35c783 100644 --- a/rails/sound/SoundPlayer.java +++ b/rails/sound/SoundPlayer.java @@ -187,59 +187,52 @@ public class SoundPlayer { return pt; } - private void playSFX(PlayerThread newPlayerThread,boolean waitForEndOfPriorSFX) { + private void playSFX(PlayerThread newPlayerThread,boolean playImmediately) { PlayerThread oldPlayerThread = adjustLastSFXThread(newPlayerThread); - if (waitForEndOfPriorSFX) { + if (!playImmediately) { newPlayerThread.setPriorThread(oldPlayerThread); } newPlayerThread.start(); } - /** - * SFX played after prior SFX playing has been completed - */ - public void playSFX(String fileName) { - playSFX(fileName,true); + private void playSFX(String fileName, boolean playImmediately) { + playSFX(new PlayerThread (fileName),playImmediately); } - public void playSFX(String fileName, boolean waitForEndOfPriorSFX) { - playSFX(new PlayerThread (fileName),waitForEndOfPriorSFX); + + private void playSFX(String fileName, double playSoundProportion, boolean playImmediately) { + playSFX(new PortionPlayerThread (fileName, 1 - playSoundProportion, 1) + ,playImmediately); } + /** * SFX played after prior SFX playing has been completed */ public void playSFXByConfigKey(String configKey) { - playSFXByConfigKey(configKey, true); - } - public void playSFXByConfigKey(String configKey, boolean waitForEndOfPriorSFX) { - playSFX(SoundConfig.get(configKey), waitForEndOfPriorSFX); + playSFX(SoundConfig.get(configKey), + SoundConfig.KEYS_SFX_IMMEDIATE_PLAYING.contains(configKey)); } public void playSFXByConfigKey(String configKey,String parameter) { - playSFX(SoundConfig.get(configKey,parameter)); + playSFX(SoundConfig.get(configKey,parameter), + SoundConfig.KEYS_SFX_IMMEDIATE_PLAYING.contains(configKey)); } - public void playSFX(String fileName, double playSoundProportion) { - playSFX(new PortionPlayerThread (fileName, 1 - playSoundProportion, 1),true); - } - /** * The latter part of the sfx is played. * @param playSoundProportion The length of this part relatively to the overall sound duration. */ public void playSFXByConfigKey(String configKey, double playSoundProportion) { - playSFX(SoundConfig.get(configKey), playSoundProportion); - } - - public void playSFXWithFollowupBGM(String sfxFileName,String bgmFileName) { - playSFX(new PlayerThreadWithFollowupBGM (sfxFileName,bgmFileName),true); + playSFX(SoundConfig.get(configKey), playSoundProportion, + SoundConfig.KEYS_SFX_IMMEDIATE_PLAYING.contains(configKey)); } /** * Plays the specified SFX and, after completing SFX play, the specified BGM * is launched. */ - public void playSFXWithFollowupBGMByConfigKey(String sfxConfigKey, String bgmConfigKey) { - playSFXWithFollowupBGM( - SoundConfig.get(sfxConfigKey),SoundConfig.get(bgmConfigKey)); + public void playSFXByConfigKeyWithFollowupBGM(String sfxConfigKey,String bgmFileName) { + playSFX(new PlayerThreadWithFollowupBGM ( + SoundConfig.get(sfxConfigKey),bgmFileName), + SoundConfig.KEYS_SFX_IMMEDIATE_PLAYING.contains(sfxConfigKey)); } public void playBGM(String backgroundMusicFileName) { commit 0711aea4fce98d414e13315873549c7c8345c795 Author: Frederick Weld <fre...@gm...> Date: Mon Jan 30 14:42:01 2012 +0100 Added new sfx options (select hex / start item) Sound framework now notified within set local step of ORUIManager in a generic manner (could be expanded upon in the future if there is a pull for more sound options). Added notification trigger into start round window's click field actionPerformed. diff --git a/LocalisedText.properties b/LocalisedText.properties index 8ef0a7f..137b73c 100644 --- a/LocalisedText.properties +++ b/LocalisedText.properties @@ -214,6 +214,7 @@ Config.label.sound.backgroundMusic.stockRound=Stock Round (several files) Config.label.sound.backgroundMusic.operatingRound=Operating Round (several files) Config.label.sound.sfx=Sound Effects Config.label.sound.sfx.gen.pass=Pass +Config.label.sound.sfx.gen.select=Select (hex, start item) Config.label.sound.sfx.str.bidStartItem=Bid on Start Item Config.label.sound.sfx.str.buyStartItem=Buy Start Item Config.label.sound.sfx.or.buyPrivate=Buy Private (as a company) diff --git a/data/Properties.xml b/data/Properties.xml index d2a9153..43e64c2 100644 --- a/data/Properties.xml +++ b/data/Properties.xml @@ -74,6 +74,7 @@ <Section name="SFX"> <Property name="sound.sfx" type="LIST" values="disabled,enabled" /> <Property name="sound.sfx.gen.pass" type="FILE" /> + <Property name="sound.sfx.gen.select" type="FILE" /> <Property name="sound.sfx.str.bidStartItem" type="FILE" /> <Property name="sound.sfx.str.buyStartItem" type="FILE" /> <Property name="sound.sfx.sr.openingBell" type="FILE" /> diff --git a/rails/sound/SoundConfig.java b/rails/sound/SoundConfig.java index 14adb30..ecff5cd 100644 --- a/rails/sound/SoundConfig.java +++ b/rails/sound/SoundConfig.java @@ -21,6 +21,7 @@ public class SoundConfig { public static final String KEY_BGM_EndOfGameRound = "sound.backgroundMusic.endOfGameRound"; public static final String KEY_SFX_Enabled = "sound.sfx"; public static final String KEY_SFX_GEN_Pass = "sound.sfx.gen.pass"; + public static final String KEY_SFX_GEN_Select = "sound.sfx.gen.select"; public static final String KEY_SFX_STR_BidStartItem = "sound.sfx.str.bidStartItem"; public static final String KEY_SFX_STR_BuyStartItem = "sound.sfx.str.buyStartItem"; public static final String KEY_SFX_SR_OpeningBell = "sound.sfx.sr.openingBell"; diff --git a/rails/sound/SoundEventInterpreter.java b/rails/sound/SoundEventInterpreter.java index 1f5590c..d45407c 100644 --- a/rails/sound/SoundEventInterpreter.java +++ b/rails/sound/SoundEventInterpreter.java @@ -6,6 +6,7 @@ import java.util.Observer; import rails.game.*; import rails.game.action.*; import rails.game.state.*; +import rails.ui.swing.ORUIManager; /** * Converts processed actions and model updates to triggers for playing sounds. @@ -72,7 +73,8 @@ public class SoundEventInterpreter { //General actions if (action instanceof NullAction) { - if (((NullAction)action).getMode() == NullAction.PASS) { + if (((NullAction)action).getMode() == NullAction.PASS + || ((NullAction)action).getMode() == NullAction.AUTOPASS) { player.playSFXByConfigKey (SoundConfig.KEY_SFX_GEN_Pass); } @@ -186,11 +188,46 @@ public class SoundEventInterpreter { public void notifyOfTimeWarp(boolean timeWarpMode) { SoundConfig.setSFXDisabled(timeWarpMode); } - public void notifyOfRotateTile() { + /** + * Interprets changes/status of OR local steps in order to trigger sfx that + * are related to neither model changes nor game engine actions. + * Is triggered whenever some step changes (but priorStep is allowed to be + * equal to currentStep) + * @param currentStep Step as defined as constant in ORUIManager + */ + public void notifyOfORLocalStep(int currentStep) { if (SoundConfig.isSFXEnabled()) { - //don't wait for prior SFX playing end, otherwise quickly repeated - //rotations would lead to a long queue of sequentially played sfx - player.playSFXByConfigKey(SoundConfig.KEY_SFX_OR_RotateTile,false); + //play rotate sound if tile has been rotated or is now ready for rotations + if (currentStep == ORUIManager.ROTATE_OR_CONFIRM_TILE) { + //don't wait for prior SFX playing end, otherwise quickly repeated + //rotations would lead to a long queue of sequentially played sfx + player.playSFXByConfigKey(SoundConfig.KEY_SFX_OR_RotateTile,false); + } + + //play hex selection sound if the follow-up step (select tile/token) is active + //(don't consider whether prior step was "select hex..." because hexes + // can also be selected during selectTile/Token) + else if ( currentStep == ORUIManager.SELECT_TILE + || currentStep == ORUIManager.SELECT_TOKEN ) { + //don't wait for prior SFX playing end, otherwise quickly repeated + //hex selections would lead to a long queue of sequentially played sfx + player.playSFXByConfigKey(SoundConfig.KEY_SFX_GEN_Select,false); + + } + } + } + /** + * Interprets selections of ClickFields + * @param clickFieldAction The action associated with the click field + */ + public void notifyOfClickFieldSelection(PossibleAction clickFieldAction) { + if (SoundConfig.isSFXEnabled()) { + if (clickFieldAction instanceof BidStartItem + || clickFieldAction instanceof BuyStartItem) { + //don't wait for prior SFX playing end, otherwise quickly repeated + //selections would lead to a long queue of sequentially played sfx + player.playSFXByConfigKey(SoundConfig.KEY_SFX_GEN_Select,false); + } } } } diff --git a/rails/sound/SoundManager.java b/rails/sound/SoundManager.java index d3a9e33..7a357d6 100644 --- a/rails/sound/SoundManager.java +++ b/rails/sound/SoundManager.java @@ -2,6 +2,7 @@ package rails.sound; import rails.game.GameManagerI; import rails.game.action.PossibleAction; +import rails.game.action.StartItemAction; /** * This is a singleton class as there should never be two @@ -58,7 +59,10 @@ public class SoundManager { public static void notifyOfTimeWarp(boolean timeWarpMode) { getInstance().eventInterpreter.notifyOfTimeWarp(timeWarpMode); } - public static void notifyOfRotateTile() { - getInstance().eventInterpreter.notifyOfRotateTile(); + public static void notifyOfORLocalStep(int currentStep) { + getInstance().eventInterpreter.notifyOfORLocalStep(currentStep); + } + public static void notifyOfClickFieldSelection(PossibleAction clickFieldAction) { + getInstance().eventInterpreter.notifyOfClickFieldSelection(clickFieldAction); } } diff --git a/rails/ui/swing/ORUIManager.java b/rails/ui/swing/ORUIManager.java index 30441d6..6f7f8c6 100644 --- a/rails/ui/swing/ORUIManager.java +++ b/rails/ui/swing/ORUIManager.java @@ -664,11 +664,9 @@ public class ORUIManager implements DialogOwner { if (localStep == ROTATE_OR_CONFIRM_TILE && clickedHex == selectedHex) { selectedHex.rotateTile(); - //directly inform sound framework of "rotate tile" as this is - //neither an action nor a model change - //call not put to GUIHex so that sound notification calls are - //centrally done by UIManagers (Game, OR) - SoundManager.notifyOfRotateTile(); + //directly inform sound framework of "rotate tile" local step + //as notification via "set local step" does not occur + SoundManager.notifyOfORLocalStep(localStep); return true; } else { @@ -1795,6 +1793,9 @@ public class ORUIManager implements DialogOwner { public void setLocalStep(int localStep) { log.debug("Setting upgrade step to " + localStep + " " + ORUIManager.messageKey[localStep]); + + SoundManager.notifyOfORLocalStep(localStep); + this.localStep = localStep; updateMessage(); diff --git a/rails/ui/swing/StartRoundWindow.java b/rails/ui/swing/StartRoundWindow.java index 1b9af8a..47f0a9a 100644 --- a/rails/ui/swing/StartRoundWindow.java +++ b/rails/ui/swing/StartRoundWindow.java @@ -15,6 +15,7 @@ import rails.common.LocalText; import rails.game.*; import rails.game.action.*; import rails.game.special.SpecialPropertyI; +import rails.sound.SoundManager; import rails.ui.swing.elements.*; import rails.ui.swing.hexmap.HexHighlightMouseListener; @@ -563,6 +564,9 @@ implements ActionListener, KeyListener, ActionPerformer, DialogOwner { StartItemAction currentActiveItem = (StartItemAction) ((ClickField) source).getPossibleActions().get( 0); + + //notify sound manager that click field has been selected + SoundManager.notifyOfClickFieldSelection(currentActiveItem); if (currentActiveItem instanceof BuyStartItem) { buyButton.setEnabled(true); |