mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
More simpler
- Remove Plan#simplify and associated tests - Neat idea but ineffective in practice - Should reduce the user burden of implementing plans
This commit is contained in:
parent
bd70b89621
commit
c931e84b65
10 changed files with 2 additions and 239 deletions
|
@ -38,12 +38,4 @@ public interface Plan<C> {
|
||||||
* @return The composed plan.
|
* @return The composed plan.
|
||||||
*/
|
*/
|
||||||
Plan<C> and(Plan<C> plan);
|
Plan<C> and(Plan<C> plan);
|
||||||
|
|
||||||
/**
|
|
||||||
* If possible, create a new plan that accomplishes everything
|
|
||||||
* this plan does but with a simpler execution schedule.
|
|
||||||
*
|
|
||||||
* @return A simplified plan, or this.
|
|
||||||
*/
|
|
||||||
Plan<C> simplify();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
||||||
effects = new VisualManagerImpl<>(effectsStorage);
|
effects = new VisualManagerImpl<>(effectsStorage);
|
||||||
|
|
||||||
tickPlan = NestedPlan.of(blockEntities.tickPlan(), entities.tickPlan(), effects.tickPlan())
|
tickPlan = NestedPlan.of(blockEntities.tickPlan(), entities.tickPlan(), effects.tickPlan())
|
||||||
.then(RaisePlan.raise(tickFlag))
|
.then(RaisePlan.raise(tickFlag));
|
||||||
.simplify();
|
|
||||||
|
|
||||||
var recreate = SimplePlan.<RenderContext>of(context -> blockEntitiesStorage.recreateAll(context.partialTick()),
|
var recreate = SimplePlan.<RenderContext>of(context -> blockEntitiesStorage.recreateAll(context.partialTick()),
|
||||||
context -> entitiesStorage.recreateAll(context.partialTick()),
|
context -> entitiesStorage.recreateAll(context.partialTick()),
|
||||||
|
@ -111,8 +110,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
||||||
.plan()
|
.plan()
|
||||||
.then(RaisePlan.raise(frameVisualsFlag))
|
.then(RaisePlan.raise(frameVisualsFlag))
|
||||||
.then(engine.createFramePlan())
|
.then(engine.createFramePlan())
|
||||||
.then(RaisePlan.raise(frameFlag))
|
.then(RaisePlan.raise(frameFlag));
|
||||||
.simplify();
|
|
||||||
|
|
||||||
if (level instanceof Level l) {
|
if (level instanceof Level l) {
|
||||||
LevelExtension.getAllLoadedEntities(l)
|
LevelExtension.getAllLoadedEntities(l)
|
||||||
|
|
|
@ -13,18 +13,4 @@ public record BarrierPlan<C>(Plan<C> first, Plan<C> second) implements SimplyCom
|
||||||
first.execute(taskExecutor, context, () -> second.execute(taskExecutor, context, onCompletion));
|
first.execute(taskExecutor, context, () -> second.execute(taskExecutor, context, onCompletion));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Plan<C> simplify() {
|
|
||||||
var first = this.first.simplify();
|
|
||||||
var second = this.second.simplify();
|
|
||||||
|
|
||||||
if (first == UnitPlan.of()) {
|
|
||||||
return second;
|
|
||||||
}
|
|
||||||
if (second == UnitPlan.of()) {
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BarrierPlan<>(first, second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,19 +30,6 @@ public record IfElsePlan<C>(BooleanSupplierWithContext<C> condition, Plan<C> onT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Plan<C> simplify() {
|
|
||||||
var maybeSimplifiedTrue = onTrue.simplify();
|
|
||||||
var maybeSimplifiedFalse = onFalse.simplify();
|
|
||||||
|
|
||||||
if (maybeSimplifiedTrue instanceof UnitPlan && maybeSimplifiedFalse instanceof UnitPlan) {
|
|
||||||
// The condition may have side effects that still need to be evaluated.
|
|
||||||
return SimplePlan.of(condition::test);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new IfElsePlan<>(condition, maybeSimplifiedTrue, maybeSimplifiedFalse);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder<C> {
|
public static class Builder<C> {
|
||||||
private final BooleanSupplierWithContext<C> condition;
|
private final BooleanSupplierWithContext<C> condition;
|
||||||
private Plan<C> onTrue = UnitPlan.of();
|
private Plan<C> onTrue = UnitPlan.of();
|
||||||
|
|
|
@ -19,17 +19,6 @@ public record MapContextPlan<C, D>(SupplierWithContext<C, D> map, Plan<D> plan)
|
||||||
plan.execute(taskExecutor, newContext, onCompletion);
|
plan.execute(taskExecutor, newContext, onCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Plan<C> simplify() {
|
|
||||||
var maybeSimplified = plan.simplify();
|
|
||||||
|
|
||||||
if (maybeSimplified instanceof UnitPlan) {
|
|
||||||
return UnitPlan.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new MapContextPlan<>(map, maybeSimplified);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder<C, D> {
|
public static class Builder<C, D> {
|
||||||
private final SupplierWithContext<C, D> map;
|
private final SupplierWithContext<C, D> map;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package com.jozufozu.flywheel.lib.task;
|
package com.jozufozu.flywheel.lib.task;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.api.task.Plan;
|
import com.jozufozu.flywheel.api.task.Plan;
|
||||||
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
import com.jozufozu.flywheel.api.task.TaskExecutor;
|
||||||
import com.jozufozu.flywheel.lib.task.functional.RunnableWithContext;
|
|
||||||
|
|
||||||
public record NestedPlan<C>(List<Plan<C>> parallelPlans) implements SimplyComposedPlan<C> {
|
public record NestedPlan<C>(List<Plan<C>> parallelPlans) implements SimplyComposedPlan<C> {
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
|
@ -44,61 +41,4 @@ public record NestedPlan<C>(List<Plan<C>> parallelPlans) implements SimplyCompos
|
||||||
.build());
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Plan<C> simplify() {
|
|
||||||
if (parallelPlans.isEmpty()) {
|
|
||||||
return UnitPlan.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parallelPlans.size() == 1) {
|
|
||||||
return parallelPlans.get(0)
|
|
||||||
.simplify();
|
|
||||||
}
|
|
||||||
|
|
||||||
var simplifiedTasks = new ArrayList<RunnableWithContext<C>>();
|
|
||||||
var simplifiedPlans = new ArrayList<Plan<C>>();
|
|
||||||
var toVisit = new ArrayDeque<>(parallelPlans);
|
|
||||||
while (!toVisit.isEmpty()) {
|
|
||||||
var plan = toVisit.pop()
|
|
||||||
.simplify();
|
|
||||||
|
|
||||||
if (plan == UnitPlan.of()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plan instanceof SimplePlan<C> simplePlan) {
|
|
||||||
// merge all simple plans into one
|
|
||||||
simplifiedTasks.addAll(simplePlan.parallelTasks());
|
|
||||||
} else if (plan instanceof NestedPlan<C> nestedPlan) {
|
|
||||||
// inline and re-visit nested plans
|
|
||||||
toVisit.addAll(nestedPlan.parallelPlans());
|
|
||||||
} else {
|
|
||||||
// /shrug
|
|
||||||
simplifiedPlans.add(plan);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simplifiedTasks.isEmpty() && simplifiedPlans.isEmpty()) {
|
|
||||||
// everything got simplified away
|
|
||||||
return UnitPlan.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simplifiedTasks.isEmpty()) {
|
|
||||||
// no simple plan to create
|
|
||||||
if (simplifiedPlans.size() == 1) {
|
|
||||||
// we only contained one complex plan, so we can just return that
|
|
||||||
return simplifiedPlans.get(0);
|
|
||||||
}
|
|
||||||
return new NestedPlan<>(simplifiedPlans);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (simplifiedPlans.isEmpty()) {
|
|
||||||
// we only contained simple plans, so we can just return one
|
|
||||||
return SimplePlan.of(simplifiedTasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we have both simple and complex plans, so we need to create a nested plan
|
|
||||||
simplifiedPlans.add(SimplePlan.of(simplifiedTasks));
|
|
||||||
return new NestedPlan<>(simplifiedPlans);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,4 @@ public record SimplePlan<C>(List<RunnableWithContext<C>> parallelTasks) implemen
|
||||||
return SimplyComposedPlan.super.and(plan);
|
return SimplyComposedPlan.super.and(plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Plan<C> simplify() {
|
|
||||||
if (parallelTasks.isEmpty()) {
|
|
||||||
return UnitPlan.of();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,4 @@ public interface SimplyComposedPlan<C> extends Plan<C> {
|
||||||
return NestedPlan.of(this, plan);
|
return NestedPlan.of(this, plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
default Plan<C> simplify() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,4 @@ public class UnitPlan<C> implements Plan<C> {
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Plan<C> simplify() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
package com.jozufozu.flywheel.lib.task;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.task.Plan;
|
|
||||||
import com.jozufozu.flywheel.lib.task.functional.RunnableWithContext;
|
|
||||||
import com.jozufozu.flywheel.lib.util.Unit;
|
|
||||||
|
|
||||||
public class PlanSimplificationTest {
|
|
||||||
|
|
||||||
public static final RunnableWithContext.Ignored<Unit> NOOP = () -> {
|
|
||||||
};
|
|
||||||
public static final Plan<Unit> SIMPLE = SimplePlan.of(NOOP);
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void emptyPlans() {
|
|
||||||
var empty = NestedPlan.of();
|
|
||||||
Assertions.assertEquals(empty.simplify(), UnitPlan.of());
|
|
||||||
|
|
||||||
var simpleEmpty = SimplePlan.of();
|
|
||||||
Assertions.assertEquals(simpleEmpty.simplify(), UnitPlan.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void nestedSimplePlans() {
|
|
||||||
var twoSimple = NestedPlan.of(SimplePlan.of(NOOP, NOOP, NOOP), SIMPLE);
|
|
||||||
Assertions.assertEquals(twoSimple.simplify(), SimplePlan.of(NOOP, NOOP, NOOP, NOOP));
|
|
||||||
|
|
||||||
var threeSimple = NestedPlan.of(SIMPLE, SIMPLE, SIMPLE);
|
|
||||||
Assertions.assertEquals(threeSimple.simplify(), SimplePlan.of(NOOP, NOOP, NOOP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void oneNestedPlan() {
|
|
||||||
var oneSimple = NestedPlan.of(SIMPLE);
|
|
||||||
|
|
||||||
Assertions.assertEquals(oneSimple.simplify(), SIMPLE);
|
|
||||||
|
|
||||||
var mainThreadNoop = new SyncedPlan<>(NOOP);
|
|
||||||
var oneMainThread = NestedPlan.of(mainThreadNoop);
|
|
||||||
|
|
||||||
Assertions.assertEquals(oneMainThread.simplify(), mainThreadNoop);
|
|
||||||
|
|
||||||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
|
||||||
var oneBarrier = NestedPlan.of(barrier);
|
|
||||||
|
|
||||||
Assertions.assertEquals(oneBarrier.simplify(), barrier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void nestedNestedPlan() {
|
|
||||||
var outer = NestedPlan.of(SIMPLE);
|
|
||||||
var outermost = NestedPlan.of(outer);
|
|
||||||
|
|
||||||
Assertions.assertEquals(outermost.simplify(), SIMPLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void nestedUnitPlan() {
|
|
||||||
var onlyUnit = NestedPlan.of(UnitPlan.of(), UnitPlan.of(), UnitPlan.of());
|
|
||||||
Assertions.assertEquals(onlyUnit.simplify(), UnitPlan.of());
|
|
||||||
|
|
||||||
var unitAndSimple = NestedPlan.of(UnitPlan.of(), UnitPlan.of(), SIMPLE);
|
|
||||||
Assertions.assertEquals(unitAndSimple.simplify(), SIMPLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void complexNesting() {
|
|
||||||
var mainThreadNoop = SyncedPlan.<Unit>of(() -> {
|
|
||||||
});
|
|
||||||
|
|
||||||
var nested = NestedPlan.of(mainThreadNoop, SIMPLE);
|
|
||||||
Assertions.assertEquals(nested.simplify(), nested); // cannot simplify
|
|
||||||
|
|
||||||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
|
||||||
var complex = NestedPlan.of(barrier, nested);
|
|
||||||
Assertions.assertEquals(complex.simplify(), NestedPlan.of(barrier, mainThreadNoop, SIMPLE));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void nestedNoSimple() {
|
|
||||||
var mainThreadNoop = SyncedPlan.<Unit>of(() -> {
|
|
||||||
});
|
|
||||||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
|
||||||
var oneMainThread = NestedPlan.of(mainThreadNoop, NestedPlan.of(mainThreadNoop, barrier, barrier));
|
|
||||||
|
|
||||||
Assertions.assertEquals(oneMainThread.simplify(), NestedPlan.of(mainThreadNoop, mainThreadNoop, barrier, barrier));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void manyNestedButJustOneAfterSimplification() {
|
|
||||||
var barrier = new BarrierPlan<>(SIMPLE, SIMPLE);
|
|
||||||
var oneMainThread = NestedPlan.of(barrier, NestedPlan.of(UnitPlan.of(), UnitPlan.of()));
|
|
||||||
|
|
||||||
Assertions.assertEquals(oneMainThread.simplify(), barrier);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void barrierPlan() {
|
|
||||||
var doubleUnit = new BarrierPlan<>(UnitPlan.of(), UnitPlan.of());
|
|
||||||
Assertions.assertEquals(doubleUnit.simplify(), UnitPlan.of());
|
|
||||||
|
|
||||||
var simpleThenUnit = new BarrierPlan<>(SIMPLE, UnitPlan.of());
|
|
||||||
Assertions.assertEquals(simpleThenUnit.simplify(), SIMPLE);
|
|
||||||
|
|
||||||
var unitThenSimple = new BarrierPlan<>(UnitPlan.of(), SIMPLE);
|
|
||||||
Assertions.assertEquals(unitThenSimple.simplify(), SIMPLE);
|
|
||||||
|
|
||||||
var simpleThenSimple = new BarrierPlan<>(SIMPLE, SIMPLE);
|
|
||||||
Assertions.assertEquals(simpleThenSimple.simplify(), new BarrierPlan<>(SIMPLE, SIMPLE));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue