com.github.czyzby.autumn.mvc.component.sfx.MusicService Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gdx-autumn-mvc Show documentation
Show all versions of gdx-autumn-mvc Show documentation
MVC framework based on LibGDX using Autumn for components management and LML as view templates.
package com.github.czyzby.autumn.mvc.component.sfx;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Music.OnCompletionListener;
import com.badlogic.gdx.audio.Sound;
import com.github.czyzby.autumn.annotation.Destroy;
import com.github.czyzby.autumn.annotation.Initiate;
import com.github.czyzby.autumn.annotation.Inject;
import com.github.czyzby.autumn.mvc.component.sfx.dto.CurrentMusicStateAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.CurrentMusicVolumeAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.CurrentSoundStateAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.CurrentSoundVolumeAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.MusicVolumeChangeAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.SoundVolumeChangeAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.ToggleMusicAction;
import com.github.czyzby.autumn.mvc.component.sfx.dto.ToggleSoundAction;
import com.github.czyzby.autumn.mvc.component.ui.InterfaceService;
import com.github.czyzby.autumn.mvc.config.AutumnActionPriority;
import com.github.czyzby.kiwi.util.common.Strings;
import com.github.czyzby.kiwi.util.gdx.preference.ApplicationPreferences;
import com.github.czyzby.lml.parser.LmlParser;
/** Manages currently played UI theme and sound settings.
*
* @author MJ */
public class MusicService {
/** Name of the action that returns music volume as it appears in LML views. Defaults to "getMusicVolume". */
public static String GET_MUSIC_VOLUME_ACTION_ID = "getMusicVolume";
/** Name of the action that returns sound volume as it appears in LML views. Defaults to "getSoundVolume". */
public static String GET_SOUND_VOLUME_ACTION_ID = "getSoundVolume";
/** Name of the action that return if music is on as it appears in LML views. Defaults to "musicOn". */
public static String GET_MUSIC_STATE_ACTION_ID = "musicOn";
/** Name of the action that return if music is on as it appears in LML views. Defaults to "soundOn". */
public static String GET_SOUND_STATE_ACTION_ID = "soundOn";
/** Name of the action that changes music volume as it appears in LML views. Defaults to "setMusicVolume". */
public static String SET_MUSIC_VOLUME_ACTION_ID = "setMusicVolume";
/** Name of the action that changes sound volume as it appears in LML views. Defaults to "setSoundVolume". */
public static String SET_SOUND_VOLUME_ACTION_ID = "setSoundVolume";
/** Name of the action that turns music on and off as it appears in LML views. Defaults to "toggleMusic". */
public static String TOGGLE_MUSIC_ACTION_ID = "toggleMusic";
/** Name of the action that turns sound on and off as it appears in LML views. Defaults to "toggleSound". */
public static String TOGGLE_SOUND_ACTION_ID = "toggleSound";
/** Time that has to pass before the theme reaches its full volume or is fully turned off. */
public static float DEFAULT_THEME_FADING_TIME = 0.25f;
private static final float MIN_VOLUME = 0f;
private static final float MAX_VOLUME = 1f;
private String musicPreferences;
private String musicVolumePreferenceName;
private String soundVolumePreferenceName;
private String musicEnabledPreferenceName;
private String soundEnabledPreferenceName;
private float musicVolume = MAX_VOLUME;
private float soundVolume = MAX_VOLUME;
private boolean musicEnabled = true;
private boolean soundEnabled = true;
private Music currentTheme;
@Inject private InterfaceService interfaceService;
private final OnCompletionListener musicCompletionListener = new OnCompletionListener() {
@Override
public void onCompletion(final Music music) {
playCurrentTheme(interfaceService.getCurrentController().getNextTheme());
}
};
@Initiate
private void initiate() {
savePreferences(true);
final LmlParser parser = interfaceService.getParser();
parser.getData().addActorConsumer(TOGGLE_SOUND_ACTION_ID, new ToggleSoundAction(this));
parser.getData().addActorConsumer(TOGGLE_MUSIC_ACTION_ID, new ToggleMusicAction(this));
parser.getData().addActorConsumer(SET_SOUND_VOLUME_ACTION_ID, new SoundVolumeChangeAction(this));
parser.getData().addActorConsumer(SET_MUSIC_VOLUME_ACTION_ID, new MusicVolumeChangeAction(this));
parser.getData().addActorConsumer(GET_SOUND_VOLUME_ACTION_ID, new CurrentSoundVolumeAction(this));
parser.getData().addActorConsumer(GET_MUSIC_VOLUME_ACTION_ID, new CurrentMusicVolumeAction(this));
parser.getData().addActorConsumer(GET_SOUND_STATE_ACTION_ID, new CurrentSoundStateAction(this));
parser.getData().addActorConsumer(GET_MUSIC_STATE_ACTION_ID, new CurrentMusicStateAction(this));
}
/** @return current volume of music, [0, 1]. */
public float getMusicVolume() {
return musicVolume;
}
/** @param musicVolume will become current volume of music. If a registered theme is currently playing, it's volume
* will be adjusted. */
public void setMusicVolume(final float musicVolume) {
this.musicVolume = normalizeVolume(musicVolume);
if (currentTheme != null) {
currentTheme.setVolume(musicVolume);
}
}
/** @param musicEnabled true to enable, false to disable. If a current theme is registered, it will stopped or
* started according to this setting. */
public void setMusicEnabled(final boolean musicEnabled) {
this.musicEnabled = musicEnabled;
if (currentTheme != null) {
if (musicEnabled) {
if (!currentTheme.isPlaying()) {
currentTheme.play();
}
} else if (currentTheme.isPlaying()) {
currentTheme.stop();
}
}
}
/** @return true if music is currently enabled. */
public boolean isMusicEnabled() {
return musicEnabled;
}
/** @param volume should be normalized.
* @return float value in range of [0, 1]. */
public static float normalizeVolume(final float volume) {
return Math.max(MIN_VOLUME, Math.min(MAX_VOLUME, volume));
}
/** Sets the current music volume according to the values stored in preferences. Mostly for internal use.
*
* @param preferences path to the preferences. Will be set as global music preferences path.
* @param preferenceName name of the volume preference.
* @param defaultValue used if preference is not set. */
public void setMusicVolumeFromPreferences(final String preferences, final String preferenceName,
final float defaultValue) {
musicPreferences = preferences;
musicVolumePreferenceName = preferenceName;
setMusicVolume(readFromPreferences(preferences, preferenceName, defaultValue));
}
/** Sets the current music state according to the value stored in preferences. Mostly for internal use.
*
* @param preferences path to the preferences. Will be set as global music preferences path.
* @param preferenceName name of the state preference.
* @param defaultValue used if preference is not set. */
public void setMusicEnabledFromPreferences(final String preferences, final String preferenceName,
final boolean defaultValue) {
musicPreferences = preferences;
musicEnabledPreferenceName = preferenceName;
setMusicEnabled(readFromPreferences(preferences, preferenceName, defaultValue));
}
/** @return current volume of sound effects. */
public float getSoundVolume() {
return soundVolume;
}
/** @param soundVolume will become current volume of sound effects. Note that currently played sounds will not be
* affected. */
public void setSoundVolume(final float soundVolume) {
this.soundVolume = normalizeVolume(soundVolume);
}
/** @param soundEnabled true to enable, false to disable. Note that currently played sounds will not be turned
* off. */
public void setSoundEnabled(final boolean soundEnabled) {
this.soundEnabled = soundEnabled;
}
/** Sets the current sound state according to the value stored in preferences. Mostly for internal use.
*
* @param preferences path to the preferences. Will be set as global music preferences path.
* @param preferenceName name of the state preference.
* @param defaultValue used if preference is not set. */
public void setSoundEnabledFromPreferences(final String preferences, final String preferenceName,
final boolean defaultValue) {
musicPreferences = preferences;
soundEnabledPreferenceName = preferenceName;
setSoundEnabled(readFromPreferences(preferences, preferenceName, defaultValue));
}
/** @return true if sounds are currently enabled. */
public boolean isSoundEnabled() {
return soundEnabled;
}
/** Sets the current sound volume according to the values stored in preferences. Mostly for internal use.
*
* @param preferences path to the preferences. Will be set as global music preferences path.
* @param preferenceName name of the volume preference.
* @param defaultValue used if preference is not set. */
public void setSoundVolumeFromPreferences(final String preferences, final String preferenceName,
final float defaultValue) {
musicPreferences = preferences;
soundVolumePreferenceName = preferenceName;
setSoundVolume(readFromPreferences(preferences, preferenceName, defaultValue));
}
/** Saves music and sound preferences.
*
* @param flush if true, preferences will be truly saved - otherwise it just sets them in the preferences map. */
public void savePreferences(final boolean flush) {
saveMusicPreferences(flush);
saveSoundPreferences(flush);
}
/** Saves music volume and state in preferences.
*
* @param flush if true, preferences will be truly saved - otherwise it just sets them in the preferences map. */
public void saveMusicPreferences(final boolean flush) {
if (Strings.isNotEmpty(musicPreferences)) {
if (Strings.isNotEmpty(musicVolumePreferenceName)) {
saveInPreferences(musicPreferences, musicVolumePreferenceName, musicVolume);
}
if (Strings.isNotEmpty(musicEnabledPreferenceName)) {
saveInPreferences(musicPreferences, musicEnabledPreferenceName, musicEnabled);
}
if (flush) {
flushPreferences();
}
}
}
/** Saves sound volume and state in preferences.
*
* @param flush if true, preferences will be truly saved - otherwise it just sets them in the preferences map. */
public void saveSoundPreferences(final boolean flush) {
if (Strings.isNotEmpty(musicPreferences)) {
if (Strings.isNotEmpty(soundVolumePreferenceName)) {
saveInPreferences(musicPreferences, soundVolumePreferenceName, soundVolume);
}
if (Strings.isNotEmpty(soundEnabledPreferenceName)) {
saveInPreferences(musicPreferences, soundEnabledPreferenceName, soundEnabled);
}
if (flush) {
flushPreferences();
}
}
}
private void flushPreferences() {
ApplicationPreferences.getPreferences(musicPreferences).flush();
}
private static void saveInPreferences(final String preferences, final String preferenceName, final float value) {
// GWT is not a huge fan of non-string preferences.
ApplicationPreferences.getPreferences(preferences).putString(preferenceName, String.valueOf(value));
}
private static void saveInPreferences(final String preferences, final String preferenceName, final boolean value) {
// GWT is not a huge fan of non-string preferences.
ApplicationPreferences.getPreferences(preferences).putString(preferenceName, String.valueOf(value));
}
private static float readFromPreferences(final String preferences, final String preferenceName,
final float defaultValue) {
return Float.parseFloat(ApplicationPreferences.getPreferences(preferences).getString(preferenceName,
String.valueOf(defaultValue)));
}
private static boolean readFromPreferences(final String preferences, final String preferenceName,
final boolean defaultValue) {
return Boolean.parseBoolean(ApplicationPreferences.getPreferences(preferences).getString(preferenceName,
String.valueOf(defaultValue)));
}
/** Restores music and sound settings to the values stored in preferences. Music preferences have to be properly
* annotated with {@link com.github.czyzby.autumn.mvc.stereotype.preference.sfx.MusicVolume},
* {@link com.github.czyzby.autumn.mvc.stereotype.preference.sfx.MusicEnabled},
* {@link com.github.czyzby.autumn.mvc.stereotype.preference.sfx.SoundVolume} and
* {@link com.github.czyzby.autumn.mvc.stereotype.preference.sfx.SoundEnabled} for each setting to work. */
public void restoreSettingsFromPreferences() {
if (Strings.isNotEmpty(musicPreferences)) {
if (Strings.isNotEmpty(musicVolumePreferenceName)) {
setMusicVolume(readFromPreferences(musicPreferences, musicVolumePreferenceName, musicVolume));
}
if (Strings.isNotEmpty(soundVolumePreferenceName)) {
setSoundVolume(readFromPreferences(musicPreferences, soundVolumePreferenceName, soundVolume));
}
if (Strings.isNotEmpty(musicEnabledPreferenceName)) {
setMusicEnabled(readFromPreferences(musicPreferences, musicEnabledPreferenceName, musicEnabled));
}
if (Strings.isNotEmpty(soundEnabledPreferenceName)) {
setSoundEnabled(readFromPreferences(musicPreferences, soundEnabledPreferenceName, soundEnabled));
}
}
}
/** @param sound will be played with the currently set sound volume, provided that sounds are turned on. */
public void play(final Sound sound) {
if (soundEnabled) {
sound.play(soundVolume);
}
}
/** @return currently played music theme, provided that it was properly registered. */
public Music getCurrentTheme() {
return currentTheme;
}
/** @param currentTheme will be set as the current theme and have its volume changed. If music is enabled, will be
* played. */
public void playCurrentTheme(final Music currentTheme) {
playCurrentTheme(currentTheme, true);
}
/** @param currentTheme will be set as the current theme. If music is enabled, will be played.
* @param forceVolume if true, music volume will be set to stored preference. */
public void playCurrentTheme(final Music currentTheme, final boolean forceVolume) {
this.currentTheme = currentTheme;
currentTheme.setOnCompletionListener(musicCompletionListener);
if (forceVolume) {
currentTheme.setVolume(musicVolume);
}
if (musicEnabled) {
currentTheme.play();
}
}
/** Clears current theme, stopping it from playing. */
public void clearCurrentTheme() {
if (currentTheme != null) {
if (currentTheme.isPlaying()) {
currentTheme.stop();
}
currentTheme = null;
}
}
@Destroy(priority = AutumnActionPriority.VERY_LOW_PRIORITY)
private void destroy() {
savePreferences(true);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy