-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
136 additions
and
0 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
cardshifter-core/src/main/java/net/zomis/cardshifter/ecs/base/Retriever.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package net.zomis.cardshifter.ecs.base; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(value = RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
public @interface Retriever { | ||
} |
11 changes: 11 additions & 0 deletions
11
cardshifter-core/src/main/java/net/zomis/cardshifter/ecs/base/RetrieverSingleton.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package net.zomis.cardshifter.ecs.base; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Retention(value = RetentionPolicy.RUNTIME) | ||
@Target(ElementType.FIELD) | ||
public @interface RetrieverSingleton { | ||
} |
75 changes: 75 additions & 0 deletions
75
cardshifter-core/src/main/java/net/zomis/cardshifter/ecs/base/Retrievers.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package net.zomis.cardshifter.ecs.base; | ||
|
||
import java.lang.reflect.Field; | ||
import java.lang.reflect.ParameterizedType; | ||
import java.lang.reflect.Type; | ||
import java.util.Arrays; | ||
import java.util.Set; | ||
|
||
public class Retrievers { | ||
|
||
public static <T extends Component> ComponentRetriever<T> component(Class<T> clazz) { | ||
return new ComponentRetriever<>(clazz); | ||
} | ||
|
||
public static <T extends Component> ComponentRetriever<T> singleton(Class<T> class1) { | ||
return new ComponentRetriever<T>(null) { | ||
|
||
@Override | ||
public boolean has(Entity entity) { | ||
return get(entity) != null; | ||
} | ||
|
||
@Override | ||
public T get(Entity entity) { | ||
return singleton(entity.getGame(), class1); | ||
} | ||
|
||
}; | ||
} | ||
|
||
public static <T extends Component> T singleton(ECSGame game, Class<T> class1) { | ||
Set<Entity> all = game.getEntitiesWithComponent(class1); | ||
if (all.size() != 1) { | ||
throw new IllegalStateException("Expected to find exactly one " + class1.getSimpleName() + ", found " + all.size()); | ||
} | ||
return all.iterator().next().getComponent(class1); | ||
} | ||
|
||
public static void inject(Object object, ECSGame game) { | ||
Field[] fields = object.getClass().getDeclaredFields(); | ||
Arrays.stream(fields).filter(field -> field.getAnnotation(Retriever.class) != null).forEach(field -> injectField(object, field, game)); | ||
Arrays.stream(fields).filter(field -> field.getAnnotation(RetrieverSingleton.class) != null).forEach(field -> injectSingleton(object, field, game)); | ||
} | ||
|
||
private static void injectSingleton(Object obj, Field field, ECSGame game) { | ||
Class<? extends Component> clazz = field.getType().asSubclass(Component.class); | ||
field.setAccessible(true); | ||
try { | ||
field.set(obj, Retrievers.singleton(game, clazz)); | ||
} catch (IllegalArgumentException | IllegalAccessException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static void injectField(Object obj, Field field, ECSGame game) { | ||
if (field.getType() != ComponentRetriever.class) { | ||
throw new RuntimeException(field.getType() + " is not a ComponentRetriever"); | ||
} | ||
|
||
Type genericFieldType = field.getGenericType(); | ||
|
||
if(genericFieldType instanceof ParameterizedType){ | ||
ParameterizedType aType = (ParameterizedType) genericFieldType; | ||
Type[] fieldArgTypes = aType.getActualTypeArguments(); | ||
Class<?> fieldArgClass = (Class<?>) fieldArgTypes[0]; | ||
try { | ||
field.setAccessible(true); | ||
field.set(obj, Retrievers.component(fieldArgClass.asSubclass(Component.class))); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} | ||
|
||
} |
39 changes: 39 additions & 0 deletions
39
cardshifter-core/src/test/java/net/zomis/cardshifter/ecs/InjectionTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package net.zomis.cardshifter.ecs; | ||
|
||
import static org.junit.Assert.*; | ||
import net.zomis.cardshifter.ecs.base.ComponentRetriever; | ||
import net.zomis.cardshifter.ecs.base.ECSGame; | ||
import net.zomis.cardshifter.ecs.base.Entity; | ||
import net.zomis.cardshifter.ecs.base.Retriever; | ||
import net.zomis.cardshifter.ecs.base.RetrieverSingleton; | ||
import net.zomis.cardshifter.ecs.base.Retrievers; | ||
import net.zomis.cardshifter.ecs.components.PlayerComponent; | ||
import net.zomis.cardshifter.ecs.phase.Phase; | ||
import net.zomis.cardshifter.ecs.phase.PhaseController; | ||
|
||
import org.junit.Test; | ||
|
||
public class InjectionTest { | ||
|
||
@RetrieverSingleton | ||
private PhaseController phases; | ||
|
||
@Retriever | ||
private ComponentRetriever<PlayerComponent> playerData; | ||
|
||
@Test | ||
public void inject() { | ||
ECSGame game = new ECSGame(); | ||
PhaseController phase = new PhaseController(); | ||
phase.addPhase(new Phase(null, "Main")); | ||
game.newEntity().addComponent(phase); | ||
Entity player = game.newEntity().addComponent(new PlayerComponent(42, "Tester")); | ||
|
||
Retrievers.inject(this, game); | ||
|
||
assertEquals(42, playerData.get(player).getIndex()); | ||
assertEquals(phase, phases); | ||
assertEquals("Main", phases.getCurrentPhase().getName()); | ||
} | ||
|
||
} |