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

CyclopsMC / IntegratedDynamics / 20210191346

14 Dec 2025 03:32PM UTC coverage: 19.514% (-33.5%) from 53.061%
20210191346

push

github

rubensworks
Remove deprecations

663 of 8728 branches covered (7.6%)

Branch coverage included in aggregate %.

6786 of 29445 relevant lines covered (23.05%)

1.09 hits per line

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

53.38
/src/main/java/org/cyclops/integrateddynamics/core/evaluate/operator/OperatorBase.java
1
package org.cyclops.integrateddynamics.core.evaluate.operator;
2

3
import net.minecraft.ChatFormatting;
4
import net.minecraft.network.chat.Component;
5
import net.minecraft.network.chat.MutableComponent;
6
import net.minecraft.resources.ResourceLocation;
7
import org.cyclops.cyclopscore.helper.IModHelpers;
8
import org.cyclops.integrateddynamics.GeneralConfig;
9
import org.cyclops.integrateddynamics.Reference;
10
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
11
import org.cyclops.integrateddynamics.api.evaluate.operator.IOperator;
12
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
13
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueType;
14
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
15
import org.cyclops.integrateddynamics.api.logicprogrammer.IConfigRenderPattern;
16
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueHelpers;
17
import org.cyclops.integrateddynamics.core.helper.L10NValues;
18

19
import javax.annotation.Nullable;
20
import java.util.Arrays;
21
import java.util.function.Consumer;
22

23
/**
24
 * A basic abstract implementation of an operator.
25
 * @author rubensworks
26
 */
27
public abstract class OperatorBase implements IOperator {
28

29
    private final String symbol;
30
    private final String operatorName;
31
    private final String interactName;
32
    @Nullable
33
    private final String globalInteractNamePrefix;
34
    private final boolean alsoPrefixLocalScope;
35
    private final IValueType[] inputTypes;
36
    private final IValueType outputType;
37
    private final IFunction function;
38
    @Nullable
39
    private final IConfigRenderPattern renderPattern;
40

41
    private String translationKey = null;
3✔
42
    private int recursiveInvocations;
43

44
    protected OperatorBase(String symbol, String operatorName, String interactName, String globalInteractNamePrefix, boolean alsoPrefixLocalScope, IValueType[] inputTypes,
45
                           IValueType outputType, IFunction function, @Nullable IConfigRenderPattern renderPattern) {
2✔
46
        this.symbol = symbol;
3✔
47
        this.operatorName = operatorName;
3✔
48
        this.interactName = interactName;
3✔
49
        this.globalInteractNamePrefix = globalInteractNamePrefix;
3✔
50
        this.alsoPrefixLocalScope = alsoPrefixLocalScope;
3✔
51
        this.inputTypes = inputTypes;
3✔
52
        this.outputType = outputType;
3✔
53
        this.function = function;
3✔
54
        this.renderPattern = renderPattern;
3✔
55
        if(renderPattern != null && renderPattern.getSlotPositions().length != inputTypes.length) {
8!
56
            throw new IllegalArgumentException(String.format("The given config render pattern with %s slots is not " +
×
57
                    "compatible with the number of input types %s for %s",
58
                    renderPattern.getSlotPositions().length, inputTypes.length, symbol));
×
59
        }
60
    }
1✔
61

62
    public static IValueType[] constructInputVariables(int length, IValueType defaultType) {
63
        IValueType[] values = new IValueType[length];
3✔
64
        Arrays.fill(values, defaultType);
3✔
65
        return values;
2✔
66
    }
67

68
    protected abstract String getUnlocalizedType();
69

70
    protected IFunction getFunction() {
71
        return this.function;
×
72
    }
73

74
    @Override
75
    public ResourceLocation getUniqueName() {
76
        return ResourceLocation.fromNamespaceAndPath(getModId(), this.getUnlocalizedType().replaceAll("\\.", "_") + "_" + getOperatorName());
12✔
77
    }
78

79
    @Override
80
    public String getInteractName() {
81
        return this.interactName;
3✔
82
    }
83

84
    @Override
85
    @Nullable
86
    public String getGlobalInteractNamePrefix() {
87
        return globalInteractNamePrefix;
3✔
88
    }
89

90
    @Override
91
    public boolean shouldAlsoPrefixLocalScope() {
92
        return this.alsoPrefixLocalScope;
3✔
93
    }
94

95
    @Override
96
    public String getTranslationKey() {
97
        return translationKey != null ? translationKey : (translationKey = getUnlocalizedPrefix());
12✔
98
    }
99

100
    @Override
101
    public String getUnlocalizedCategoryName() {
102
        return getUnlocalizedCategoryPrefix();
3✔
103
    }
104

105
    @Override
106
    public MutableComponent getLocalizedNameFull() {
107
        return Component.translatable(getUnlocalizedCategoryPrefix() + ".basename", Component.translatable(getTranslationKey()));
13✔
108
    }
109

110
    protected String getUnlocalizedPrefix() {
111
        return "operator." + getModId() + "." + getUnlocalizedType() + "." + getOperatorName();
8✔
112
    }
113

114
    protected String getUnlocalizedCategoryPrefix() {
115
        return "operator." + getModId() + "." + getUnlocalizedType();
6✔
116
    }
117

118
    protected String getOperatorName() {
119
        return this.operatorName;
3✔
120
    }
121

122
    @Override
123
    public String getSymbol() {
124
        return symbol;
×
125
    }
126

127
    @Override
128
    public void loadTooltip(Consumer<Component> tooltipAdder, boolean appendOptionalInfo) {
129
        Component operatorName = Component.translatable(getTranslationKey());
×
130
        Component categoryName = Component.translatable(getUnlocalizedCategoryName());
×
131
        String symbol = getSymbol();
×
132
        String outputTypeName = IModHelpers.get().getL10NHelpers().localize(getOutputType().getTranslationKey());
×
133
        tooltipAdder.accept(Component.translatable(L10NValues.OPERATOR_TOOLTIP_OPERATORNAME, operatorName, symbol));
×
134
        tooltipAdder.accept(Component.translatable(L10NValues.OPERATOR_TOOLTIP_OPERATORCATEGORY, categoryName));
×
135
        IValueType[] inputTypes = getInputTypes();
×
136
        for(int i = 0; i < inputTypes.length; i++) {
×
137
            tooltipAdder.accept(Component.translatable(L10NValues.OPERATOR_TOOLTIP_INPUTTYPENAME, i + 1)
×
138
            .append(Component.translatable(inputTypes[i].getTranslationKey()))
×
139
                    .withStyle(inputTypes[i].getDisplayColorFormat()));
×
140
        }
141
        tooltipAdder.accept(Component.translatable(L10NValues.OPERATOR_TOOLTIP_OUTPUTTYPENAME, getOutputType().getDisplayColorFormat() + outputTypeName));
×
142
        if(appendOptionalInfo) {
×
143
            // Global name
144
            MutableComponent globalNameComponent = Component.translatable(L10NValues.GUI_OPERATOR_GLOBALNAME,
×
145
                            ChatFormatting.WHITE + this.getGlobalInteractName() + "(")
×
146
                    .withStyle(ChatFormatting.YELLOW);
×
147
            for(int i = 0; i < inputTypes.length; i++) {
×
148
                if (i > 0) {
×
149
                    globalNameComponent = globalNameComponent.append(Component
×
150
                            .literal(", ")
×
151
                            .withStyle(ChatFormatting.WHITE));
×
152
                }
153
                globalNameComponent = globalNameComponent.append(Component
×
154
                        .translatable(inputTypes[i].getTranslationKey())
×
155
                        .withStyle(inputTypes[i].getDisplayColorFormat()));
×
156
            }
157
            tooltipAdder.accept(globalNameComponent.append(Component
×
158
                    .literal(")")
×
159
                    .withStyle(ChatFormatting.WHITE)));
×
160

161
            // Local name
162
            if (this.getInputTypes().length > 0) {
×
163
                String scopedTypeName = IModHelpers.get().getL10NHelpers().localize(this.getInputTypes()[0].getTranslationKey());
×
164
                MutableComponent localNameComponent = Component.translatable(L10NValues.GUI_OPERATOR_LOCALNAME,
×
165
                                this.getInputTypes()[0].getDisplayColorFormat() + scopedTypeName + "." + ChatFormatting.WHITE + this.getScopedInteractName() + "(")
×
166
                        .withStyle(ChatFormatting.YELLOW);
×
167
                for(int i = 1; i < inputTypes.length; i++) {
×
168
                    if (i > 1) {
×
169
                        localNameComponent = localNameComponent.append(Component
×
170
                                .literal(", ")
×
171
                                .withStyle(ChatFormatting.WHITE));
×
172
                    }
173
                    localNameComponent = localNameComponent.append(Component
×
174
                            .translatable(inputTypes[i].getTranslationKey())
×
175
                            .withStyle(inputTypes[i].getDisplayColorFormat()));
×
176
                }
177
                tooltipAdder.accept(localNameComponent.append(Component
×
178
                        .literal(")")
×
179
                        .withStyle(ChatFormatting.WHITE)));
×
180
            }
181
            IModHelpers.get().getL10NHelpers().addOptionalInfo(tooltipAdder, getUnlocalizedPrefix());
×
182
        }
183
    }
×
184

185
    @Override
186
    public IValueType[] getInputTypes() {
187
        return inputTypes;
3✔
188
    }
189

190
    @Override
191
    public IValueType getOutputType() {
192
        return outputType;
3✔
193
    }
194

195
    @Override
196
    public IValueType getConditionalOutputType(IVariable[] input) {
197
        return outputType;
3✔
198
    }
199

200
    @Override
201
    public IValue evaluate(IVariable... input) throws EvaluationException {
202
        if (this.recursiveInvocations++ > GeneralConfig.operatorRecursionLimit) {
9✔
203
            this.recursiveInvocations = 0;
3✔
204
            throw new EvaluationException(Component.translatable(L10NValues.OPERATOR_ERROR_RECURSIONLIMIT,
11✔
205
                    GeneralConfig.operatorRecursionLimit,
5✔
206
                    Component.translatable(this.getTranslationKey())
3✔
207
            ));
208
        }
209
        MutableComponent error = validateTypes(ValueHelpers.from(input));
5✔
210
        if(error != null) {
2✔
211
            this.recursiveInvocations--;
6✔
212
            throw new EvaluationException(error);
5✔
213
        }
214
        IValue res = function.evaluate(new SafeVariablesGetter(input));
8✔
215
        this.recursiveInvocations--;
6✔
216
        return res;
2✔
217
    }
218

219
    @Override
220
    public int getRequiredInputLength() {
221
        return getInputTypes().length;
4✔
222
    }
223

224
    @Override
225
    public MutableComponent validateTypes(IValueType[] input) {
226
        // Input size checking
227
        int requiredInputLength = getRequiredInputLength();
3✔
228
        if(input.length != requiredInputLength) {
4✔
229
            return Component.translatable(L10NValues.OPERATOR_ERROR_WRONGINPUTLENGTH,
8✔
230
                    this.getOperatorName(), input.length, requiredInputLength);
13✔
231
        }
232
        // Input types checking
233
        for(int i = 0; i < requiredInputLength; i++) {
7✔
234
            IValueType inputType = input[i];
4✔
235
            if(inputType == null) {
2!
236
                return Component.translatable(L10NValues.OPERATOR_ERROR_NULLTYPE, this.getOperatorName(), Integer.toString(i));
×
237
            }
238
            if(!ValueHelpers.correspondsTo(getInputTypes()[i], inputType)) {
7✔
239
                return Component.translatable(L10NValues.OPERATOR_ERROR_WRONGTYPE,
8✔
240
                        this.getOperatorName(), Component.translatable(inputType.getTranslationKey()),
13✔
241
                        Integer.toString(i + 1), Component.translatable(getInputTypes()[i].getTranslationKey()));
11✔
242
            }
243
        }
244
        return null;
2✔
245
    }
246

247
    @Override
248
    public String toString() {
249
        return "[Operator: " + getOperatorName() + "]";
×
250
    }
251

252
    protected String getModId() {
253
        return Reference.MOD_ID;
2✔
254
    }
255

256
    @Override
257
    @Nullable
258
    public IConfigRenderPattern getRenderPattern() {
259
        return renderPattern;
×
260
    }
261

262
    @Override
263
    public IOperator materialize() throws EvaluationException {
264
        return this;
×
265
    }
266

267
    public static class SafeVariablesGetter {
268

269
        private final IVariable[] variables;
270

271
        public SafeVariablesGetter(IVariable... variables) {
2✔
272
            this.variables = variables;
3✔
273
        }
1✔
274

275
        public IValue getValue(int i) throws EvaluationException {
276
            return variables[i].getValue();
6✔
277
        }
278

279
        public <V extends IValue> V getValue(int i, IValueType<V> valueType) throws EvaluationException {
280
            return valueType.cast(getValue(i));
6✔
281
        }
282

283
        public IVariable[] getVariables() {
284
            return this.variables;
3✔
285
        }
286

287
        public static class Shifted extends SafeVariablesGetter {
288

289
            public Shifted(int start, IVariable... variables) {
290
                super(Arrays.copyOfRange(variables, start, variables.length));
8✔
291
            }
1✔
292
        }
293
    }
294

295
    public static interface IFunction {
296

297
        /**
298
         * Evaluate this function for the given input.
299
         * @param variables The input variables holder.
300
         * @return The output value.
301
         * @throws EvaluationException If an exception occurs while evaluating
302
         */
303
        public IValue evaluate(SafeVariablesGetter variables) throws EvaluationException;
304

305
    }
306

307
}
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