Design um boolsche ausdrücke zu speichern & auszuwerten

zzuegg

Mitglied
Hallo,

Der Titel ist ein wenig wage, da ich das Problem nicht in einem Satz definieren konnte.

Es geht um ein EntitySystem. Zur Zeit habe ich folgendes Design:
Java:
class Object{
 List<Component> components
}

class ObjectEvaluator{
 List<Component> neededComponents
}

Folglich wird der ObjectEvaluator für jedes Object aufgerufen wenn
Java:
Pseudo:
Object.components.contains(ObjectEvaluator.neededComponents)

Das ganze wird intern über einen MapperService zimlich performant gelöst.

Jetzt möchte ich das System erweitern, sodass ich den Evaluatoren einen boolschen Ausdruck anstatt den neededComponents zuweisen kann, zb:
Java:
class ObjectEvaluator{
 //evaluate for all Objects with components: 
 BoolscherAusdruck neededComponents=ComponentA.class && ComponentB.class && (ComponentC.class || ComponentD.class)
}

Hab leider keine Ahnung wie sich sowas implementieren lässt.
Wäre für jeden Ansatz dankbar...
 
Etwas weniger Pseudocode wäre vielleicht hilfreich. Tut's vielleicht schon sowas wie
Java:
interface Evaluator<T> {
    boolean evaluate(T t);
}

class OrEvaluator<T> implements Evaluator<T> {
    private Evaluator<T> e0;    
    private Evaluator<T> e1;
...
    @Override  
    public boolean evaluate(T t) {
        return e0.evaluate(t) || e1.evaluate(t);
    }
}
(analog mit And und Not) ähnlich zu ganz normalen "Predicates", wie man sie in vielen Bibliotheken findet?
 
Hmm, ich versuchs mit weniger pseudo code:

Ich habe folgende classen:

Java:
public abstract class EntityComponent implements Comparable{

    @Override
    public int compareTo(Object o) {
        return(this.getClass().getName().compareTo(o.getClass().getName()));
    }
    
}

Die eigentlichen Componenten schauen dann zb. so aus:

Java:
public class EC_Position extends EntityComponent{
    private Vector3f position;

    public EC_Position(Vector3f position) {
        this.position = position;
    }

    public Vector3f getPosition() {
        return position;
    }

    public void setPosition(Vector3f position) {
        this.position = position;
    }
    
}


public class EC_Movement extends EntityComponent{
    private Vector3f movment;

    public EC_Movement(Vector3f position) {
        this.movment = position;
    }

    public Vector3f getMovment() {
        return movment;
    }


    
}


Hier die basis für alle EntitySysteme:

Java:
public abstract class EntitySystem {

    public enum SystemThreadType {

        RenderThread, EntityThread
    };
    Class[] dependingComponents;
    EntityMonkey entityMonkey;
    SystemThreadType type;
    boolean backgroundEvaluation;
    boolean enabled;

    public EntitySystem(Class[] dependingComponents, EntityMonkey entityMonkey, SystemThreadType type, boolean backgroundEvaluation) {
        this.dependingComponents = dependingComponents;
        this.entityMonkey = entityMonkey;
        this.type = type;
        this.backgroundEvaluation = backgroundEvaluation;
        this.enabled = true;
    }

    public Class[] getDependingComponents() {
        return dependingComponents;
    }

    public EntityMonkey getEntityMonkey() {
        return entityMonkey;
    }

    public boolean isBackgroundEvaluation() {
        return backgroundEvaluation;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public SystemThreadType getType() {
        return type;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    public abstract void evaluate(Entity e, double delta);
}


Der dazu passende MovementUpdater:

Java:
public class ES_MovmentUpdater extends EntitySystem{

    public ES_MovmentUpdater(EntityMonkey entityMonkey) {
        super(new Class[]{EC_Movement.class,EC_MovementUpdate.class}, entityMonkey, SystemThreadType.EntityThread, false);
    }

    @Override
    public void evaluate(Entity e, double delta) {

    }
    
}


Beim Aufruf des super Constructors werden die benötigten Componenten angegeben, (In diesem fall: EC_Movement.class und EC_MovementUpdate.class)

Ich hätte gerne einen Weg, um anstatt des Class Array's einen boolschen Ausdruck vom Typ: 'EC_Movement.class && EC_MovementUpdate.class' mitzugeben. (Oder eben einen etwas komplexeren wie: EC_Movement.class && (EC_MovementUpdate.class || EC_MovementUpdate2.class)
 
Etwas, was in Richtung des schon geposteten ging, könnte da ja nicht verkehrt sein, aber ... muss dann auch in die jeweiligen Klassen gecastet werden (oder muss man noch wissen, welche Class-Objekte dort drinstecken...?)
 

Zurück
Oben