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); } }