Skip to content

Coalesce Base Predicate counts + information into record and make MultiPredicate have counts - #5342

Open
ghzdude wants to merge 26 commits into
GregTechCEu:1.20.1from
ghzdude:gh/predicate-settings
Open

Coalesce Base Predicate counts + information into record and make MultiPredicate have counts#5342
ghzdude wants to merge 26 commits into
GregTechCEu:1.20.1from
ghzdude:gh/predicate-settings

Conversation

@ghzdude

@ghzdude ghzdude commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

What

Multipredicates should now be able to be treated like base predicates for testing min/max counts

Implementation Details

Added record PredicateSettings which combines several of BasePredicate's fields
MultiPredicate also has a settings field, though it is nullable unlike in BasePredicate
For MultiPredicates, if settings == null they behave exactly as before.
When settings is nonnull, it also gets checked along with children predicates
both must be true to pass
Lang has also been introduced for the to-be-used recipe view tooltips

AI Usage

  • No AI driven tools were used for this pull request.
  • Yes AI driven tools were used for this pull request.

Outcome

you should be able to do a.or(b).setMinCount(4) to mean "4 combined of either predicates" now

How Was This Tested

ran client, only check the assembly line which formed as expected

@ghzdude ghzdude added type: refactor Suggestion to refactor a section of code 1.20.1 labels Aug 24, 2026
Comment thread src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiPredicate.java Outdated
@ghzdude
ghzdude force-pushed the gh/predicate-settings branch 2 times, most recently from 644713d to da9a8e9 Compare September 4, 2026 06:21
@ghzdude
ghzdude force-pushed the gh/predicate-settings branch from da9a8e9 to 1dcbd26 Compare September 4, 2026 06:45
@ghzdude
ghzdude marked this pull request as ready for review September 4, 2026 06:59
@ghzdude
ghzdude requested a review from a team as a code owner September 4, 2026 06:59
}

default int getMaxCount() {
return getSettings().maxCount();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these directly reference getSettings() but settings is nullable, so these should have guards for that then

if (testGlobalMin(ctx)) return true;
boolean passed = testGlobalMin(ctx);
if (this.settings != null) {
passed &= SettingsHolder.super.testGlobalMin(ctx.getGlobalCount(this));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This specific SettingsHolder.super.testGlobalMin(int count) doesnt' seem to be tested for any children in the recursive steps, only in the top level predicates (e.g. the AndPredicate etc' testGlobalMin doesnt' call anything that calls testGlobalMin(int count) on the children)

return passedPredicate.testSliceMax(context);
boolean passed = passedPredicate.testGlobalMax(context);
if (this.settings != null) {
passed &= this.testGlobalMax(context.incrementGlobalCount(this));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only increments the count itself, not of ancestors, so a predicate whose count requirements are satisfied through only its children will never match

@Override
public List<Component> getRecipeViewerTooltips(MultiPredicate root) {
List<Component> tooltips = new ArrayList<>(this.getAdditionalTooltips());
List<Component> tooltips = new ArrayList<>();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was the getAdditionalTooltips call removed?

public MultiPredicate withSettings(UnaryOperator<PredicateSettings> configurator) {
return copyWith(p -> {
// is this (the current reference being copied) have their settings set to null?
if (this.settings == null) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case with the XorPredicate, nothing actually recomputes isNoneValid after this happened and its children have a potentially now valid predicate

@CheckReturnValue
public MultiPredicate setMaxSliceCount(int max) {
return mutatedCopy(p -> p.setMaxSliceCount(max));
public void updateSettings(UnaryOperator<PredicateSettings> configurator, boolean shouldCreate) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means any non-single recursive (settings = null) predicate who gets any e.g. .setMinCount() applied to it actually no-ops right?


@CheckReturnValue
public MultiPredicate setMaxGlobalLimited(int max) {
return this.setMaxCount(max);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because e.g. setMinCount and setMaxCount now just call SettingsHolder.setMinCount() which doesn't make a mutated copy anymore, doing stuff like Predicates.AIR.setMinCount(4) mutates the global air predicate. This is why we did all those mutatedCopy things

if (multiPredicate.isSingle() || multiPredicate.isType(type)) {
List<BasePredicate> predicates, List<MultiPredicate> children,
boolean equalSettings) {
if (multiPredicate.isSingle() || (multiPredicate.isType(type) && equalSettings)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we wanna merge on equalSettings, since then blocks(a,b).setMax(2).or(blocks(c,d).setMax(2)) would collapse into the equivalent of blocks(a,b,c,d).setMax(2) which is bad, since the original semantically should match aacc

@CheckReturnValue
public MultiPredicate setMinLayerLimited(int min, int previewCount) {
return this.setMinSliceCount(min).setPreviewCount(previewCount);
/// Sets the setting of this multipredicate to its children, then makes {@code this.settings} null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems unused

@jurrejelle

Copy link
Copy Markdown
Contributor

Edit to add: review assisted by opus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1.20.1 type: refactor Suggestion to refactor a section of code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants