-
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
feat: autocrafting calculation
- Loading branch information
Showing
43 changed files
with
1,843 additions
and
178 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...rafting-api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/Ingredient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.refinedmods.refinedstorage.api.autocrafting; | ||
|
||
import com.refinedmods.refinedstorage.api.resource.ResourceKey; | ||
|
||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
public class Ingredient { | ||
private final long amount; | ||
private final List<ResourceKey> inputs; | ||
|
||
public Ingredient(final long amount, final List<? extends ResourceKey> inputs) { | ||
this.amount = amount; | ||
this.inputs = Collections.unmodifiableList(inputs); | ||
} | ||
|
||
public boolean isEmpty() { | ||
return inputs.isEmpty(); | ||
} | ||
|
||
public int size() { | ||
return inputs.size(); | ||
} | ||
|
||
public long getAmount() { | ||
return amount; | ||
} | ||
|
||
public ResourceKey get(final int index) { | ||
return inputs.get(index); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Ingredient{" | ||
+ "amount=" + amount | ||
+ ", inputs=" + inputs | ||
+ '}'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...api/src/main/java/com/refinedmods/refinedstorage/api/autocrafting/calculation/Amount.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.refinedmods.refinedstorage.api.autocrafting.calculation; | ||
|
||
import com.refinedmods.refinedstorage.api.autocrafting.Pattern; | ||
import com.refinedmods.refinedstorage.api.resource.ResourceAmount; | ||
import com.refinedmods.refinedstorage.api.resource.ResourceKey; | ||
|
||
record Amount(long iterations, long amountPerIteration) { | ||
public long getTotal() { | ||
return iterations * amountPerIteration; | ||
} | ||
|
||
static Amount of(final Pattern pattern, final ResourceKey resource, final long requestedAmount) { | ||
final long amountPerIteration = pattern.getOutputs() | ||
.stream() | ||
.filter(output -> output.resource().equals(resource)) | ||
.mapToLong(ResourceAmount::amount) | ||
.sum(); | ||
final long iterations = ((requestedAmount - 1) / amountPerIteration) + 1; | ||
return new Amount(iterations, amountPerIteration); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
.../java/com/refinedmods/refinedstorage/api/autocrafting/calculation/CraftingCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.refinedmods.refinedstorage.api.autocrafting.calculation; | ||
|
||
import com.refinedmods.refinedstorage.api.resource.ResourceKey; | ||
|
||
import org.apiguardian.api.API; | ||
|
||
@FunctionalInterface | ||
@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.12") | ||
public interface CraftingCalculator { | ||
<T> void calculate(ResourceKey resource, long amount, CraftingCalculatorListener<T> listener); | ||
} |
48 changes: 48 additions & 0 deletions
48
...a/com/refinedmods/refinedstorage/api/autocrafting/calculation/CraftingCalculatorImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package com.refinedmods.refinedstorage.api.autocrafting.calculation; | ||
|
||
import com.refinedmods.refinedstorage.api.autocrafting.Pattern; | ||
import com.refinedmods.refinedstorage.api.autocrafting.PatternRepository; | ||
import com.refinedmods.refinedstorage.api.core.CoreValidations; | ||
import com.refinedmods.refinedstorage.api.resource.ResourceKey; | ||
import com.refinedmods.refinedstorage.api.storage.root.RootStorage; | ||
|
||
import java.util.List; | ||
|
||
import static com.refinedmods.refinedstorage.api.autocrafting.calculation.CraftingTree.root; | ||
|
||
public class CraftingCalculatorImpl implements CraftingCalculator { | ||
private final PatternRepository patternRepository; | ||
private final RootStorage rootStorage; | ||
|
||
public CraftingCalculatorImpl(final PatternRepository patternRepository, final RootStorage rootStorage) { | ||
this.patternRepository = patternRepository; | ||
this.rootStorage = rootStorage; | ||
} | ||
|
||
@Override | ||
public <T> void calculate(final ResourceKey resource, | ||
final long amount, | ||
final CraftingCalculatorListener<T> listener) { | ||
CoreValidations.validateLargerThanZero(amount, "Requested amount must be greater than 0"); | ||
final List<Pattern> patterns = patternRepository.getByOutput(resource); | ||
CraftingCalculatorListener<T> lastChildListener = null; | ||
Amount lastPatternAmount = null; | ||
for (final Pattern pattern : patterns) { | ||
final Amount patternAmount = Amount.of(pattern, resource, amount); | ||
final CraftingCalculatorListener<T> childListener = listener.childCalculationStarted(); | ||
final CraftingTree<T> tree = root(pattern, rootStorage, patternAmount, patternRepository, childListener); | ||
final CraftingTree.CalculationResult calculationResult = tree.calculate(); | ||
if (calculationResult == CraftingTree.CalculationResult.MISSING_RESOURCES) { | ||
lastChildListener = childListener; | ||
lastPatternAmount = patternAmount; | ||
continue; | ||
} | ||
listener.childCalculationCompleted(resource, patternAmount.getTotal(), childListener); | ||
return; | ||
} | ||
if (lastChildListener == null) { | ||
throw new IllegalStateException("No pattern found for " + resource); | ||
} | ||
listener.childCalculationCompleted(resource, lastPatternAmount.getTotal(), lastChildListener); | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
...m/refinedmods/refinedstorage/api/autocrafting/calculation/CraftingCalculatorListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.refinedmods.refinedstorage.api.autocrafting.calculation; | ||
|
||
import com.refinedmods.refinedstorage.api.resource.ResourceKey; | ||
|
||
import org.apiguardian.api.API; | ||
|
||
@API(status = API.Status.STABLE, since = "2.0.0-milestone.4.12") | ||
public interface CraftingCalculatorListener<T> { | ||
CraftingCalculatorListener<T> childCalculationStarted(); | ||
|
||
void childCalculationCompleted(ResourceKey resource, long amount, CraftingCalculatorListener<T> childListener); | ||
|
||
void ingredientsExhausted(ResourceKey resource, long amount); | ||
|
||
void ingredientExtractedFromStorage(ResourceKey resource, long amount); | ||
} |
74 changes: 74 additions & 0 deletions
74
.../main/java/com/refinedmods/refinedstorage/api/autocrafting/calculation/CraftingState.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.refinedmods.refinedstorage.api.autocrafting.calculation; | ||
|
||
import com.refinedmods.refinedstorage.api.autocrafting.Pattern; | ||
import com.refinedmods.refinedstorage.api.resource.ResourceKey; | ||
import com.refinedmods.refinedstorage.api.resource.list.MutableResourceList; | ||
import com.refinedmods.refinedstorage.api.resource.list.MutableResourceListImpl; | ||
import com.refinedmods.refinedstorage.api.storage.root.RootStorage; | ||
|
||
import java.util.Comparator; | ||
|
||
class CraftingState { | ||
private final MutableResourceList storage; | ||
private final MutableResourceList internalStorage; | ||
|
||
private CraftingState(final MutableResourceList storage, | ||
final MutableResourceList internalStorage) { | ||
this.storage = storage; | ||
this.internalStorage = internalStorage; | ||
} | ||
|
||
void extractFromInternalStorage(final ResourceKey resource, final long amount) { | ||
internalStorage.remove(resource, amount); | ||
} | ||
|
||
void extractFromStorage(final ResourceKey resource, final long amount) { | ||
storage.remove(resource, amount); | ||
} | ||
|
||
void addOutputsToInternalStorage(final Pattern pattern, final Amount amount) { | ||
pattern.getOutputs().forEach( | ||
output -> internalStorage.add(output.resource(), output.amount() * amount.iterations()) | ||
); | ||
} | ||
|
||
CraftingState copy() { | ||
return new CraftingState(storage.copy(), internalStorage.copy()); | ||
} | ||
|
||
static CraftingState of(final RootStorage rootStorage) { | ||
final MutableResourceListImpl storage = MutableResourceListImpl.create(); | ||
rootStorage.getAll().forEach(storage::add); | ||
return new CraftingState(storage, MutableResourceListImpl.create()); | ||
} | ||
|
||
Comparator<ResourceKey> storageSorter() { | ||
return sorter(storage); | ||
} | ||
|
||
Comparator<ResourceKey> internalStorageSorter() { | ||
return sorter(internalStorage); | ||
} | ||
|
||
private Comparator<ResourceKey> sorter(final MutableResourceList list) { | ||
return (a, b) -> { | ||
final long ar = list.get(a); | ||
final long br = list.get(b); | ||
return (int) br - (int) ar; | ||
}; | ||
} | ||
|
||
ResourceState getResource(final ResourceKey resource) { | ||
return new ResourceState(resource, storage.get(resource), internalStorage.get(resource)); | ||
} | ||
|
||
record ResourceState(ResourceKey resource, long inStorage, long inInternalStorage) { | ||
boolean isInStorage() { | ||
return inStorage > 0; | ||
} | ||
|
||
boolean isInInternalStorage() { | ||
return inInternalStorage > 0; | ||
} | ||
} | ||
} |
Oops, something went wrong.