package com.plattysoft.leonids;
import java.util.ArrayList;
import java.util.List;
/**
* Created by daniel on 27.12.15.
*/
public class ParticleSystemPool implements ParticleSystem.OnAnimationEndedListener {
// lightweight holding of particle systems: lazy creation of new systems up to max capacity;
// not removing from list and only marking as locked if animation did not end yet
private final List<ParticleSystem> mSystems;
private final ParticleSystemMaker mMaker;
private boolean[] mAvailable;
private final int mCapacity;
public interface ParticleSystemMaker {
ParticleSystem makeParticleSystem();
}
/**
* Creates a new pool with fixed capacity giving it a valid maker that produces valid new
* particle systems.
* @param maker Something that produces new ParticleSystems.
* @param capacity The capacity of the pool, must be >0.
*/
public ParticleSystemPool(ParticleSystemMaker maker, int capacity) {
if (capacity < 1) {
throw new IllegalArgumentException("Zero or negative capacity given: " + capacity);
}
mMaker = maker;
mSystems = new ArrayList<>(capacity);
mCapacity = capacity;
mAvailable = new boolean[mCapacity];
}
/**
* Obtains a new ParticleSystem if there is one available. The capacity limits how many
* ParticleSystems can be available at total. When the particle emitting and animation ends,
* the system is automatically freed for future use.
* @return A particle system that can be used for starting emitting or null if none is
* available due to capacity limitations.
*/
public synchronized ParticleSystem obtain() {
for (int i = 0; i < mAvailable.length; i++) {
if (mAvailable[i]) {
return lockSystem(i, mSystems.get(i));
}
}
// no old system available: if capacity not yet reached create new one
if (mSystems.size() < mCapacity) {
ParticleSystem system = mMaker.makeParticleSystem();
mSystems.add(system);
return lockSystem(mSystems.size() - 1, system);
}
return null;
}
private ParticleSystem lockSystem(int index, ParticleSystem system) {
system.setOnAnimationEndedListener(this);
mAvailable[index] = false;
return system;
}
@Override
public synchronized void onParticleAnimationEnded(ParticleSystem system, boolean cancelled) {
for (int i = 0; i < mSystems.size(); i++) {
if (mSystems.get(i) == system) {
system.setOnAnimationEndedListener(null);
mAvailable[i] = true;
break;
}
}
}
}