org.qbicc.facts.Condition Maven / Gradle / Ivy
package org.qbicc.facts;
import java.util.function.ObjLongConsumer;
/**
* A condition that, when met, triggers the execution of an action.
*
* @param the fact type
*/
public abstract class Condition> {
Condition() {}
/**
* A condition which is true when the given fact is present.
*
* @param fact the fact
* @param the fact type
* @return the condition
*/
public static > Condition when(F fact) {
return new Of<>(fact);
}
/**
* A condition which is true when all of the given facts are present.
*
* @param fact1 the first fact
* @param fact2 the second fact
* @param the fact type
* @return the condition
*/
public static > Condition whenAll(F fact1, F fact2) {
return new All2<>(fact1, fact2);
}
/**
* A condition which is true when all of the given facts are present.
*
* @param fact1 the first fact
* @param fact2 the second fact
* @param fact3 the second fact
* @param the fact type
* @return the condition
*/
public static > Condition whenAll(F fact1, F fact2, F fact3) {
return new All3<>(fact1, fact2, fact3);
}
/**
* A condition which is true when all of the given facts are present.
*
* @param facts the facts
* @param the fact type
* @return the condition
*/
@SafeVarargs
public static > Condition whenAll(F... facts) {
return new AllMany<>(facts);
}
/**
* A condition which is true when any of the given facts are present.
*
* @param fact1 the first fact
* @param fact2 the second fact
* @param the fact type
* @return the condition
*/
public static > Condition whenAny(F fact1, F fact2) {
return new Any2<>(fact1, fact2);
}
/**
* A condition which is true when any of the given facts are present.
*
* @param fact1 the first fact
* @param fact2 the second fact
* @param fact3 the third fact
* @param the fact type
* @return the condition
*/
public static > Condition whenAny(F fact1, F fact2, F fact3) {
return new Any3<>(fact1, fact2, fact3);
}
/**
* A condition which is true when any of the given facts are present.
*
* @param facts the facts
* @param the fact type
* @return the condition
*/
@SafeVarargs
public static > Condition whenAny(F... facts) {
return new AnyMany<>(facts);
}
/**
* Get a condition which is true when both this condition and the given condition are true.
*
* @param other the other condition
* @return the new condition
*/
public Condition and(Condition other) {
return new And(this, other);
}
/**
* Get a condition which is true when either this condition or the given condition are true.
*
* @param other the other condition
* @return the new condition
*/
public Condition or(Condition other) {
return new Or(this, other);
}
abstract ObjLongConsumer getRegisterFunction(ObjLongConsumer next);
static class Of> extends Condition {
final F fact1;
Of(F fact1) {
this.fact1 = fact1;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> next.accept(holder, bits | 1L << holder.getFactIndex(fact1));
}
}
static class Any2> extends Of {
final F fact2;
Any2(F fact1, F fact2) {
super(fact1);
this.fact2 = fact2;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> {
next.accept(holder, bits | 1L << holder.getFactIndex(fact1));
next.accept(holder, bits | 1L << holder.getFactIndex(fact2));
};
}
}
static class Any3> extends Any2 {
final F fact3;
Any3(F fact1, F fact2, F fact3) {
super(fact1, fact2);
this.fact3 = fact3;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> {
next.accept(holder, bits | 1L << holder.getFactIndex(fact1));
next.accept(holder, bits | 1L << holder.getFactIndex(fact2));
next.accept(holder, bits | 1L << holder.getFactIndex(fact3));
};
}
}
static class AnyMany> extends Condition {
final F[] facts;
AnyMany(F[] facts) {
this.facts = facts;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> {
for (F fact : facts) {
next.accept(holder, bits | 1L << holder.getFactIndex(fact));
}
};
}
}
static class All2> extends Of {
final F fact2;
All2(F fact1, F fact2) {
super(fact1);
this.fact2 = fact2;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> next.accept(holder, bits | 1L << holder.getFactIndex(fact1) | 1L << holder.getFactIndex(fact2));
}
}
static class All3> extends All2 {
final F fact3;
All3(F fact1, F fact2, F fact3) {
super(fact1, fact2);
this.fact3 = fact3;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> next.accept(holder, bits | 1L << holder.getFactIndex(fact1) | 1L << holder.getFactIndex(fact2) | 1L << holder.getFactIndex(fact3));
}
}
static class AllMany> extends Condition {
final F[] facts;
AllMany(F[] facts) {
this.facts = facts;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return (holder, bits) -> {
for (F fact : facts) {
bits |= 1L << holder.getFactIndex(fact);
}
next.accept(holder, bits);
};
}
}
static class Or> extends Condition {
private final Condition cond1;
private final Condition cond2;
Or(Condition cond1, Condition cond2) {
this.cond1 = cond1;
this.cond2 = cond2;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
var f1 = cond1.getRegisterFunction(next);
var f2 = cond2.getRegisterFunction(next);
return (holder, bits) -> {
f1.accept(holder, bits);
f2.accept(holder, bits);
};
}
}
static class And> extends Condition {
private final Condition cond1;
private final Condition cond2;
And(Condition cond1, Condition cond2) {
this.cond1 = cond1;
this.cond2 = cond2;
}
@Override
ObjLongConsumer getRegisterFunction(ObjLongConsumer next) {
return cond1.getRegisterFunction(cond2.getRegisterFunction(next));
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy