mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +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.
|
||||
*/
|
||||
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);
|
||||
|
||||
tickPlan = NestedPlan.of(blockEntities.tickPlan(), entities.tickPlan(), effects.tickPlan())
|
||||
.then(RaisePlan.raise(tickFlag))
|
||||
.simplify();
|
||||
.then(RaisePlan.raise(tickFlag));
|
||||
|
||||
var recreate = SimplePlan.<RenderContext>of(context -> blockEntitiesStorage.recreateAll(context.partialTick()),
|
||||
context -> entitiesStorage.recreateAll(context.partialTick()),
|
||||
|
@ -111,8 +110,7 @@ public class VisualizationManagerImpl implements VisualizationManager {
|
|||
.plan()
|
||||
.then(RaisePlan.raise(frameVisualsFlag))
|
||||
.then(engine.createFramePlan())
|
||||
.then(RaisePlan.raise(frameFlag))
|
||||
.simplify();
|
||||
.then(RaisePlan.raise(frameFlag));
|
||||
|
||||
if (level instanceof Level 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));
|
||||
}
|
||||
|
||||
@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> {
|
||||
private final BooleanSupplierWithContext<C> condition;
|
||||
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);
|
||||
}
|
||||
|
||||
@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> {
|
||||
private final SupplierWithContext<C, D> map;
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.jozufozu.flywheel.lib.task;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.jozufozu.flywheel.api.task.Plan;
|
||||
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> {
|
||||
@SafeVarargs
|
||||
|
@ -44,61 +41,4 @@ public record NestedPlan<C>(List<Plan<C>> parallelPlans) implements SimplyCompos
|
|||
.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);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@Override
|
||||
default Plan<C> simplify() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,4 @@ public class UnitPlan<C> implements Plan<C> {
|
|||
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