Skip to content

Commit

Permalink
feat: starting and running crafting tasks in a pattern provider
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulvdberge committed Jan 6, 2025
1 parent 97149aa commit b071b44
Show file tree
Hide file tree
Showing 57 changed files with 1,036 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;

import java.util.List;
import java.util.UUID;

import org.apiguardian.api.API;

@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.6")
public record Pattern(List<Ingredient> ingredients, List<ResourceAmount> outputs, PatternType type) {
public Pattern(final List<Ingredient> ingredients, final List<ResourceAmount> outputs, final PatternType type) {
public record Pattern(UUID id, List<Ingredient> ingredients, List<ResourceAmount> outputs, PatternType type) {
public Pattern(final UUID id,
final List<Ingredient> ingredients,
final List<ResourceAmount> outputs,
final PatternType type) {
CoreValidations.validateNotNull(id, "ID cannot be null");
CoreValidations.validateNotEmpty(ingredients, "Ingredients cannot be empty");
CoreValidations.validateNotEmpty(outputs, "Outputs cannot be empty");
CoreValidations.validateNotNull(type, "Type cannot be null");
this.id = id;
this.ingredients = List.copyOf(ingredients);
this.outputs = List.copyOf(outputs);
this.type = type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.apiguardian.api.API;

@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.12")
public class PatternBuilder {
private final PatternType type;
private final UUID id;
private final List<Ingredient> ingredients = new ArrayList<>();
private final List<ResourceAmount> outputs = new ArrayList<>();

private PatternBuilder(final PatternType type) {
private PatternBuilder(final UUID id, final PatternType type) {
this.id = id;
this.type = type;
}

Expand All @@ -23,7 +26,11 @@ public static PatternBuilder pattern() {
}

public static PatternBuilder pattern(final PatternType type) {
return new PatternBuilder(type);
return pattern(UUID.randomUUID(), type);
}

public static PatternBuilder pattern(final UUID id, final PatternType type) {
return new PatternBuilder(id, type);
}

public IngredientBuilder ingredient(final long amount) {
Expand All @@ -46,7 +53,7 @@ public PatternBuilder output(final ResourceKey output, final long amount) {
}

public Pattern build() {
return new Pattern(ingredients, outputs, type);
return new Pattern(id, ingredients, outputs, type);
}

public class IngredientBuilder {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package com.refinedmods.refinedstorage.api.autocrafting.calculation;

import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
import com.refinedmods.refinedstorage.api.core.CoreValidations;
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;

public record Amount(long iterations, long amountPerIteration) {
public Amount {
CoreValidations.validateLargerThanZero(iterations, "Iterations");
CoreValidations.validateLargerThanZero(amountPerIteration, "Amount per iteration");
}

public long getTotal() {
return iterations * amountPerIteration;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@

@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.12")
public interface CraftingCalculatorListener<T> {
CraftingCalculatorListener<T> childCalculationStarted(Pattern pattern, ResourceKey resource, Amount amount);
CraftingCalculatorListener<T> childCalculationStarted(Pattern childPattern, ResourceKey resource, Amount amount);

void childCalculationCompleted(CraftingCalculatorListener<T> childListener);

void ingredientsExhausted(ResourceKey resource, long amount);

void ingredientUsed(Pattern pattern, int ingredientIndex, ResourceKey resource, long amount);
void ingredientUsed(Pattern ingredientPattern, int ingredientIndex, ResourceKey resource, long amount);

void ingredientExtractedFromStorage(ResourceKey resource, long amount);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ boolean isMissingResources() {
}

@Override
public CraftingCalculatorListener<Boolean> childCalculationStarted(final Pattern pattern,
public CraftingCalculatorListener<Boolean> childCalculationStarted(final Pattern childPattern,
final ResourceKey resource,
final Amount amount) {
return new MissingResourcesCraftingCalculatorListener(missingResources);
Expand All @@ -37,7 +37,7 @@ public void ingredientsExhausted(final ResourceKey resource, final long amount)
}

@Override
public void ingredientUsed(final Pattern pattern,
public void ingredientUsed(final Pattern ingredientPattern,
final int ingredientIndex,
final ResourceKey resource,
final long amount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public static Preview calculatePreview(final CraftingCalculator calculator,
}

@Override
public CraftingCalculatorListener<PreviewBuilder> childCalculationStarted(final Pattern pattern,
public CraftingCalculatorListener<PreviewBuilder> childCalculationStarted(final Pattern childPattern,
final ResourceKey resource,
final Amount amount) {
LOGGER.debug("{} - Child calculation starting for {}x {}", listenerId, amount, resource);
Expand All @@ -64,7 +64,7 @@ public void ingredientsExhausted(final ResourceKey resource, final long amount)
}

@Override
public void ingredientUsed(final Pattern pattern,
public void ingredientUsed(final Pattern ingredientPattern,
final int ingredientIndex,
final ResourceKey resource,
final long amount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ public interface PreviewProvider {

CompletableFuture<Long> getMaxAmount(ResourceKey resource);

boolean startTask(ResourceKey resource, long amount, Actor actor, boolean notify);
CompletableFuture<Boolean> startTask(ResourceKey resource, long amount, Actor actor, boolean notify);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,52 +10,62 @@
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

import static java.util.Objects.requireNonNull;

public class MutableTaskPlan {
@Nullable
private final Pattern pattern;
private final Map<Pattern, MutablePatternPlan> patterns;
private final MutableResourceList initialRequirements;
private boolean missing;

MutableTaskPlan() {
this(new LinkedHashMap<>(), MutableResourceListImpl.create(), false);
this(null, new LinkedHashMap<>(), MutableResourceListImpl.create(), false);
}

private MutableTaskPlan(final Map<Pattern, MutablePatternPlan> patterns,
private MutableTaskPlan(@Nullable final Pattern pattern,
final Map<Pattern, MutablePatternPlan> patterns,
final MutableResourceList initialRequirements,
final boolean missing) {
this.pattern = pattern;
this.patterns = patterns;
this.initialRequirements = initialRequirements;
this.missing = missing;
}

void addOrUpdatePattern(final Pattern pattern, final long iterations) {
patterns.computeIfAbsent(pattern, MutablePatternPlan::new).addIterations(iterations);
void addOrUpdatePattern(final Pattern usedPattern, final long iterations) {
patterns.computeIfAbsent(usedPattern, MutablePatternPlan::new).addIterations(iterations);
}

void addToExtract(final ResourceKey resource, final long amount) {
initialRequirements.add(resource, amount);
}

void addUsedIngredient(final Pattern pattern,
void addUsedIngredient(final Pattern ingredientPattern,
final int ingredientIndex,
final ResourceKey resource,
final long amount) {
final MutablePatternPlan patternPlan = requireNonNull(patterns.get(pattern));
final MutablePatternPlan patternPlan = requireNonNull(patterns.get(ingredientPattern));
patternPlan.addUsedIngredient(ingredientIndex, resource, amount);
}

MutableTaskPlan copy() {
MutableTaskPlan copy(final Pattern childPattern) {
final Map<Pattern, MutablePatternPlan> patternsCopy = new LinkedHashMap<>();
for (final Map.Entry<Pattern, MutablePatternPlan> entry : patterns.entrySet()) {
patternsCopy.put(entry.getKey(), entry.getValue().copy());
}
return new MutableTaskPlan(patternsCopy, initialRequirements.copy(), missing);
return new MutableTaskPlan(
pattern == null ? childPattern : pattern,
patternsCopy,
initialRequirements.copy(),
missing
);
}

Optional<TaskPlan> getPlan() {
if (missing) {
if (missing || pattern == null) {
return Optional.empty();
}
final Map<Pattern, TaskPlan.PatternPlan> finalPatterns = Collections.unmodifiableMap(patterns.entrySet()
Expand All @@ -66,7 +76,7 @@ Optional<TaskPlan> getPlan() {
(a, b) -> a,
LinkedHashMap::new
)));
return Optional.of(new TaskPlan(finalPatterns, initialRequirements.copyState()));
return Optional.of(new TaskPlan(pattern, finalPatterns, initialRequirements.copyState()));
}

void setMissing() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.refinedmods.refinedstorage.api.autocrafting.task;

import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.api.storage.root.RootStorage;

import java.util.Collection;

import org.apiguardian.api.API;

@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.12")
public interface Task {
TaskId getId();

TaskState getState();

Collection<ResourceAmount> copyInternalStorageState();

void step(RootStorage rootStorage, ExternalPatternInputSink externalPatternInputSink);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ public record TaskId(UUID id) {
public static TaskId create() {
return new TaskId(UUID.randomUUID());
}

@Override
public String toString() {
return id.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class TaskImpl implements Task, RootStorageListener {
private final MutableResourceList internalStorage = MutableResourceListImpl.create();
private TaskState state = TaskState.READY;

public TaskImpl(final TaskPlan plan) {
private TaskImpl(final TaskPlan plan) {
this.patterns = plan.patterns().entrySet().stream().collect(Collectors.toMap(
Map.Entry::getKey,
e -> createTaskPattern(e.getKey(), e.getValue()),
Expand All @@ -39,6 +39,10 @@ public TaskImpl(final TaskPlan plan) {
plan.initialRequirements().forEach(initialRequirements::add);
}

public static TaskImpl fromPlan(final TaskPlan plan) {
return new TaskImpl(plan);
}

private static AbstractTaskPattern createTaskPattern(final Pattern pattern,
final TaskPlan.PatternPlan patternPlan) {
return switch (pattern.type()) {
Expand All @@ -47,6 +51,11 @@ private static AbstractTaskPattern createTaskPattern(final Pattern pattern,
};
}

@Override
public TaskId getId() {
return id;
}

@Override
public TaskState getState() {
return state;
Expand Down Expand Up @@ -97,7 +106,8 @@ private void returnInternalStorageAndTryCompleteTask(final RootStorage rootStora
}
}

Collection<ResourceAmount> copyInternalStorageState() {
@Override
public Collection<ResourceAmount> copyInternalStorageState() {
return internalStorage.copyState();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import org.apiguardian.api.API;

@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.12")
public record TaskPlan(Map<Pattern, PatternPlan> patterns, Collection<ResourceAmount> initialRequirements) {
public PatternPlan pattern(final Pattern pattern) {
return patterns.get(pattern);
public record TaskPlan(Pattern pattern,
Map<Pattern, PatternPlan> patterns,
Collection<ResourceAmount> initialRequirements) {
public PatternPlan getPattern(final Pattern p) {
return patterns.get(p);
}

public record PatternPlan(long iterations, Map<Integer, Map<ResourceKey, Long>> ingredients) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,32 @@

import java.util.Optional;

public class TaskCraftingCalculatorListener implements CraftingCalculatorListener<MutableTaskPlan> {
public class TaskPlanCraftingCalculatorListener implements CraftingCalculatorListener<MutableTaskPlan> {
private MutableTaskPlan task;

private TaskCraftingCalculatorListener(final MutableTaskPlan task) {
private TaskPlanCraftingCalculatorListener(final MutableTaskPlan task) {
this.task = task;
}

private TaskPlanCraftingCalculatorListener() {
this(new MutableTaskPlan());
}

public static Optional<TaskPlan> calculatePlan(final CraftingCalculator calculator,
final ResourceKey resource,
final long amount) {
final TaskCraftingCalculatorListener listener = new TaskCraftingCalculatorListener(new MutableTaskPlan());
final TaskPlanCraftingCalculatorListener listener = new TaskPlanCraftingCalculatorListener();
calculator.calculate(resource, amount, listener);
return listener.task.getPlan();
}

@Override
public CraftingCalculatorListener<MutableTaskPlan> childCalculationStarted(final Pattern pattern,
public CraftingCalculatorListener<MutableTaskPlan> childCalculationStarted(final Pattern childPattern,
final ResourceKey resource,
final Amount amount) {
final MutableTaskPlan copy = task.copy();
copy.addOrUpdatePattern(pattern, amount.iterations());
return new TaskCraftingCalculatorListener(copy);
final MutableTaskPlan copy = task.copy(childPattern);
copy.addOrUpdatePattern(childPattern, amount.iterations());
return new TaskPlanCraftingCalculatorListener(copy);
}

@Override
Expand All @@ -43,11 +47,11 @@ public void ingredientsExhausted(final ResourceKey resource, final long amount)
}

@Override
public void ingredientUsed(final Pattern pattern,
public void ingredientUsed(final Pattern ingredientPattern,
final int ingredientIndex,
final ResourceKey resource,
final long amount) {
task.addUsedIngredient(pattern, ingredientIndex, resource, amount);
task.addUsedIngredient(ingredientPattern, ingredientIndex, resource, amount);
}

@Override
Expand Down
Loading

0 comments on commit b071b44

Please sign in to comment.