134 lines
3.3 KiB
Java
134 lines
3.3 KiB
Java
package speiger.src.coreengine.utils.collections.registries.simple;
|
|
|
|
import java.util.BitSet;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.Set;
|
|
|
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
|
import speiger.src.collections.objects.lists.ObjectList;
|
|
import speiger.src.collections.objects.maps.impl.hash.Object2IntLinkedOpenHashMap;
|
|
import speiger.src.collections.objects.maps.impl.hash.Object2ObjectLinkedOpenHashMap;
|
|
import speiger.src.collections.objects.maps.interfaces.Object2IntMap;
|
|
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
|
|
import speiger.src.collections.objects.utils.ObjectCollections;
|
|
import speiger.src.collections.objects.utils.ObjectSets;
|
|
import speiger.src.coreengine.assets.AssetLocation;
|
|
import speiger.src.coreengine.utils.collections.iterators.ReadOnlyIterator;
|
|
|
|
public class SimpleRegistry<T extends IRegistryEntry<T>> implements IRegistry<T>
|
|
{
|
|
protected Object2IntMap<AssetLocation> nameToId = new Object2IntLinkedOpenHashMap<>();
|
|
protected Object2ObjectMap<AssetLocation, T> nameToValue = new Object2ObjectLinkedOpenHashMap<>();
|
|
protected ObjectList<AssetLocation> idsToName = new ObjectArrayList<>();
|
|
protected BitSet freeIds;
|
|
protected int capacity;
|
|
protected int stored;
|
|
|
|
boolean frozen = false;
|
|
Object2IntMap<AssetLocation> missing = new Object2IntLinkedOpenHashMap<>();
|
|
Object2ObjectMap<AssetLocation, AssetLocation> remaps = new Object2ObjectLinkedOpenHashMap<>();
|
|
|
|
public SimpleRegistry(int capacity)
|
|
{
|
|
this.capacity = capacity;
|
|
freeIds = new BitSet(capacity + 1);
|
|
nameToId.setDefaultReturnValue(-1);
|
|
}
|
|
|
|
@Override
|
|
public T register(T value)
|
|
{
|
|
if(frozen)
|
|
{
|
|
throw new RuntimeException("Registry is Frozen");
|
|
}
|
|
if(value.getName() == null)
|
|
{
|
|
throw new IllegalStateException(value+", is Missing a name");
|
|
}
|
|
AssetLocation name = value.getName();
|
|
if(nameToValue.get(name) != null)
|
|
{
|
|
throw new IllegalStateException("Name is already registered [Name="+name+", Tile="+nameToValue.get(name)+"]");
|
|
}
|
|
int freeBit = freeIds.nextClearBit(0);
|
|
if(capacity >= 0 && freeBit >= capacity)
|
|
{
|
|
throw new IllegalStateException("Registry is full");
|
|
}
|
|
while(idsToName.size() <= freeBit)
|
|
{
|
|
idsToName.add(null);
|
|
}
|
|
freeIds.set(freeBit);
|
|
idsToName.set(freeBit, name);
|
|
nameToValue.put(name, value);
|
|
nameToId.put(name, freeBit);
|
|
value.setId(this, freeBit);
|
|
if(missing.size() > 0)
|
|
{
|
|
missing.remove(name);
|
|
}
|
|
stored++;
|
|
return value;
|
|
}
|
|
|
|
@Override
|
|
public int getId(AssetLocation name)
|
|
{
|
|
return nameToId.getInt(remap(name));
|
|
}
|
|
|
|
@Override
|
|
public AssetLocation getName(int id)
|
|
{
|
|
return idsToName.get(id);
|
|
}
|
|
|
|
@Override
|
|
public T getValue(AssetLocation name)
|
|
{
|
|
return nameToValue.get(remap(name));
|
|
}
|
|
|
|
public boolean isEmpty()
|
|
{
|
|
return stored <= 0;
|
|
}
|
|
|
|
public int size()
|
|
{
|
|
return stored;
|
|
}
|
|
|
|
@Override
|
|
public Set<AssetLocation> keySet()
|
|
{
|
|
return ObjectSets.unmodifiable(nameToId.keySet());
|
|
}
|
|
|
|
@Override
|
|
public Collection<T> values()
|
|
{
|
|
return ObjectCollections.unmodifiable(nameToValue.values());
|
|
}
|
|
|
|
@Override
|
|
public Iterator<T> iterator()
|
|
{
|
|
return new ReadOnlyIterator<T>(nameToValue.values().iterator());
|
|
}
|
|
|
|
protected AssetLocation remap(AssetLocation location)
|
|
{
|
|
AssetLocation mapped = remaps.get(location);
|
|
return mapped == null ? location : mapped;
|
|
}
|
|
|
|
public final void freeze()
|
|
{
|
|
frozen = true;
|
|
}
|
|
}
|