package net.glowstone.entity;
import java.util.HashSet;
import java.util.Set;
/**
* Manager responsible for allocating all entity ids on the server.
*/
public final class EntityIdManager {
/**
* A set containing all used entity ids.
*/
private final Set<Integer> usedIds = new HashSet<>();
/**
* The last assigned id value.
*/
private int lastId = 0;
/**
* Allocates the id for an entity.
* This method performs synchronization as it might be
* accessed by multiple world threads simultaneously.
* @param entity The entity.
* @return The id.
*/
synchronized int allocate(GlowEntity entity) {
if (entity.id != 0) {
throw new IllegalStateException("Entity already has an id assigned.");
}
int startedAt = lastId;
// intentionally wraps around integer boundaries
for (int id = lastId + 1; id != startedAt; ++id) {
// skip special values
if (id == -1 || id == 0) continue;
if (usedIds.add(id)) {
entity.id = id;
lastId = id;
return id;
}
}
throw new IllegalStateException("No free entity ids");
}
/**
* Deallocates the id for an entity.
* @param entity The entity.
*/
synchronized void deallocate(GlowEntity entity) {
if (entity.id == 0) {
throw new IllegalStateException("Entity does not have an id assigned.");
}
usedIds.remove(entity.id);
}
}