All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jalse.entities.EntityContainer Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package jalse.entities;

import static jalse.attributes.Attributes.EMPTY_ATTRIBUTECONTAINER;
import static jalse.entities.Entities.asType;
import jalse.attributes.AttributeContainer;
import jalse.misc.ListenerSet;

import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * This is an {@link Entity} collection. Entities can only be added to a container by creating them
 * and remove them by killing them. Entity creation and death can be listened for using
 * {@link EntityListener} and {@link EntityEvent}.
 *
 * @author Elliot Ford
 *
 * @see DefaultEntityContainer
 * @see EntityFactory
 * @see Entities#emptyEntityContainer()
 * @see Entities#unmodifiableEntityContainer(EntityContainer)
 */
public interface EntityContainer {

    /**
     * Adds a listener for entities.
     *
     * @param listener
     *            Listener to add.
     *
     * @return {@code true} if container did not already contain this listener.
     * @throws NullPointerException
     *             if listener is null.
     *
     * @see ListenerSet#add(Object)
     *
     */
    boolean addEntityListener(EntityListener listener);

    /**
     * Gets all the entities within the containers.
     *
     * @return Gets all entities or an empty set if none were found.
     *
     * @see #streamEntities()
     */
    default Set getEntities() {
	return streamEntities().collect(Collectors.toSet());
    }

    /**
     * Gets all the entities as the specified type.
     *
     * @param type
     *            Entity type to check for.
     * @return Set of entities as the type.
     *
     * @see #streamEntitiesAsType(Class)
     */
    default  Set getEntitiesAsType(final Class type) {
	return streamEntitiesAsType(type).collect(Collectors.toSet());
    }

    /**
     * Gets all the entities marked with the specified type.
     *
     * @param type
     *            Entity type to check for.
     * @return Set of entities marked with the type.
     *
     * @see #streamEntitiesOfType(Class)
     */
    default  Set getEntitiesOfType(final Class type) {
	return streamEntitiesOfType(type).collect(Collectors.toSet());
    }

    /**
     * Gets the entity with the specified ID.
     *
     * @param id
     *            Unique ID of the entity.
     * @return The entity matching the supplied id or null if none found.
     */
    Entity getEntity(final UUID id);

    /**
     * This is a convenience method for getting an entity (no optional). The entity is wrapped with
     * the supplied entity type.
     *
     * @param id
     *            Unique ID of the entity.
     * @param type
     *            Entity type to wrap to.
     * @return The entity matching the supplied id or null if none found.
     *
     * @see Entities#asType(Entity, Class)
     */
    default  T getEntityAsType(final UUID id, final Class type) {
	final Entity e = getEntity(id);
	return e != null ? asType(e, type) : null;
    }

    /**
     * Gets the direct entity count.
     *
     * @return Direct child entity count.
     */
    int getEntityCount();

    /**
     * Gets the IDs of all the entities within the container.
     *
     * @return Set of all entity identifiers.
     */
    Set getEntityIDs();

    /**
     * Gets all the entity listeners.
     *
     * @return All the entity listeners.
     */
    Set getEntityListeners();

    /**
     * This is a convenience method for getting an entity (optional).
     *
     * @param id
     *            Unique ID of the entity.
     * @return Gets an Optional of the resulting entity or an empty Optional if it was not found.
     * @throws NullPointerException
     *             If the ID is null.
     */
    default Optional getOptEntity(final UUID id) {
	return Optional.ofNullable(getEntity(id));
    }

    /**
     * This is a convenience method for getting an entity (optional).The entity is wrapped with the
     * supplied entity type.
     *
     * @param id
     *            Unique ID of the entity.
     * @param type
     *            Entity type to wrap to.
     * @return Gets an Optional of the resulting entity or an empty Optional if it was not found.
     * @throws NullPointerException
     *             If type is null.
     *
     * @see Entities#asType(Entity, Class)
     */
    default  Optional getOptEntityAsType(final UUID id, final Class type) {
	return getOptEntity(id).map(e -> asType(e, type));
    }

    /**
     * Checks whether the container has any entities.
     *
     * @return Whether the container is not empty.
     */
    default boolean hasEntities() {
	return getEntityCount() > 0;
    }

    /**
     * Checks whether the entity is contained.
     *
     * @param id
     *            Entity ID.
     * @return Whether the entity was found.
     */
    default boolean hasEntity(final UUID id) {
	return getEntity(id) != null;
    }

    /**
     * Checks whether the container contains a particular listener.
     *
     * @param listener
     *            The EntityListener to check for.
     * @return Whether the container contains the given EntityListener.
     */
    default boolean hasEntityListener(final EntityListener listener) {
	return getEntityListeners().contains(listener);
    }

    /**
     * Kills all entities.
     */
    void killEntities();

    /**
     * Kills the specified entity.
     *
     * @param id
     *            Entity ID.
     * @return Whether the entity was alive.
     */
    boolean killEntity(UUID id);

    /**
     * Creates a new entity with a random ID.
     *
     * @return The newly created entity's ID.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     *
     * @see UUID#randomUUID()
     */
    default Entity newEntity() {
	return newEntity(EMPTY_ATTRIBUTECONTAINER);
    }

    /**
     * Creates a new entity with a random ID.
     *
     * @param sourceContainer
     *            Source attribute container.
     *
     * @return The newly created entity's ID.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     *
     * @see UUID#randomUUID()
     */
    default Entity newEntity(final AttributeContainer sourceContainer) {
	return newEntity(UUID.randomUUID(), sourceContainer);
    }

    /**
     * Creates a new entity with a random ID. This entity is marked as the specified entity type and
     * then wrapped to it.
     *
     * @param type
     *            Entity type.
     * @return The newly created entity.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     *
     * @see UUID#randomUUID()
     * @see Entity#markAsType(Class)
     * @see Entities#asType(Entity, Class)
     */
    default  T newEntity(final Class type) {
	return newEntity(type, EMPTY_ATTRIBUTECONTAINER);
    }

    /**
     * Creates a new entity with a random ID. This entity is marked as the specified entity type and
     * then wrapped to it.
     *
     * @param type
     *            Entity type.
     * @param sourceContainer
     *            Source attribute container.
     * @return The newly created entity.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     *
     * @see UUID#randomUUID()
     * @see Entity#markAsType(Class)
     * @see Entities#asType(Entity, Class)
     */
    default  T newEntity(final Class type, final AttributeContainer sourceContainer) {
	return newEntity(UUID.randomUUID(), type, sourceContainer);
    }

    /**
     * Creates new entity with the specified ID.
     *
     * @param id
     *            Entity ID.
     * @return The newly created entity.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     * @throws IllegalArgumentException
     *             If the entity ID is already assigned.
     */
    default Entity newEntity(final UUID id) {
	return newEntity(id, EMPTY_ATTRIBUTECONTAINER);
    }

    /**
     * Creates new entity with the specified ID.
     *
     * @param id
     *            Entity ID.
     * @param sourceContainer
     *            Source attribute container.
     * @return The newly created entity.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     * @throws IllegalArgumentException
     *             If the entity ID is already assigned.
     */
    Entity newEntity(UUID id, AttributeContainer sourceContainer);

    /**
     * Creates new entity with the specified ID. This entity is marked as the specified entity type
     * and then wrapped to it.
     *
     *
     * @param id
     *            Entity ID.
     * @param type
     *            Entity type.
     * @return The newly created entity.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     * @throws IllegalArgumentException
     *             If the entity ID is already assigned.
     *
     * @see Entity#markAsType(Class)
     * @see Entities#asType(Entity, Class)
     */
    default  T newEntity(final UUID id, final Class type) {
	return newEntity(id, type, EMPTY_ATTRIBUTECONTAINER);
    }

    /**
     * Creates new entity with the specified ID. This entity is marked as the specified entity type
     * and then wrapped to it.
     *
     *
     * @param id
     *            Entity ID.
     * @param type
     *            Entity type.
     * @param sourceContainer
     *            Source attribute container.
     * @return The newly created entity.
     * @throws IllegalStateException
     *             If the entity limit has been reached.
     * @throws IllegalArgumentException
     *             If the entity ID is already assigned.
     *
     * @see Entity#markAsType(Class)
     * @see Entities#asType(Entity, Class)
     */
     T newEntity(UUID id, Class type, AttributeContainer sourceContainer);

    /**
     * Receives an entity (from a transfer). This method may receive an entity from within or
     * outside the tree.
     *
     * @param e
     *            Entity to receive.
     * @return Whether the entity was received.
     *
     * @see #transferEntity(UUID, EntityContainer)
     */
    boolean receiveEntity(Entity e);

    /**
     * Removes a entity listener.
     *
     * @param listener
     *            Listener to remove.
     *
     * @return {@code true} if the listener was removed.
     * @throws NullPointerException
     *             if listener is null.
     *
     * @see ListenerSet#remove(Object)
     *
     */
    boolean removeEntityListener(EntityListener listener);

    /**
     * Removes all listeners for entities.
     */
    void removeEntityListeners();

    /**
     * Provides a stream of entities from the container.
     *
     * @return A stream of entities in the container.
     */
    Stream streamEntities();

    /**
     * Gets a stream of as the specified type.
     *
     * @param type
     *            Entity type to check for.
     * @return Stream of entities as the type.
     *
     * @see Entity#asType(Class)
     * @see #streamEntities()
     */
    default  Stream streamEntitiesAsType(final Class type) {
	return streamEntities().map(e -> asType(e, type));
    }

    /**
     * Gets a stream of entities marked with the specified type.
     *
     * @param type
     *            Entity type to check for.
     * @return Stream of entities marked with the type.
     *
     * @see Entity#isMarkedAsType(Class)
     * @see Entity#asType(Class)
     * @see #streamEntities()
     */
    default  Stream streamEntitiesOfType(final Class type) {
	return streamEntities().filter(e -> e.isMarkedAsType(type)).map(e -> asType(e, type));
    }

    /**
     * Transfers all entities to the destination.
     *
     * @param destination
     *            Destination to transfer to.
     * @return Entities that could not be transfered.
     *
     * @see #transferEntities(Set, EntityContainer)
     */
    default Set transferAllEntities(final EntityContainer destination) {
	return transferEntities(getEntityIDs(), destination);
    }

    /**
     * Transfers all entities to the destination.
     *
     * @param predicate
     *            Predicate to filter entities.
     * @param destination
     *            Destination to transfer to.
     * @return Entities that could not be transfered.
     */
    default Set transferEntities(final Predicate predicate, final EntityContainer destination) {
	return transferEntities(streamEntities().filter(predicate).map(Entity::getID).collect(Collectors.toSet()),
		destination);
    }

    /**
     * Transfers a number of entities
     *
     * @param entityIDs
     *            Entities to transfer.
     * @param destination
     *            Destination to transfer to.
     * @return Entities that could not be transfered.
     */
    default Set transferEntities(final Set entityIDs, final EntityContainer destination) {
	Objects.requireNonNull(destination);

	final Set notTransfered = new HashSet<>();
	for (final UUID id : entityIDs) {
	    if (!transferEntity(id, destination)) {
		notTransfered.add(id);
	    }
	}
	return notTransfered;
    }

    /**
     * Transfers the entity to the supplied destination container.
     *
     * @param id
     *            Entity ID.
     * @param destination
     *            Target container.
     * @return Whether the entity was transfered.
     *
     * @see #receiveEntity(Entity)
     */
    boolean transferEntity(UUID id, EntityContainer destination);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy