SimpleJavaEngine/src/main/java/speiger/src/coreengine/utils/collections/registries/simple/SimpleRegistry.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;
}
}