Java tutorial
/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.audio.openAL; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import org.terasology.audio.AudioManager; import org.terasology.audio.Sound; import java.util.Map; import java.util.Set; /** * */ public abstract class BaseSoundPool<SOUND extends Sound<?>, SOURCE extends SoundSource<SOUND>> implements SoundPool<SOUND, SOURCE> { private static final int DEFAULT_POOL_SIZE = 32; protected Map<SOURCE, Integer> soundSources; private float volume; public BaseSoundPool(int capacity) { soundSources = Maps.newHashMapWithExpectedSize(capacity); this.fillPool(capacity); } public BaseSoundPool() { this(DEFAULT_POOL_SIZE); } public SOURCE getLockedSource() { for (SOURCE source : soundSources.keySet()) { if (!isActive(source)) { if (lock(source)) { return source; } } } return null; } @Override public SOURCE getSource(SOUND sound, int priority) { if (sound == null) { return null; } // TODO: should be optimized (performance crucial) for (SOURCE source : soundSources.keySet()) { if (!isActive(source)) { soundSources.put(source, priority); return (SOURCE) source.setAudio(sound); } } // No free sound found, will look by priority for (Map.Entry<SOURCE, Integer> entry : soundSources.entrySet()) { SOURCE source = entry.getKey(); Integer soundPriority = entry.getValue(); if (soundPriority < priority) { // sound playing wil lower priority than our query soundSources.put(source, priority); return (SOURCE) source.setAudio(sound); } } return null; } @Override public SOURCE getSource(SOUND sound) { return getSource(sound, AudioManager.PRIORITY_NORMAL); } @Override public Set<SOURCE> getSources() { return soundSources.keySet(); } @Override public Set<SOURCE> getInactiveSources() { Set<SOURCE> inactiveSources = Sets.newHashSet(); for (SOURCE source : soundSources.keySet()) { if (!isActive(source)) { inactiveSources.add(source); } } return inactiveSources; } @Override public Set<SOURCE> getActiveSources() { Set<SOURCE> inactiveSources = Sets.newHashSet(); for (SOURCE source : soundSources.keySet()) { if (isActive(source)) { inactiveSources.add(source); } } return inactiveSources; } @Override public void stopAll() { for (SOURCE source : soundSources.keySet()) { source.stop(); } } @Override public void update(float delta) { for (SOURCE source : soundSources.keySet()) { if (source.isPlaying()) { source.update(delta); } } } @Override public void setVolume(float volume) { this.volume = volume; for (SOURCE soundSource : soundSources.keySet()) { soundSource.updateGain(); } } @Override public float getVolume() { return this.volume; } @Override public int size() { return soundSources.size(); } @Override public boolean isInPool(SOURCE source) { return soundSources.containsKey(source); } public boolean isLocked(SOURCE source) { Integer lock = soundSources.get(source); return lock != null && lock == AudioManager.PRIORITY_LOCKED; } public boolean lock(SOURCE source) { if (isLocked(source) && !isInPool(source)) { return false; } soundSources.put(source, AudioManager.PRIORITY_LOCKED); return true; } public void unlock(SOURCE source) { soundSources.put(source, null); } public boolean isActive(SOURCE source) { return isLocked(source) || source.isPlaying(); } protected abstract SOURCE createSoundSource(); private void fillPool(int capacity) { for (int i = 0; i < capacity; i++) { this.soundSources.put(createSoundSource(), null); } } @Override public void purge(Sound<?> sound) { for (SOURCE source : soundSources.keySet()) { if (sound.equals(source.getAudio())) { source.purge(); } } } }