Skip to content

Commit

Permalink
add hook for default base aspect applied to all aspects
Browse files Browse the repository at this point in the history
  • Loading branch information
schosin committed Nov 4, 2019
1 parent 859790b commit 57be9b0
Show file tree
Hide file tree
Showing 18 changed files with 892 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
public class ArchetypeBuilder {
private final Bag<Class<? extends Component>> classes;
private boolean defaults;

/**
* Constructs an archetype builder containing the composition of the specified parent.
Expand Down Expand Up @@ -69,6 +70,21 @@ public ArchetypeBuilder add(Class<? extends Component>... types) {

return this;
}

/**
* Ensure this builder includes the specified component types.
*
* @param types
* @return This instance for chaining.
*/
public ArchetypeBuilder add(Iterable<Class<? extends Component>> types) {
for (Class<? extends Component> type : types) {
if (!classes.contains(type))
classes.add(type);
}

return this;
}

/**
* Remove the specified component from this builder, if it is present (optional operation).
Expand All @@ -94,6 +110,34 @@ public ArchetypeBuilder remove(Class<? extends Component>... types) {

return this;
}

/**
* Remove the specified component from this builder, if it is present (optional operation).
*
* @param types
* @return This instance for chaining.
*/
public ArchetypeBuilder remove(Iterable<Class<? extends Component>> types) {
for (Class<? extends Component> type : types) {
classes.remove(type);
}

return this;
}

/**
* Changes whether the default aspect will be applied to this archetype.
*
* @param defaults
* whether to apply default aspect
*
* @return an archetype that will have the default aspect applied to it
* depending on the value.
*/
public ArchetypeBuilder defaults(boolean defaults) {
this.defaults = defaults;
return this;
}

/**
* Create a new world specific instance of Archetype based on the current state.
Expand All @@ -113,9 +157,13 @@ public Archetype build(World world) {
* @return new Archetype based on current state
*/
public Archetype build(World world, String name) {
ComponentManager cm = world.getComponentManager();
if (defaults) {
add(cm.defaultAspectBuilder.allTypes);
}

ComponentType[] types = resolveTypes(world);

ComponentManager cm = world.getComponentManager();
ComponentMapper[] mappers = new ComponentMapper[types.length];
for (int i = 0, s = mappers.length; s > i; i++) {
mappers[i] = cm.getMapper(types[i].getType());
Expand Down
44 changes: 37 additions & 7 deletions artemis-core/artemis/src/main/java/com/artemis/Aspect.java
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,28 @@ public static Aspect.Builder one(Class<? extends Component>... types) {
public static Aspect.Builder one(Collection<Class<? extends Component>> types) {
return new Builder().one(types);
}

/**
* Changes whether the default aspect will be applied to this aspect.
*
* @param defaults
* whether to apply default aspect
*
* @return an aspect that will have the default aspect applied to it
* depending on the value.
*/
public static Aspect.Builder defaults(boolean defaults) {
return new Builder().defaults(defaults);
}

/**
* Constructs instances of {@link Aspect}.
*/
public static class Builder {
private final Bag<Class<? extends Component>> allTypes;
private final Bag<Class<? extends Component>> exclusionTypes;
private final Bag<Class<? extends Component>> oneTypes;
final Bag<Class<? extends Component>> allTypes;
final Bag<Class<? extends Component>> exclusionTypes;
final Bag<Class<? extends Component>> oneTypes;
boolean defaults = true;

private Builder() {
allTypes = new Bag<Class<? extends Component>>();
Expand Down Expand Up @@ -258,7 +272,7 @@ public Builder copy() {
*
* @return an aspect that can be matched against entities
*/
public Builder all(Collection<Class<? extends Component>> types) {
public Builder all(Iterable<Class<? extends Component>> types) {
for (Class<? extends Component> t : types) {
allTypes.add(t);
}
Expand Down Expand Up @@ -292,7 +306,7 @@ public final Builder one(Class<? extends Component>... types) {
*
* @return an aspect that can be matched against entities
*/
public Builder one(Collection<Class<? extends Component>> types) {
public Builder one(Iterable<Class<? extends Component>> types) {
for (Class<? extends Component> t : types)
oneTypes.add(t);

Expand Down Expand Up @@ -332,12 +346,27 @@ public final Builder exclude(Class<? extends Component>... types) {
*
* @return an aspect that can be matched against entities
*/
public Builder exclude(Collection<Class<? extends Component>> types) {
public Builder exclude(Iterable<Class<? extends Component>> types) {
for (Class<? extends Component> t : types)
exclusionTypes.add(t);

return this;
}

/**
* Changes whether the default aspect will be applied to this aspect.
*
* @param defaults
* whether to apply default aspect
*
* @return an aspect that will have the default aspect applied to it
* depending on the value.
*/
public Builder defaults(boolean defaults) {
this.defaults = defaults;

return this;
}

/**
* Bake an aspect.
Expand All @@ -351,7 +380,7 @@ public Aspect build(World world) {
associate(tf, exclusionTypes, aspect.exclusionSet);
associate(tf, oneTypes, aspect.oneSet);

return aspect;
return defaults ? world.getComponentManager().applyDefaultAspect(aspect) : aspect;
}

private static void associate(ComponentTypeFactory tf, Bag<Class<? extends Component>> types, BitVector componentBits) {
Expand Down Expand Up @@ -391,6 +420,7 @@ public String toString() {
"all=" + append(allTypes) +
", one=" + append(oneTypes) +
", exclude=" + append(exclusionTypes) +
", defaults=" + defaults +
']';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ protected void setWorld(World world) {
super.setWorld(world);

// making sure the first subscription matches all entities
get(all());
get(all().defaults(false));
}

/**
* <p>Gets the entity subscription for the {@link Aspect}.
* Subscriptions are only created once per aspect.</p>
Expand All @@ -60,6 +60,8 @@ protected void setWorld(World world) {
* @return {@link EntitySubscription} for aspect.
*/
public EntitySubscription get(Aspect.Builder builder) {
world.getComponentManager().applyDefaultAspect(builder);

EntitySubscription subscription = subscriptionMap.get(builder);
return (subscription != null) ? subscription : createSubscription(builder);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public class ComponentManager extends BaseSystem {
final ShortBag entityToIdentity;
protected final ComponentTypeFactory typeFactory;

Aspect defaultAspect;
Aspect.Builder defaultAspectBuilder;
private final BitVector tmpVector = new BitVector();
private final Bag<Class<? extends Component>> tmpComponentBag = new Bag<>();


/**
* Creates a new instance of {@link ComponentManager}.
*/
Expand Down Expand Up @@ -74,7 +80,6 @@ static <T extends Component> T newInstance(Class<T> componentClass) {
}
}


/**
* Removes all components from deleted entities.
*
Expand Down Expand Up @@ -274,4 +279,69 @@ int allocateIdentity(BitVector componentBits, ComponentManager cm) {
return compositionBits.size() - 1;
}
}

public Aspect.Builder applyDefaultAspect(Aspect.Builder builder) {
if (defaultAspectBuilder == null || !builder.defaults) {
return builder;
}

tmpComponentBag.clear();
tmpComponentBag.addAll(defaultAspectBuilder.allTypes);
tmpComponentBag.removeAll(builder.allTypes);
tmpComponentBag.removeAll(builder.oneTypes);
tmpComponentBag.removeAll(builder.exclusionTypes);
builder.all(tmpComponentBag);

tmpComponentBag.clear();
tmpComponentBag.addAll(defaultAspectBuilder.oneTypes);
tmpComponentBag.removeAll(builder.allTypes);
tmpComponentBag.removeAll(builder.oneTypes);
tmpComponentBag.removeAll(builder.exclusionTypes);
builder.one(tmpComponentBag);

tmpComponentBag.clear();
tmpComponentBag.addAll(defaultAspectBuilder.exclusionTypes);
tmpComponentBag.removeAll(builder.allTypes);
tmpComponentBag.removeAll(builder.oneTypes);
tmpComponentBag.removeAll(builder.exclusionTypes);
builder.exclude(tmpComponentBag);

return builder;
}

public Aspect applyDefaultAspect(Aspect aspect) {
if (defaultAspect == null) {
return aspect;
}

tmpVector.clear();
tmpVector.or(defaultAspect.allSet);
tmpVector.andNot(aspect.oneSet);
tmpVector.andNot(aspect.exclusionSet);
aspect.allSet.or(tmpVector);

tmpVector.clear();
tmpVector.or(defaultAspect.oneSet);
tmpVector.andNot(aspect.allSet);
tmpVector.andNot(aspect.exclusionSet);
aspect.oneSet.or(tmpVector);

tmpVector.clear();
tmpVector.or(defaultAspect.exclusionSet);
tmpVector.andNot(aspect.allSet);
tmpVector.andNot(aspect.oneSet);
aspect.exclusionSet.or(tmpVector);

return aspect;
}

void setDefaultAspect(Aspect.Builder aspect) {
if (aspect != null) {
this.defaultAspectBuilder = aspect;
this.defaultAspect = aspect.build(world);
tmpVector.ensureCapacity(defaultAspect.allSet.length());
tmpVector.ensureCapacity(defaultAspect.oneSet.length());
tmpVector.ensureCapacity(defaultAspect.exclusionSet.length());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public final class EntityTransmuter {
private final ShortBag entityToIdentity;

public EntityTransmuter(World world, Aspect.Builder aspect) {
this(world, world.getAspectSubscriptionManager().get(aspect).getAspect());
this(world, world.getAspectSubscriptionManager().get(aspect.defaults(false)).getAspect());
}

EntityTransmuter(World world, Aspect aspect) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public final class WorldConfiguration {

private boolean alwaysDelayComponentRemoval = false;
private Set<Class<? extends BaseSystem>> registered = new HashSet<Class<? extends BaseSystem>>();
private Aspect.Builder defaultAspect;

public WorldConfiguration() {
// reserving space for core managers
Expand Down Expand Up @@ -162,7 +163,11 @@ void initialize(World world, Injector injector, AspectSubscriptionManager asm) {

world.invocationStrategy = invocationStrategy;

systems.set(COMPONENT_MANAGER_IDX, world.getComponentManager());
ComponentManager cm = world.getComponentManager();
cm.setWorld(world);
cm.setDefaultAspect(defaultAspect);

systems.set(COMPONENT_MANAGER_IDX, cm);
systems.set(ENTITY_MANAGER_IDX, world.getEntityManager());
systems.set(ASPECT_SUBSCRIPTION_MANAGER_IDX, asm);

Expand All @@ -172,7 +177,7 @@ void initialize(World world, Injector injector, AspectSubscriptionManager asm) {
if (ClassReflection.isInstance(Manager.class, system)) {
((Manager) system).registerManager();
}
}
}

injector.initialize(world, injectables);

Expand Down Expand Up @@ -222,4 +227,16 @@ public boolean isAlwaysDelayComponentRemoval() {
public void setAlwaysDelayComponentRemoval(boolean value) {
this.alwaysDelayComponentRemoval = value;
}

/**
* Sets the default aspect to be applied to all aspects unless explicitly set to not do so.
*
* @param aspect default aspect
* @return
* @return this
*/
public WorldConfiguration setDefaultAspect(Aspect.Builder aspect) {
this.defaultAspect = aspect;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class WorldConfigurationBuilder {
private ArtemisPlugin activePlugin;
private final InjectionCache cache;
private SystemInvocationStrategy invocationStrategy;
private Aspect.Builder defaultAspect;

public WorldConfigurationBuilder() {
reset();
Expand All @@ -46,6 +47,7 @@ public WorldConfiguration build() {
registerFieldResolvers(config);
registerInvocationStrategies(config);
config.setAlwaysDelayComponentRemoval(alwaysDelayComponentRemoval);
config.setDefaultAspect(defaultAspect);
reset();
return config;
}
Expand Down Expand Up @@ -266,6 +268,17 @@ public WorldConfigurationBuilder with(ArtemisPlugin... plugins) {
addPlugins(plugins);
return this;
}

/**
* Sets the default aspect to be applied to all aspects unless explicitly set to not do so.
*
* @param aspect default aspect
* @return this
*/
public WorldConfigurationBuilder defaultAspect(Aspect.Builder aspect) {
this.defaultAspect = aspect;
return this;
}

/**
* helper to queue systems for registration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@
* @return excluding types
*/
Class<? extends Component>[] exclude() default {};

/**
* @return whether to apply default aspect
*/
boolean defaults() default true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,9 @@
*/
Class<? extends Component>[] value() default {};

/**
* @return whether to exclude default aspect
*/
boolean excludeDefaults() default false;

}
Loading

0 comments on commit 57be9b0

Please sign in to comment.