• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CyclopsMC / IntegratedDynamics / 16552051255

27 Jul 2025 01:58PM UTC coverage: 53.206% (+8.0%) from 45.161%
16552051255

push

github

rubensworks
Resolve minor TODOs

2888 of 8740 branches covered (33.04%)

Branch coverage included in aggregate %.

17341 of 29280 relevant lines covered (59.22%)

3.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.07
/src/main/java/org/cyclops/integrateddynamics/core/evaluate/operator/OperatorRegistry.java
1
package org.cyclops.integrateddynamics.core.evaluate.operator;
2

3
import com.google.common.collect.*;
4
import com.mojang.logging.LogUtils;
5
import com.mojang.serialization.Codec;
6
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
7
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
8
import net.minecraft.nbt.CompoundTag;
9
import net.minecraft.nbt.IntTag;
10
import net.minecraft.nbt.ListTag;
11
import net.minecraft.network.chat.Component;
12
import net.minecraft.resources.ResourceLocation;
13
import net.minecraft.util.ProblemReporter;
14
import net.minecraft.world.level.storage.TagValueInput;
15
import net.minecraft.world.level.storage.TagValueOutput;
16
import net.minecraft.world.level.storage.ValueInput;
17
import net.minecraft.world.level.storage.ValueOutput;
18
import org.cyclops.cyclopscore.helper.IModHelpers;
19
import org.cyclops.integrateddynamics.IntegratedDynamics;
20
import org.cyclops.integrateddynamics.Reference;
21
import org.cyclops.integrateddynamics.api.advancement.criterion.ValuePredicate;
22
import org.cyclops.integrateddynamics.api.advancement.criterion.VariablePredicate;
23
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
24
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperator;
25
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperatorRegistry;
26
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperatorSerializer;
27
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueType;
28
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
29
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
30
import org.cyclops.integrateddynamics.api.item.IOperatorVariableFacade;
31
import org.cyclops.integrateddynamics.api.item.IVariableFacade;
32
import org.cyclops.integrateddynamics.api.item.IVariableFacadeHandlerRegistry;
33
import org.cyclops.integrateddynamics.api.item.TagPathElement;
34
import org.cyclops.integrateddynamics.core.evaluate.expression.LazyExpression;
35
import org.cyclops.integrateddynamics.core.helper.L10NValues;
36
import org.cyclops.integrateddynamics.core.item.OperatorVariableFacade;
37
import org.slf4j.Logger;
38

39
import java.util.*;
40

41
/**
42
 * Registry for {@link IOperator}
43
 * @author rubensworks
44
 */
45
public class OperatorRegistry implements IOperatorRegistry {
46

47
    private static final Logger LOGGER = LogUtils.getLogger();
2✔
48
    private static OperatorRegistry INSTANCE = new OperatorRegistry();
4✔
49
    private static final IOperatorVariableFacade INVALID_FACADE = new OperatorVariableFacade(false, null, null);
8✔
50

51
    private final List<IOperator> operators = Lists.newArrayList();
3✔
52
    private final Map<String, IOperator> namedOperators = Maps.newHashMap();
3✔
53
    private final Map<String, IOperator> globalInteractOperators = Maps.newHashMap();
3✔
54
    private final Map<IValueType<?>, Map<String, IOperator>> scopedInteractOperators = Maps.newHashMap();
3✔
55
    private final Multimap<List<IValueType>, IOperator> inputTypedOperators = HashMultimap.create();
3✔
56
    private final Multimap<IValueType, IOperator> outputTypedOperators = HashMultimap.create();
3✔
57
    private final Multimap<String, IOperator> categoryOperators = HashMultimap.create();
3✔
58
    private final List<IOperatorSerializer> serializers = Lists.newArrayList();
3✔
59
    private final Map<String, IOperatorSerializer> namedSerializers = Maps.newHashMap();
3✔
60
    private final IOperatorSerializer DEFAULT_SERIALIZER = new OperatorSerializerDefault();
5✔
61

62
    private OperatorRegistry() {
2✔
63
        if(IModHelpers.get().getMinecraftHelpers().isModdedEnvironment()) {
4✔
64
            IntegratedDynamics._instance.getRegistryManager().getRegistry(IVariableFacadeHandlerRegistry.class).registerHandler(this);
7✔
65
        }
66
    }
1✔
67

68
    /**
69
     * @return The unique instance.
70
     */
71
    public static OperatorRegistry getInstance() {
72
        return INSTANCE;
2✔
73
    }
74

75
    @Override
76
    public <O extends IOperator> O register(O operator) {
77
        operators.add(operator);
5✔
78
        namedOperators.put(operator.getUniqueName().toString(), operator);
8✔
79
        inputTypedOperators.put(ImmutableList.copyOf(operator.getInputTypes()), operator);
8✔
80
        outputTypedOperators.put(operator.getOutputType(), operator);
7✔
81
        categoryOperators.put(operator.getUnlocalizedCategoryName(), operator);
7✔
82

83
        String globalInteractName = operator.getGlobalInteractName();
3✔
84
        if (globalInteractOperators.containsKey(globalInteractName)) {
5!
85
            throw new IllegalStateException("Detected registration of an operator with non-unique global interact name: " + operator.getUniqueName().toString() + ", " + globalInteractOperators.get(globalInteractName).getUniqueName().toString());
×
86
        }
87
        globalInteractOperators.put(globalInteractName, operator);
6✔
88

89
        if (operator.getInputTypes().length > 0) {
4!
90
            Map<String, IOperator> scopedIteracts = scopedInteractOperators.get(operator.getInputTypes()[0]);
9✔
91
            if (scopedIteracts == null) {
2✔
92
                scopedIteracts = Maps.newHashMap();
2✔
93
                scopedInteractOperators.put(operator.getInputTypes()[0], scopedIteracts);
9✔
94
            }
95
            String scopedInteractName = operator.getScopedInteractName();
3✔
96
            if (scopedIteracts.containsKey(scopedInteractName)) {
4!
97
                throw new IllegalStateException("Detected registration of an operator with non-unique scoped interact name: " + operator.getUniqueName().toString() + ", " + scopedIteracts.get(scopedInteractName).getUniqueName().toString());
×
98
            }
99
            scopedIteracts.put(scopedInteractName, operator);
5✔
100
        }
101

102
        return operator;
2✔
103
    }
104

105
    @Override
106
    public Collection<IOperator> getOperators() {
107
        return Collections.unmodifiableList(operators);
×
108
    }
109

110
    @Override
111
    public IOperator getOperator(ResourceLocation uniqueName) {
112
        return namedOperators.get(uniqueName.toString());
7✔
113
    }
114

115
    @Override
116
    public Collection<IOperator> getOperatorsWithInputTypes(IValueType... valueTypes) {
117
        return inputTypedOperators.get(ImmutableList.copyOf(valueTypes));
×
118
    }
119

120
    @Override
121
    public Collection<IOperator> getOperatorsWithOutputType(IValueType valueType) {
122
        return outputTypedOperators.get(valueType);
×
123
    }
124

125
    @Override
126
    public Collection<IOperator> getOperatorsInCategory(String categoryName) {
127
        return categoryOperators.get(categoryName);
×
128
    }
129

130
    @Override
131
    public void registerSerializer(IOperatorSerializer serializer) {
132
        serializers.add(serializer);
5✔
133
        namedSerializers.put(serializer.getUniqueName().toString(), serializer);
8✔
134
    }
1✔
135

136
    @Override
137
    public void serialize(ValueOutput valueOutput, IOperator value) {
138
        for (IOperatorSerializer serializer : serializers) {
11✔
139
            if (serializer.canHandle(value)) {
4!
140
                valueOutput.putString("serializer", serializer.getUniqueName().toString());
×
141
                serializer.serialize(valueOutput.child("value"), value);
×
142
                return;
×
143
            }
144
        }
1✔
145
        DEFAULT_SERIALIZER.serialize(valueOutput, value);
5✔
146
    }
1✔
147

148
    @Override
149
    public IOperator deserialize(ValueInput valueInput) throws EvaluationException {
150
        IOperatorSerializer serializer = valueInput.getString("serializer")
6✔
151
                .map(namedSerializers::get)
6✔
152
                .orElse(DEFAULT_SERIALIZER);
3✔
153
        if (serializer == null) { // Can be null if namedSerializers does not contain the serializer
2!
154
            throw new EvaluationException(
×
155
                    Component.translatable(L10NValues.OPERATOR_ERROR_NO_DESERIALIZER, valueInput.toString()));
×
156
        }
157
        return serializer.deserialize(valueInput);
4✔
158
    }
159

160
    @Override
161
    public ResourceLocation getUniqueName() {
162
        return ResourceLocation.fromNamespaceAndPath(Reference.MOD_ID, "operator");
4✔
163
    }
164

165
    @Override
166
    public IOperatorVariableFacade getVariableFacade(ValueDeseralizationContext valueDeseralizationContext, int id, CompoundTag tag) {
167
        if(!tag.contains("operator") || !(tag.contains("variableIds") || tag.contains("variableIds"))) {
8!
168
            return INVALID_FACADE;
×
169
        }
170
        try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(new TagPathElement(tag), LOGGER)) {
9✔
171
            ValueInput input = TagValueInput.create(
4✔
172
                    scopedCollector,
173
                    valueDeseralizationContext.holderLookupProvider(),
2✔
174
                    tag
175
            );
176
            IOperator operator;
177
            try {
178
                operator = deserialize(input.child("operator").orElseThrow());
8✔
179
            } catch (EvaluationException e) {
×
180
                return INVALID_FACADE;
×
181
            }
1✔
182
            if(operator == null) {
2!
183
                return INVALID_FACADE;
×
184
            }
185
            int[] variableIds = input.list("variableIds", Codec.INT).orElseThrow()
6✔
186
                    .stream()
2✔
187
                    .mapToInt(i -> i)
4✔
188
                    .toArray();
2✔
189
            return new OperatorVariableFacade(id, operator, variableIds);
9✔
190
        } catch (IllegalArgumentException | NoSuchElementException e) {
×
191
            return INVALID_FACADE;
×
192
        }
193
    }
194

195
    @Override
196
    public void setVariableFacade(ValueDeseralizationContext valueDeseralizationContext, CompoundTag tag, IOperatorVariableFacade variableFacade) {
197
        try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(new TagPathElement(tag), LOGGER)) {
9✔
198
            TagValueOutput valueOutput = TagValueOutput.createWithContext(scopedCollector, valueDeseralizationContext.holderLookupProvider());
5✔
199
            serialize(valueOutput, variableFacade.getOperator());
5✔
200
            tag.put("operator", valueOutput.buildResult());
6✔
201
        }
202
        ListTag variableIds = new ListTag();
4✔
203
        for (int variableId : variableFacade.getVariableIds()) {
17✔
204
            variableIds.add(IntTag.valueOf(variableId));
5✔
205
        }
206
        tag.put("variableIds", variableIds);
5✔
207
    }
1✔
208

209
    @Override
210
    public boolean isInstance(IVariableFacade variableFacade) {
211
        return variableFacade instanceof IOperatorVariableFacade;
×
212
    }
213

214
    @Override
215
    public boolean isInstance(IVariable<?> variable) {
216
        return variable instanceof IVariable;
×
217
    }
218

219
    @Override
220
    public Map<String, IOperator> getGlobalInteractOperators() {
221
        return globalInteractOperators;
×
222
    }
223

224
    @Override
225
    public Map<IValueType<?>, Map<String, IOperator>> getScopedInteractOperators() {
226
        return scopedInteractOperators;
×
227
    }
228

229
    public static class OperatorVariablePredicate extends VariablePredicate<LazyExpression> {
230

231
        private final Optional<IOperator> operator;
232
        private final Optional<Int2ObjectMap<VariablePredicate>> inputPredicates;
233

234
        public OperatorVariablePredicate(Optional<IValueType> valueType, Optional<ValuePredicate> valuePredicate,
235
                                         Optional<IOperator> operator, Optional<Map<Integer, VariablePredicate>> inputPredicates) {
236
            super(LazyExpression.class, valueType, valuePredicate);
5✔
237
            this.operator = operator;
3✔
238
            this.inputPredicates = inputPredicates.map(Int2ObjectOpenHashMap::new);
5✔
239
        }
1✔
240

241
        public Optional<IOperator> getOperator() {
242
            return operator;
×
243
        }
244

245
        @Override
246
        protected boolean testTyped(LazyExpression variable) {
247
            if (!super.testTyped(variable)
×
248
                    || !(operator.isEmpty() || variable.getOperator() == operator.get())) {
×
249
                return false;
×
250
            }
251
            if (inputPredicates.isPresent()) {
×
252
                Int2ObjectMap<VariablePredicate> inputPredicatesMap = inputPredicates.get();
×
253
                for (int i = 0; i < variable.getInput().length; i++) {
×
254
                    IVariable inputVariable = variable.getInput()[i];
×
255
                    VariablePredicate variablePredicate = inputPredicatesMap.get(i);
×
256
                    if (variablePredicate != null && !variablePredicate.test(inputVariable)) {
×
257
                        return false;
×
258
                    }
259
                }
260
            }
261
            return true;
×
262
        }
263

264
        public Optional<Map<Integer, VariablePredicate>> getInputPredicates() {
265
            return inputPredicates.map(map -> map);
×
266
        }
267
    }
268
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc