Skip to content

Commit

Permalink
feat: tasks can build their status
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulvdberge committed Jan 26, 2025
1 parent 9b3b6aa commit 06c9026
Show file tree
Hide file tree
Showing 11 changed files with 392 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@
import org.apiguardian.api.API;

@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.10")
public record TaskStatus(TaskInfo info, float percentageCompleted, List<Item> items) {
public record TaskStatus(TaskInfo info, double percentageCompleted, List<Item> items) {
public record TaskInfo(TaskId id, ResourceKey resource, long amount, long startTime) {
}

public record Item(
ItemType type,
ResourceKey resource,
// what is stored internally?
ItemType type,
long stored,
// what is currently processing?
long processing, // (originalIterationsToSendToSink - iterationsToSendToSink)*input
// what are we still going to process?
long scheduled, // iterationsToSendToSink*input
// what do we need to still craft?
long crafting // iterationsRemaining*output
long processing,
long scheduled,
long crafting
) {
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.refinedmods.refinedstorage.api.autocrafting.status;

import com.refinedmods.refinedstorage.api.autocrafting.task.TaskId;
import com.refinedmods.refinedstorage.api.core.CoreValidations;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;

import java.util.LinkedHashMap;
import java.util.Map;

public class TaskStatusBuilder {
private final TaskStatus.TaskInfo info;
private final Map<ResourceKey, MutableItem> items = new LinkedHashMap<>();

public TaskStatusBuilder(final TaskId id, final ResourceKey resource, final long amount, final long startTime) {
this.info = new TaskStatus.TaskInfo(id, resource, amount, startTime);
}

public TaskStatusBuilder stored(final ResourceKey resource, final long stored) {
CoreValidations.validateLargerThanZero(stored, "Stored");
get(resource).stored += stored;
return this;
}

public TaskStatusBuilder processing(final ResourceKey resource, final long processing) {
CoreValidations.validateLargerThanZero(processing, "Processing");
get(resource).processing += processing;
return this;
}

public TaskStatusBuilder scheduled(final ResourceKey resource, final long scheduled) {
CoreValidations.validateLargerThanZero(scheduled, "Crafting");
get(resource).scheduled += scheduled;
return this;
}

public TaskStatusBuilder crafting(final ResourceKey resource, final long crafting) {
CoreValidations.validateLargerThanZero(crafting, "Crafting");
get(resource).crafting += crafting;
return this;
}

private MutableItem get(final ResourceKey resource) {
return items.computeIfAbsent(resource, key -> new MutableItem(TaskStatus.ItemType.NORMAL));
}

public TaskStatus build(final double percentageCompleted) {
return new TaskStatus(info, percentageCompleted, items.entrySet().stream().map(entry -> new TaskStatus.Item(
entry.getKey(),
entry.getValue().type,
entry.getValue().stored,
entry.getValue().processing,
entry.getValue().scheduled,
entry.getValue().crafting
)).toList());
}

private static class MutableItem {
private final TaskStatus.ItemType type;
private long stored;
private long processing;
private long scheduled;
private long crafting;

private MutableItem(final TaskStatus.ItemType type) {
this.type = type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.refinedmods.refinedstorage.api.autocrafting.task;

import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusBuilder;
import com.refinedmods.refinedstorage.api.core.Action;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.api.resource.list.MutableResourceList;
Expand Down Expand Up @@ -38,6 +39,12 @@ abstract boolean step(MutableResourceList internalStorage,

abstract RootStorageListener.InterceptResult interceptInsertion(ResourceKey resource, long amount);

abstract void appendStatus(TaskStatusBuilder builder);

abstract long getWeight();

abstract double getPercentageCompleted();

protected final boolean extractAll(final ResourceList inputs,
final MutableResourceList internalStorage,
final Action action) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.refinedmods.refinedstorage.api.autocrafting.task;

import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusBuilder;
import com.refinedmods.refinedstorage.api.core.Action;
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.api.resource.list.MutableResourceList;
import com.refinedmods.refinedstorage.api.resource.list.MutableResourceListImpl;
Expand All @@ -16,14 +18,19 @@ class ExternalTaskPattern extends AbstractTaskPattern {
private static final Logger LOGGER = LoggerFactory.getLogger(ExternalTaskPattern.class);

private final MutableResourceList expectedOutputs = MutableResourceListImpl.create();
private final ResourceList simulatedIterationInputs;
private final long originalIterationsToSendToSink;
private long iterationsToSendToSink;
private long iterationsReceived;

ExternalTaskPattern(final Pattern pattern, final TaskPlan.PatternPlan plan) {
super(pattern, plan);
this.iterationsToSendToSink = plan.iterations();
this.originalIterationsToSendToSink = plan.iterations();
pattern.outputs().forEach(
output -> expectedOutputs.add(output.resource(), output.amount() * plan.iterations())
);
this.iterationsToSendToSink = plan.iterations();
this.simulatedIterationInputs = calculateIterationInputs(Action.SIMULATE);
}

@Override
Expand Down Expand Up @@ -52,10 +59,51 @@ RootStorageListener.InterceptResult interceptInsertion(final ResourceKey resourc
}
final long reserved = Math.min(needed, amount);
expectedOutputs.remove(resource, reserved);
updateIterationsReceived();
final long intercepted = root ? 0 : reserved;
return new RootStorageListener.InterceptResult(reserved, intercepted);
}

private void updateIterationsReceived() {
long result = originalIterationsToSendToSink;
for (final ResourceAmount output : pattern.outputs()) {
final long expected = output.amount() * originalIterationsToSendToSink;
final long stillNeeded = expectedOutputs.get(output.resource());
final long receivedOutputs = expected - stillNeeded;
final long receivedOutputIterations = receivedOutputs / output.amount();
if (result > receivedOutputIterations) {
result = receivedOutputIterations;
}
}
this.iterationsReceived = result;
}

@Override
void appendStatus(final TaskStatusBuilder builder) {
if (iterationsToSendToSink > 0) {
for (final ResourceAmount output : pattern.outputs()) {
builder.scheduled(output.resource(), output.amount() * iterationsToSendToSink);
}
}
final long iterationsSentToSink = originalIterationsToSendToSink - iterationsToSendToSink;
final long iterationsProcessing = iterationsSentToSink - iterationsReceived;
if (iterationsProcessing > 0) {
for (final ResourceKey input : simulatedIterationInputs.getAll()) {
builder.processing(input, simulatedIterationInputs.get(input) * iterationsProcessing);
}
}
}

@Override
long getWeight() {
return iterationsToSendToSink;
}

@Override
double getPercentageCompleted() {
return iterationsReceived / (double) originalIterationsToSendToSink;
}

private boolean acceptsIterationInputs(final MutableResourceList internalStorage,
final ExternalPatternInputSink externalPatternInputSink) {
final ResourceList iterationInputsSimulated = calculateIterationInputs(Action.SIMULATE);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.refinedmods.refinedstorage.api.autocrafting.task;

import com.refinedmods.refinedstorage.api.autocrafting.Pattern;
import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatusBuilder;
import com.refinedmods.refinedstorage.api.core.Action;
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
Expand All @@ -16,10 +17,12 @@
class InternalTaskPattern extends AbstractTaskPattern {
private static final Logger LOGGER = LoggerFactory.getLogger(InternalTaskPattern.class);

private final long originalIterationsRemaining;
private long iterationsRemaining;

InternalTaskPattern(final Pattern pattern, final TaskPlan.PatternPlan plan) {
super(pattern, plan);
this.originalIterationsRemaining = plan.iterations();
this.iterationsRemaining = plan.iterations();
}

Expand Down Expand Up @@ -60,6 +63,27 @@ RootStorageListener.InterceptResult interceptInsertion(final ResourceKey resourc
return RootStorageListener.InterceptResult.EMPTY;
}

@Override
void appendStatus(final TaskStatusBuilder builder) {
if (iterationsRemaining == 0) {
return;
}
for (final ResourceAmount output : pattern.outputs()) {
builder.crafting(output.resource(), output.amount() * iterationsRemaining);
}
}

@Override
long getWeight() {
return originalIterationsRemaining;
}

@Override
double getPercentageCompleted() {
final double iterationsCompleted = originalIterationsRemaining - iterationsRemaining;
return iterationsCompleted / originalIterationsRemaining;
}

protected boolean useIteration() {
iterationsRemaining--;
LOGGER.debug("Stepped {} with {} iterations remaining", pattern, iterationsRemaining);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.refinedmods.refinedstorage.api.autocrafting.task;

import com.refinedmods.refinedstorage.api.autocrafting.status.TaskStatus;
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.api.storage.root.RootStorage;
import com.refinedmods.refinedstorage.api.storage.root.RootStorageListener;
Expand All @@ -13,10 +14,12 @@ public interface Task extends RootStorageListener {
TaskId getId();

TaskState getState();

Collection<ResourceAmount> copyInternalStorageState();

void step(RootStorage rootStorage, ExternalPatternInputSink externalPatternInputSink, StepBehavior stepBehavior);

void cancel();

TaskStatus getStatus();
}
Loading

0 comments on commit 06c9026

Please sign in to comment.