• 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

0.0
/src/main/java/org/cyclops/integrateddynamics/core/part/PartStateOffsetHandler.java
1
package org.cyclops.integrateddynamics.core.part;
2

3
import com.google.common.collect.Lists;
4
import com.google.common.collect.MapMaker;
5
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
6
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
7
import it.unimi.dsi.fastutil.ints.IntArraySet;
8
import it.unimi.dsi.fastutil.ints.IntSet;
9
import net.minecraft.core.Vec3i;
10
import net.minecraft.network.chat.Component;
11
import net.minecraft.network.chat.MutableComponent;
12
import net.neoforged.neoforge.common.NeoForge;
13
import org.cyclops.cyclopscore.inventory.SimpleInventory;
14
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
15
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
16
import org.cyclops.integrateddynamics.api.evaluate.variable.IVariable;
17
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
18
import org.cyclops.integrateddynamics.api.network.INetwork;
19
import org.cyclops.integrateddynamics.api.network.IPartNetwork;
20
import org.cyclops.integrateddynamics.api.part.IPartState;
21
import org.cyclops.integrateddynamics.api.part.IPartType;
22
import org.cyclops.integrateddynamics.api.part.PartTarget;
23
import org.cyclops.integrateddynamics.core.evaluate.InventoryVariableEvaluator;
24
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypeInteger;
25
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
26
import org.cyclops.integrateddynamics.core.part.event.PartVariableDrivenVariableContentsUpdatedEvent;
27

28
import javax.annotation.Nullable;
29
import java.util.List;
30
import java.util.Map;
31

32
/**
33
 * Handles dynamic offsets inside part states.
34
 * @author rubensworks
35
 */
36
public class PartStateOffsetHandler<P extends IPartType> {
×
37

38
    public final List<InventoryVariableEvaluator<ValueTypeInteger.ValueInteger>> offsetVariableEvaluators = Lists.newArrayList();
×
39
    public final Int2ObjectMap<MutableComponent> offsetVariablesSlotMessages = new Int2ObjectArrayMap<>();
×
40
    public boolean offsetVariablesDirty = true;
×
41
    public final IntSet offsetVariableSlotDirty = new IntArraySet();
×
42
    public final Map<IVariable, Boolean> offsetVariableListeners = new MapMaker().weakKeys().makeMap();
×
43
    protected final Int2ObjectMap<IVariable> slotVariables = new Int2ObjectArrayMap<>();
×
44

45
    public void initializeVariableEvaluators(SimpleInventory offsetVariablesInventory, PartTarget target) {
46
        offsetVariableEvaluators.clear();
×
47
        for (int i = 0; i < 3; i++) {
×
48
            int slot = i;
×
49
            offsetVariableEvaluators.add(new InventoryVariableEvaluator<>(
×
50
                    offsetVariablesInventory, slot, ValueDeseralizationContext.of(target.getCenter().getPos().getLevel(true)), ValueTypes.INTEGER) {
×
51
                @Override
52
                public void onErrorsChanged() {
53
                    super.onErrorsChanged();
×
54
                    setOffsetVariableErrors(slot, getErrors());
×
55
                }
×
56
            });
57
        }
58
    }
×
59

60
    public void updateOffsetVariables(P partType, IPartState<P> partState, INetwork network, IPartNetwork partNetwork, PartTarget target) {
61
        // Reload offset variables if needed
62
        if (offsetVariablesDirty) {
×
63
            offsetVariablesDirty = false;
×
64
            reloadOffsetVariables(partType, partState, network, partNetwork, target);
×
65
        }
66

67
        // Only update single slots if needed
68
        if (!offsetVariableSlotDirty.isEmpty()) {
×
69
            IntArraySet offsetVariableSlotDirtyCopy = new IntArraySet(offsetVariableSlotDirty);
×
70
            offsetVariableSlotDirty.clear();
×
71
            for (Integer slot : offsetVariableSlotDirtyCopy) {
×
72
                this.reloadOffsetVariable(partType, partState, network, partNetwork, target, slot);
×
73
            }
×
74
        }
75
    }
×
76

77
    public void markOffsetVariablesChanged() {
78
        this.offsetVariablesDirty = true;
×
79
    }
×
80

81
    public SimpleInventory getOffsetVariablesInventory(IPartState<P> partState) {
82
        SimpleInventory offsetVariablesInventory = new SimpleInventory(3, 1);
×
83
        partState.loadInventoryNamed("offsetVariablesInventory", offsetVariablesInventory);
×
84
        return offsetVariablesInventory;
×
85
    }
86

87
    public void reloadOffsetVariables(P partType, IPartState<P> partState, INetwork network, IPartNetwork partNetwork, PartTarget target) {
88
        offsetVariableSlotDirty.clear();
×
89
        SimpleInventory offsetVariablesInventory = getOffsetVariablesInventory(partState);
×
90
        initializeVariableEvaluators(offsetVariablesInventory, target);
×
91
        for (int i = 0; i < offsetVariablesInventory.getContainerSize(); i++) {
×
92
            reloadOffsetVariable(partType, partState, network, partNetwork, target, i);
×
93
        }
94
    }
×
95

96
    private void setOffsetVariableErrors(int slot, List<MutableComponent> errors) {
97
        if (errors.isEmpty()) {
×
98
            if (this.offsetVariablesSlotMessages.size() > slot) {
×
99
                this.offsetVariablesSlotMessages.remove(slot);
×
100
            }
101
        } else {
102
            this.offsetVariablesSlotMessages.put(slot, errors.get(0));
×
103
        }
104
    }
×
105

106
    @Nullable
107
    public MutableComponent getOffsetVariableError(int slot) {
108
        return this.offsetVariablesSlotMessages.get(slot);
×
109
    }
110

111
    protected void reloadOffsetVariable(P partType, IPartState<P> partState, INetwork network, IPartNetwork partNetwork, PartTarget target, int slot) {
112
        if (this.offsetVariablesSlotMessages.size() > slot) {
×
113
            this.offsetVariablesSlotMessages.remove(slot);
×
114
        }
115
        IVariable lastVariable = slotVariables.get(slot);
×
116
        if (lastVariable != null) {
×
117
            lastVariable.invalidate();
×
118
        }
119

120
        InventoryVariableEvaluator<ValueTypeInteger.ValueInteger> evaluator = offsetVariableEvaluators.get(slot);
×
121
        evaluator.refreshVariable(network, false);
×
122
        IVariable<ValueTypeInteger.ValueInteger> variable = evaluator.getVariable(network);
×
123
        if (variable != null) {
×
124
            slotVariables.put(slot, variable);
×
125
            try {
126
                // Refresh the recipe if variable is changed
127
                // The map is needed because we only want to register the listener once for each variable
128
                if (!this.offsetVariableListeners.containsKey(variable)) {
×
129
                    variable.addInvalidationListener(() -> {
×
130
                        this.offsetVariableListeners.remove(variable);
×
131
                        this.offsetVariableSlotDirty.add(slot);
×
132
                    });
×
133
                    this.offsetVariableListeners.put(variable, true);
×
134
                }
135

136
                IValue value = variable.getValue();
×
137
                if (value.getType() == ValueTypes.INTEGER) {
×
138
                    int valueRaw = ((ValueTypeInteger.ValueInteger) value).getRawValue();
×
139
                    Vec3i offset = partState.getTargetOffset();
×
140
                    if (slot == 0) {
×
141
                        offset = new Vec3i(valueRaw, offset.getY(), offset.getZ());
×
142
                    }
143
                    if (slot == 1) {
×
144
                        offset = new Vec3i(offset.getX(), valueRaw, offset.getZ());
×
145
                    }
146
                    if (slot == 2) {
×
147
                        offset = new Vec3i(offset.getX(), offset.getY(), valueRaw);
×
148
                    }
149
                    boolean valid = partType.setTargetOffset(partState, target.getCenter(), offset);
×
150
                    if (!valid) {
×
151
                        this.offsetVariablesSlotMessages.put(slot, Component.translatable("gui.integrateddynamics.partoffset.slot.message.outofrange"));
×
152
                        partState.markDirty();
×
153
                    }
154
                } else {
×
155
                    this.offsetVariablesSlotMessages.put(slot, Component.translatable("gui.integrateddynamics.partoffset.slot.message.noint"));
×
156
                    partState.markDirty();
×
157
                }
158
            } catch (EvaluationException e) {
×
159
                this.offsetVariablesSlotMessages.put(slot, e.getErrorMessage());
×
160
                partState.markDirty();
×
161
            }
×
162
        } else if (evaluator.hasVariable()) {
×
163
            this.offsetVariableSlotDirty.add(slot);
×
164
        }
165

166
        try {
167
            NeoForge.EVENT_BUS.post(new PartVariableDrivenVariableContentsUpdatedEvent<>(network,
×
168
                    partNetwork, target,
169
                    partType, partState, null, variable,
170
                    variable != null ? variable.getValue() : null));
×
171
        } catch (EvaluationException e) {
×
172
            // Ignore error
173
        }
×
174
    }
×
175

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