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

CyclopsMC / IntegratedDynamics / 29699251478

19 Jul 2026 06:44PM UTC coverage: 53.952% (-0.006%) from 53.958%
29699251478

push

github

rubensworks
Merge remote-tracking branch 'origin/master-26-lts' into master-26

3097 of 8991 branches covered (34.45%)

Branch coverage included in aggregate %.

18918 of 31814 relevant lines covered (59.46%)

3.08 hits per line

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

3.8
/src/main/java/org/cyclops/integrateddynamics/core/network/IngredientChannelAdapterWrapperSlotted.java
1
package org.cyclops.integrateddynamics.core.network;
2

3
import com.google.common.collect.Iterators;
4
import it.unimi.dsi.fastutil.ints.Int2IntMap;
5
import net.neoforged.neoforge.transfer.transaction.Transaction;
6
import net.neoforged.neoforge.transfer.transaction.TransactionContext;
7
import org.apache.commons.lang3.tuple.Triple;
8
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
9
import org.cyclops.commoncapabilities.api.ingredient.storage.IIngredientComponentStorage;
10
import org.cyclops.commoncapabilities.api.ingredient.storage.IIngredientComponentStorageSlotted;
11
import org.cyclops.cyclopscore.helper.IModHelpers;
12
import org.cyclops.integrateddynamics.api.network.IPositionedAddonsNetworkIngredients;
13
import org.cyclops.integrateddynamics.api.network.PositionedAddonsNetworkIngredientsFilter;
14
import org.cyclops.integrateddynamics.api.part.PartPos;
15

16
import javax.annotation.Nonnull;
17
import java.util.Iterator;
18

19
/**
20
 * A slotted wrapper over {@link IngredientChannelAdapter}.
21
 *
22
 * It exposes slots by chaining storages sequentially, not using the index.
23
 *
24
 * @param <T> The instance type.
25
 * @param <M> The matching condition parameter.
26
 *
27
 * @author rubensworks
28
 */
29
public class IngredientChannelAdapterWrapperSlotted<T, M> implements IIngredientComponentStorageSlotted<T, M> {
30

31
    private final IngredientChannelAdapter<T, M> channel;
32
    private final Int2IntMap cacheChannelSlots;
33

34
    public IngredientChannelAdapterWrapperSlotted(IngredientChannelAdapter<T, M> channel, Int2IntMap cacheChannelSlots) {
2✔
35
        this.channel = channel;
3✔
36
        this.cacheChannelSlots = cacheChannelSlots;
3✔
37
    }
1✔
38

39
    protected static int getIngredientComponentStorageSize(IIngredientComponentStorage<?, ?> storage) {
40
        if (storage instanceof IIngredientComponentStorageSlotted) {
×
41
            return ((IIngredientComponentStorageSlotted<?, ?>) storage).getSlots();
×
42
        } else {
43
            return Iterators.size(storage.iterator()) + 1;
×
44
        }
45
    }
46

47
    @Override
48
    public int getSlots() {
49
        int slots = this.cacheChannelSlots.getOrDefault(this.channel.getChannel(), -1);
×
50
        if (slots != -1) {
×
51
            return slots;
×
52
        }
53

54
        slots = 0;
×
55
        IPositionedAddonsNetworkIngredients<T, M> network = this.channel.getNetwork();
×
56

57
        boolean hasDisabledPosition = false;
×
58
        for (PartPos pos : network.getPositions(this.channel.getChannel())) {
×
59
            // Skip if the position is not loaded or disabled
60
            if (!pos.getPos().isLoaded()) {
×
61
                continue;
×
62
            }
63
            if (network.isPositionDisabled(pos)) {
×
64
                hasDisabledPosition = true;
×
65
                continue;
×
66
            }
67
            network.disablePosition(pos);
×
68
            IIngredientComponentStorage<T, M> storage = network.getPositionedStorage(pos);
×
69
            slots = IModHelpers.get().getBaseHelpers().addSafe(slots, getIngredientComponentStorageSize(storage));
×
70
            network.enablePosition(pos);
×
71
        }
×
72

73
        if (!hasDisabledPosition) {
×
74
            this.cacheChannelSlots.put(this.channel.getChannel(), slots);
×
75
        }
76
        return slots;
×
77
    }
78

79
    protected Triple<IIngredientComponentStorage<T, M>, Integer, PartPos> getStorageAndRelativeSlot(int slot) {
80
        IPositionedAddonsNetworkIngredients<T, M> network = this.channel.getNetwork();
×
81

82
        for (PartPos pos : network.getPositions(this.channel.getChannel())) {
×
83
            // Skip if the position is not loaded or disabled
84
            if (!pos.getPos().isLoaded() || network.isPositionDisabled(pos)) {
×
85
                continue;
×
86
            }
87
            network.disablePosition(pos);
×
88
            IIngredientComponentStorage<T, M> storage = network.getPositionedStorage(pos);
×
89
            int storageSize = getIngredientComponentStorageSize(storage);
×
90
            network.enablePosition(pos);
×
91
            if (slot < storageSize) {
×
92
                return Triple.of(storage, slot, pos);
×
93
            } else {
94
                slot -= storageSize;
×
95
            }
96
        }
×
97

98
        return Triple.of(null, -1, null);
×
99
    }
100

101
    @Override
102
    public T getSlotContents(int slotAbsolute) {
103
        Triple<IIngredientComponentStorage<T, M>, Integer, PartPos> storageAndSlot = getStorageAndRelativeSlot(slotAbsolute);
×
104
        IIngredientComponentStorage<T, M> storage = storageAndSlot.getLeft();
×
105
        int slotRelative = storageAndSlot.getMiddle();
×
106
        PartPos pos = storageAndSlot.getRight();
×
107
        if (storage == null) {
×
108
            return getComponent().getMatcher().getEmptyInstance();
×
109
        }
110

111
        if (storage instanceof IIngredientComponentStorageSlotted) {
×
112
            return ((IIngredientComponentStorageSlotted<T, M>) storage).getSlotContents(slotRelative);
×
113
        } else {
114
            try {
115
                T ingredient = Iterators.get(storage.iterator(), slotRelative);
×
116
                PositionedAddonsNetworkIngredientsFilter<T> filter = this.channel.getNetwork().getPositionedStorageFilter(pos);
×
117
                if (filter != null && !filter.testView(ingredient)) {
×
118
                    return getComponent().getMatcher().getEmptyInstance();
×
119
                }
120
                return ingredient;
×
121
            } catch (IndexOutOfBoundsException e) {
×
122
                return getComponent().getMatcher().getEmptyInstance();
×
123
            }
124
        }
125
    }
126

127
    @Override
128
    public long getMaxQuantity(int slotAbsolute) {
129
        Triple<IIngredientComponentStorage<T, M>, Integer, PartPos> storageAndSlot = getStorageAndRelativeSlot(slotAbsolute);
×
130
        IIngredientComponentStorage<T, M> storage = storageAndSlot.getLeft();
×
131
        int slotRelative = storageAndSlot.getMiddle();
×
132
        if (storage == null) {
×
133
            return 0;
×
134
        }
135

136
        if (storage instanceof IIngredientComponentStorageSlotted) {
×
137
            return ((IIngredientComponentStorageSlotted<T, M>) storage).getMaxQuantity(slotRelative);
×
138
        } else {
139
            return IModHelpers.get().getBaseHelpers().castSafe(getComponent().getMatcher().getMaximumQuantity());
×
140
        }
141
    }
142

143
    @Override
144
    public T insert(int slotAbsolute, @Nonnull T ingredient, TransactionContext transaction) {
145
        // First run the ingredient instance through the pre-consumers.
146
        for (IIngredientChannelInsertPreConsumer<T> insertPreConsumer : this.channel.getNetwork().getInsertPreConsumers()) {
×
147
            ingredient = insertPreConsumer.insert(this.channel.getChannel(), ingredient, transaction);
×
148
        }
×
149

150
        Triple<IIngredientComponentStorage<T, M>, Integer, PartPos> storageAndSlot = getStorageAndRelativeSlot(slotAbsolute);
×
151
        IIngredientComponentStorage<T, M> storage = storageAndSlot.getLeft();
×
152
        int slotRelative = storageAndSlot.getMiddle();
×
153
        PartPos pos = storageAndSlot.getRight();
×
154
        if (storage == null) {
×
155
            return ingredient;
×
156
        }
157

158
        PositionedAddonsNetworkIngredientsFilter<T> filter = this.channel.getNetwork().getPositionedStorageFilter(pos);
×
159
        if (filter != null && !filter.testInsertion(ingredient)) {
×
160
            return ingredient;
×
161
        }
162

163
        if (storage instanceof IIngredientComponentStorageSlotted) {
×
164
            return ((IIngredientComponentStorageSlotted<T, M>) storage).insert(slotRelative, ingredient, transaction);
×
165
        } else {
166
            return storage.insert(ingredient, transaction);
×
167
        }
168
    }
169

170
    @Override
171
    public T extract(int slotAbsolute, long maxQuantity, TransactionContext transaction) {
172
        Triple<IIngredientComponentStorage<T, M>, Integer, PartPos> storageAndSlot = getStorageAndRelativeSlot(slotAbsolute);
×
173
        IIngredientComponentStorage<T, M> storage = storageAndSlot.getLeft();
×
174
        int slotRelative = storageAndSlot.getMiddle();
×
175
        PartPos pos = storageAndSlot.getRight();
×
176
        if (storage == null) {
×
177
            return getComponent().getMatcher().getEmptyInstance();
×
178
        }
179

180
        // If we do an effective extraction, first simulate to check if it matches the filter
181
        PositionedAddonsNetworkIngredientsFilter<T> filter = this.channel.getNetwork().getPositionedStorageFilter(pos);
×
182
        if (filter != null) {
×
183
            try (var tx = Transaction.open(transaction)) {
×
184
                T extractedSimulated;
185
                if (storage instanceof IIngredientComponentStorageSlotted) {
×
186
                    extractedSimulated = ((IIngredientComponentStorageSlotted<T, M>) storage).extract(slotRelative, maxQuantity, tx);
×
187
                } else {
188
                    extractedSimulated = storage.extract(maxQuantity, tx);
×
189
                }
190
                if (!filter.testExtraction(extractedSimulated)) {
×
191
                    return getComponent().getMatcher().getEmptyInstance();
×
192
                }
193
            }
×
194
        }
195

196
        T extracted;
197
        if (storage instanceof IIngredientComponentStorageSlotted) {
×
198
            extracted = ((IIngredientComponentStorageSlotted<T, M>) storage).extract(slotRelative, maxQuantity, transaction);
×
199
        } else {
200
            extracted = storage.extract(maxQuantity, transaction);
×
201
        }
202

203
        return extracted;
×
204
    }
205

206
    @Override
207
    public IngredientComponent<T, M> getComponent() {
208
        return channel.getComponent();
×
209
    }
210

211
    @Override
212
    public Iterator<T> iterator() {
213
        return channel.iterator();
4✔
214
    }
215

216
    @Override
217
    public Iterator<T> iterator(@Nonnull T prototype, M matchCondition) {
218
        return channel.iterator(prototype, matchCondition);
×
219
    }
220

221
    @Override
222
    public long getMaxQuantity() {
223
        return channel.getMaxQuantity();
4✔
224
    }
225

226
    @Override
227
    public T insert(@Nonnull T ingredient, TransactionContext transaction) {
228
        return channel.insert(ingredient, transaction);
×
229
    }
230

231
    @Override
232
    public T extract(@Nonnull T prototype, M matchCondition, TransactionContext transaction) {
233
        return channel.extract(prototype, matchCondition, transaction);
×
234
    }
235

236
    @Override
237
    public T extract(long maxQuantity, TransactionContext transaction) {
238
        return channel.extract(maxQuantity, transaction);
×
239
    }
240
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc