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

com.artemis.Aspect Maven / Gradle / Ivy

package com.artemis;

import java.util.BitSet;
import java.util.Collection;

import com.artemis.utils.Bag;


/**
 * An Aspect is used by systems as a matcher against entities, to check if a
 * system is interested in an entity.
 * 

* Aspects define what sort of component types an entity must possess, or not * possess. *

* This creates an aspect where an entity must possess A and B and C:
* {@code Aspect.all(A.class, B.class, C.class)} *

* This creates an aspect where an entity must possess A and B and C, but must * not possess U or V.
* {@code Aspect.all(A.class, B.class, C.class).exclude(U.class, V.class)} *

* This creates an aspect where an entity must possess A and B and C, but must * not possess U or V, but must possess one of X or Y or Z.
* {@code Aspect.all(A.class, B.class, C.class).exclude(U.class, V.class).one(X.class, Y.class, Z.class)} *

* You can create and compose aspects in many ways:
* {@code Aspect.one(X.class, Y.class, Z.class).all(A.class, B.class, C.class).exclude(U.class, V.class)}
* is the same as:
* {@code Aspect.all(A.class, B.class, C.class).exclude(U.class, V.class).one(X.class, Y.class, Z.class)} *

* * @author Arni Arent */ public class Aspect { /** Component bits the entity must all possess. */ private BitSet allSet; /** Component bits the entity must not possess. */ private BitSet exclusionSet; /** Component bits of which the entity must possess at least one. */ private BitSet oneSet; private Aspect() { this.allSet = new BitSet(); this.exclusionSet = new BitSet(); this.oneSet = new BitSet(); } /** * Get a BitSet containing bits of components the entity must all possess. * * @return * the "all" BitSet */ public BitSet getAllSet() { return allSet; } /** * Get a BitSet containing bits of components the entity must not possess. * * @return * the "exclusion" BitSet */ public BitSet getExclusionSet() { return exclusionSet; } /** * Get a BitSet containing bits of components of which the entity must * possess atleast one. * * @return * the "one" BitSet */ public BitSet getOneSet() { return oneSet; } /** * Returns whether this Aspect would accept the given Entity. */ public boolean isInterested(Entity e){ return isInterested(e.getComponentBits()); } /** * Returns whether this Aspect would accept the given set. */ public boolean isInterested(BitSet componentBits){ // Check if the entity possesses ALL of the components defined in the aspect. if(!allSet.isEmpty()) { for (int i = allSet.nextSetBit(0); i >= 0; i = allSet.nextSetBit(i+1)) { if(!componentBits.get(i)) { return false; } } } // If we are STILL interested, // Check if the entity possesses ANY of the exclusion components, if it does then the system is not interested. if(!exclusionSet.isEmpty() && exclusionSet.intersects(componentBits)) { return false; } // If we are STILL interested, // Check if the entity possesses ANY of the components in the oneSet. If so, the system is interested. if(!oneSet.isEmpty() && !oneSet.intersects(componentBits)) { return false; } return true; } /** * Returns an aspect where an entity must possess all of the specified * component types. * * @param types * a required component type * * @return an aspect that can be matched against entities */ @SafeVarargs public static final Aspect.Builder all(Class... types) { return new Builder().all(types); } /** * Returns an aspect where an entity must possess all of the specified * component types. * * @param types * a required component type * * @return an aspect that can be matched against entities */ public static Aspect.Builder all(Collection> types) { return new Builder().all(types); } /** * Excludes all of the specified component types from the aspect. *

* A system will not be interested in an entity that possesses one of the * specified exclusion component types. *

* * @param types * component type to exclude * * @return an aspect that can be matched against entities */ @SafeVarargs public static final Aspect.Builder exclude(Class... types) { return new Builder().exclude(types); } /** * Excludes all of the specified component types from the aspect. *

* A system will not be interested in an entity that possesses one of the * specified exclusion component types. *

* * @param types * component type to exclude * * @return an aspect that can be matched against entities */ public static Aspect.Builder exclude(Collection> types) { return new Builder().exclude(types); } /** * Returns an aspect where an entity must possess one of the specified * component types. * * @param types * one of the types the entity must possess * * @return an aspect that can be matched against entities */ @SafeVarargs public static final Aspect.Builder one(Class... types) { return new Builder().one(types); } /** * Returns an aspect where an entity must possess one of the specified * component types. * * @param types * one of the types the entity must possess * * @return an aspect that can be matched against entities */ public static Aspect.Builder one(Collection> types) { return new Builder().one(types); } /** * Creates an aspect where an entity must possess all of the specified * component types. * * @param types * a required component type * * @return an aspect that can be matched against entities * @deprecated see {@link #all(Class[])} */ @Deprecated @SafeVarargs public static final Aspect.Builder getAspectForAll(Class... types) { return all(types); } /** * Creates an aspect where an entity must possess one of the specified * component types. * * @param types * one of the types the entity must possess * * @return an aspect that can be matched against entities * @deprecated see {@link #one(Class[])} */ @Deprecated @SafeVarargs public static final Aspect.Builder getAspectForOne(Class... types) { return one(types); } /** * Creates an aspect that matches all entities. * * Prior to version 0.9.0, this method returned an aspect which matched no entities. * * @return an empty Aspect that will reject all entities * @deprecated extend {@link com.artemis.BaseSystem} instead of {@link com.artemis.EntitySystem} for entity-less systems. */ @Deprecated public static Aspect.Builder getEmpty() { return new Aspect.Builder(); } public static class Builder { private final Bag> allTypes; private final Bag> exclusionTypes; private final Bag> oneTypes; private Builder() { allTypes = new Bag>(); exclusionTypes = new Bag>(); oneTypes = new Bag>(); } /** * Returns an aspect where an entity must possess all of the specified * component types. * * @param types * a required component type * * @return an aspect that can be matched against entities */ public Builder all(Class... types) { for (Class t : types) { allTypes.add(t); } return this; } /** * Returns an aspect where an entity must possess all of the specified * component types. * * @param types * a required component type * * @return an aspect that can be matched against entities */ public Builder all(Collection> types) { for (Class t : types) { allTypes.add(t); } return this; } /** * Returns an aspect where an entity must possess one of the specified * component types. * * @param types * one of the types the entity must possess * * @return an aspect that can be matched against entities */ public Builder one(Class... types) { for (Class t : types) oneTypes.add(t); return this; } /** * Returns an aspect where an entity must possess one of the specified * component types. * * @param types * one of the types the entity must possess * * @return an aspect that can be matched against entities */ public Builder one(Collection> types) { for (Class t : types) oneTypes.add(t); return this; } /** * Excludes all of the specified component types from the aspect. *

* A system will not be interested in an entity that possesses one of the * specified exclusion component types. *

* * @param types * component type to exclude * * @return an aspect that can be matched against entities */ public Builder exclude(Class... types) { for (Class t : types) exclusionTypes.add(t); return this; } /** * Excludes all of the specified component types from the aspect. *

* A system will not be interested in an entity that possesses one of the * specified exclusion component types. *

* * @param types * component type to exclude * * @return an aspect that can be matched against entities */ public Builder exclude(Collection> types) { for (Class t : types) exclusionTypes.add(t); return this; } public Aspect build(World world) { ComponentTypeFactory tf = world.getComponentManager().typeFactory; Aspect aspect = new Aspect(); associate(tf, allTypes, aspect.allSet); associate(tf, exclusionTypes, aspect.exclusionSet); associate(tf, oneTypes, aspect.oneSet); return aspect; } private static void associate(ComponentTypeFactory tf, Bag> types, BitSet componentBits) { for (Class t : types) { componentBits.set(tf.getIndexFor(t)); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Builder builder = (Builder) o; if (!allTypes.equals(builder.allTypes)) return false; if (!exclusionTypes.equals(builder.exclusionTypes)) return false; if (!oneTypes.equals(builder.oneTypes)) return false; return true; } @Override public int hashCode() { int result = allTypes.hashCode(); result = 31 * result + exclusionTypes.hashCode(); result = 31 * result + oneTypes.hashCode(); return result; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy