/* * Copyright (c) 2003-onwards Shaven Puppy Ltd * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of 'Shaven Puppy' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.shavenpuppy.jglib.util; import org.lwjgl.Sys; /** * A PriorityPool takes care of allocating objects by priority from a finite pool. */ public class PriorityPool { /** Pool wrapper */ private final class PoolWrapper { /** The index into the pool, when active */ private int index; /** The Pooled thing's owner */ private Object owner; /** The age of this Pooled thing */ private long age; /** The actual pooled object */ private final PriorityPooled pooled; /** * Constructor */ PoolWrapper(PriorityPooled pooled) { this.pooled = pooled; } int getPriority() { return pooled.getPriority(); } boolean isLocked() { return pooled.isLocked(); } /** * @return true if this is active */ boolean isActive() { return owner != null; } /** * Deactivate this object. The owner is cleared. */ void deactivate() { if (isActive()) { pooled.deactivate(); owner = null; returnToPool(this); } } /** * Allocate this object. The object's priority is set and it becomes active. * @param priority The object's new priority * @param owner The object's new owner */ void allocate(int priority, Object owner) { this.owner = owner; age = Sys.getTime(); pooled.allocate(owner); pooled.setPriority(priority); } /** * Perform ticking. If this object is active then we check to see whether it * should be deactivated. */ void tick() { if (isActive()) { pooled.tick(); if (!pooled.isActive()) { deactivate(); } } } /** * Reset to initial 'unused' state */ void reset() { deactivate(); } } /** The pool */ private final PoolWrapper[] pool; /** Copy of the pool */ private final PoolWrapper[] poolCopy; /** The number of active entries */ private int inUse; /** * Constructor for PriorityPool. * @param pool[] the pooled objects, which should be all the same class, and unique, and not null */ public PriorityPool(PriorityPooled[] pooled) { pool = new PoolWrapper[pooled.length]; poolCopy = new PoolWrapper[pooled.length]; for (int i = 0; i < pooled.length; i ++) { pool[i] = new PoolWrapper(pooled[i]); pool[i].index = i; } } /** * Allocate an object from the pool. The rule is as follows: *