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

CyclopsMC / IntegratedCrafting / #479011834

31 Dec 2025 02:03PM UTC coverage: 23.802% (-1.1%) from 24.876%
#479011834

push

github

rubensworks
Fix incorrect commoncapabilities version

755 of 3172 relevant lines covered (23.8%)

0.24 hits per line

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

0.0
/src/main/java/org/cyclops/integratedcrafting/core/part/PartTypeInterfaceCraftingBase.java
1
package org.cyclops.integratedcrafting.core.part;
2

3
import com.google.common.collect.Lists;
4
import net.minecraft.core.Direction;
5
import net.minecraft.nbt.CompoundTag;
6
import net.minecraft.nbt.ListTag;
7
import net.minecraft.nbt.Tag;
8
import net.minecraft.resources.ResourceLocation;
9
import net.minecraft.world.entity.player.Player;
10
import net.minecraft.world.item.ItemStack;
11
import net.minecraftforge.common.capabilities.Capability;
12
import net.minecraftforge.common.util.LazyOptional;
13
import org.cyclops.commoncapabilities.api.ingredient.IPrototypedIngredient;
14
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
15
import org.cyclops.commoncapabilities.api.ingredient.IngredientInstanceWrapper;
16
import org.cyclops.commoncapabilities.api.ingredient.storage.IIngredientComponentStorage;
17
import org.cyclops.integratedcrafting.GeneralConfig;
18
import org.cyclops.integratedcrafting.api.crafting.CraftingJob;
19
import org.cyclops.integratedcrafting.api.crafting.CraftingJobStatus;
20
import org.cyclops.integratedcrafting.api.crafting.ICraftingInterface;
21
import org.cyclops.integratedcrafting.api.crafting.ICraftingResultsSink;
22
import org.cyclops.integratedcrafting.api.network.ICraftingNetwork;
23
import org.cyclops.integratedcrafting.capability.network.CraftingInterfaceConfig;
24
import org.cyclops.integratedcrafting.capability.network.CraftingNetworkConfig;
25
import org.cyclops.integratedcrafting.core.CraftingHelpers;
26
import org.cyclops.integratedcrafting.core.CraftingJobHandler;
27
import org.cyclops.integratedcrafting.core.CraftingProcessOverrides;
28
import org.cyclops.integratedcrafting.ingredient.storage.IngredientComponentStorageSlottedInsertProxy;
29
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
30
import org.cyclops.integrateddynamics.api.network.INetwork;
31
import org.cyclops.integrateddynamics.api.network.IPartNetwork;
32
import org.cyclops.integrateddynamics.api.network.IPositionedAddonsNetworkIngredients;
33
import org.cyclops.integrateddynamics.api.part.PartPos;
34
import org.cyclops.integrateddynamics.api.part.PartTarget;
35
import org.cyclops.integrateddynamics.api.part.PrioritizedPartPos;
36
import org.cyclops.integrateddynamics.capability.network.PositionedAddonsNetworkIngredientsHandlerConfig;
37
import org.cyclops.integrateddynamics.core.helper.NetworkHelpers;
38
import org.cyclops.integrateddynamics.core.part.PartStateBase;
39

40
import javax.annotation.Nullable;
41
import java.util.Iterator;
42
import java.util.List;
43
import java.util.ListIterator;
44
import java.util.Map;
45
import java.util.function.Function;
46

47
/**
48
 * Base logic for parts that do crafting interfacing.
49
 * @author rubensworks
50
 */
51
public abstract class PartTypeInterfaceCraftingBase<P extends PartTypeInterfaceCraftingBase<P, S>, S extends PartTypeInterfaceCraftingBase.State<P, S>> extends PartTypeCraftingBase<P, S> {
52

53
    public PartTypeInterfaceCraftingBase(String name) {
54
        super(name);
×
55
    }
×
56

57
    @Override
58
    public void afterNetworkReAlive(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
59
        super.afterNetworkReAlive(network, partNetwork, target, state);
×
60
        addTargetToNetwork(network, target, state, true);
×
61
    }
×
62

63
    @Override
64
    public void onNetworkRemoval(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
65
        super.onNetworkRemoval(network, partNetwork, target, state);
×
66
        removeTargetFromNetwork(network, target.getTarget(), state);
×
67
    }
×
68

69
    @Override
70
    public void onNetworkAddition(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
71
        super.onNetworkAddition(network, partNetwork, target, state);
×
72
        addTargetToNetwork(network, target, state, true);
×
73
    }
×
74

75
    @Override
76
    public void setPriorityAndChannel(INetwork network, IPartNetwork partNetwork, PartTarget target, S state, int priority, int channel) {
77
        // We need to do this because the crafting network is not automagically aware of the priority changes,
78
        // so we have to re-add it.
79
        removeTargetFromNetwork(network, target.getTarget(), state);
×
80
        super.setPriorityAndChannel(network, partNetwork, target, state, priority, channel);
×
81
        addTargetToNetwork(network, target, state, false);
×
82
    }
×
83

84
    protected Capability<ICraftingNetwork> getNetworkCapability() {
85
        return CraftingNetworkConfig.CAPABILITY;
×
86
    }
87

88
    protected void addTargetToNetwork(INetwork network, PartTarget pos, S state, boolean initialize) {
89
        network.getCapability(getNetworkCapability())
×
90
                .ifPresent(craftingNetwork -> {
×
91
                    int channelCrafting = state.getChannelCrafting();
×
92
                    state.setTarget(pos);
×
93
                    state.setNetworks(network, craftingNetwork, NetworkHelpers.getPartNetworkChecked(network), channelCrafting, ValueDeseralizationContext.of(pos.getCenter().getPos().getLevel(true)), initialize);
×
94
                    state.setShouldAddToCraftingNetwork(true);
×
95
                });
×
96
    }
×
97

98
    protected void removeTargetFromNetwork(INetwork network, PartPos pos, S state) {
99
        ICraftingNetwork craftingNetwork = state.getCraftingNetwork();
×
100
        if (craftingNetwork != null) {
×
101
            network.getCapability(getNetworkCapability())
×
102
                    .ifPresent(n -> n.removeCraftingInterface(state.getChannelCrafting(), state));
×
103
        }
104
        state.setNetworks(null, null, null, -1, null, false);
×
105
        state.setTarget(null);
×
106
    }
×
107

108
    @Override
109
    public boolean isUpdate(S state) {
110
        return true;
×
111
    }
112

113
    @Override
114
    public int getMinimumUpdateInterval(S state) {
115
        return state.getDefaultUpdateInterval();
×
116
    }
117

118
    @Nullable
119
    protected static <T, M> IngredientInstanceWrapper<T, M> insertIntoNetwork(IngredientInstanceWrapper<T, M> wrapper,
120
                                                                              INetwork network, int channel) {
121
        IPositionedAddonsNetworkIngredients<T, M> storageNetwork = wrapper.getComponent()
×
122
                .getCapability(PositionedAddonsNetworkIngredientsHandlerConfig.CAPABILITY)
×
123
                .map(n -> (IPositionedAddonsNetworkIngredients<T, M>) n.getStorage(network).orElse(null))
×
124
                .orElse(null);
×
125
        if (storageNetwork != null) {
×
126
            IIngredientComponentStorage<T, M> storage = storageNetwork.getChannel(channel);
×
127
            T remaining = storage.insert(wrapper.getInstance(), false);
×
128
            if (wrapper.getComponent().getMatcher().isEmpty(remaining)) {
×
129
                return null;
×
130
            } else {
131
                return new IngredientInstanceWrapper<>(wrapper.getComponent(), remaining);
×
132
            }
133
        }
134
        return wrapper;
×
135
    }
136

137
    @Override
138
    public void update(INetwork network, IPartNetwork partNetwork, PartTarget target, S state) {
139
        super.update(network, partNetwork, target, state);
×
140

141
        // Init network data in part state if it has not been done yet.
142
        // This can occur when the part chunk is being reloaded.
143
        if (state.getCraftingNetwork() == null) {
×
144
            addTargetToNetwork(network, target, state, false);
×
145
        }
146

147
        int channel = state.getChannelCrafting();
×
148

149
        // Update the network data in the part state
150
        if (state.shouldAddToCraftingNetwork()) {
×
151
            ICraftingNetwork craftingNetwork = network.getCapability(getNetworkCapability()).orElse(null);
×
152
            craftingNetwork.addCraftingInterface(channel, state);
×
153
            state.setShouldAddToCraftingNetwork(false);
×
154
        }
155

156
        // Push any pending output ingredients into the network
157
        state.flushInventoryOutputBuffer(network);
×
158

159
        // Block job ticking if there still are outputs in our crafting result buffer.
160
        if (state.getInventoryOutputBuffer().isEmpty()) {
×
161
            // Tick the job handler
162
            PartPos targetPos = state.getTarget().getTarget();
×
163
            state.getCraftingJobHandler().update(network, channel, targetPos);
×
164
        }
165
    }
×
166

167
    @Override
168
    public void addDrops(PartTarget target, S state, List<ItemStack> itemStacks, boolean dropMainElement, boolean saveState) {
169
        // Drop any remaining output ingredients (only items)
170
        for (IngredientInstanceWrapper<?, ?> ingredientInstanceWrapper : state.getInventoryOutputBuffer()) {
×
171
            if (ingredientInstanceWrapper.getComponent() == IngredientComponent.ITEMSTACK) {
×
172
                itemStacks.add((ItemStack) ingredientInstanceWrapper.getInstance());
×
173
            }
174
        }
×
175
        state.getInventoryOutputBuffer().clear();
×
176

177
        super.addDrops(target, state, itemStacks, dropMainElement, saveState);
×
178
    }
×
179

180
    public static abstract class State<P extends PartTypeInterfaceCraftingBase<P, S>, S extends PartTypeInterfaceCraftingBase.State<P, S>>
181
            extends PartStateBase<P> implements ICraftingInterface, ICraftingResultsSink {
182

183
        private final CraftingJobHandler craftingJobHandler;
184
        private final List<IngredientInstanceWrapper<?, ?>> inventoryOutputBuffer;
185

186
        private int channelCrafting = 0;
×
187
        private PartTarget target = null;
×
188
        protected INetwork network = null;
×
189
        protected IPartNetwork partNetwork = null;
×
190
        protected ICraftingNetwork craftingNetwork = null;
×
191
        private int channel = -1;
×
192
        protected ValueDeseralizationContext valueDeseralizationContext;
193
        private boolean shouldAddToCraftingNetwork = false;
×
194
        protected Player lastPlayer;
195

196
        public State() {
×
197
            this.craftingJobHandler = new CraftingJobHandler(1, true,
×
198
                    CraftingProcessOverrides.REGISTRY.getCraftingProcessOverrides(), this);
×
199
            this.inventoryOutputBuffer = Lists.newArrayList();
×
200
        }
×
201

202
        @Override
203
        public void writeToNBT(CompoundTag tag) {
204
            super.writeToNBT(tag);
×
205

206
            ListTag instanceTags = new ListTag();
×
207
            for (IngredientInstanceWrapper instanceWrapper : inventoryOutputBuffer) {
×
208
                CompoundTag instanceTag = new CompoundTag();
×
209
                instanceTag.putString("component", IngredientComponent.REGISTRY.getKey(instanceWrapper.getComponent()).toString());
×
210
                instanceTag.put("instance", instanceWrapper.getComponent().getSerializer().serializeInstance(instanceWrapper.getInstance()));
×
211
                instanceTags.add(instanceTag);
×
212
            }
×
213
            tag.put("inventoryOutputBuffer", instanceTags);
×
214

215
            this.craftingJobHandler.writeToNBT(tag);
×
216
            tag.putInt("channelCrafting", channelCrafting);
×
217
        }
×
218

219
        @Override
220
        public void readFromNBT(ValueDeseralizationContext valueDeseralizationContext, CompoundTag tag) {
221
            super.readFromNBT(valueDeseralizationContext, tag);
×
222

223
            this.inventoryOutputBuffer.clear();
×
224
            for (Tag instanceTagRaw : tag.getList("inventoryOutputBuffer", Tag.TAG_COMPOUND)) {
×
225
                CompoundTag instanceTag = (CompoundTag) instanceTagRaw;
×
226
                String componentName = instanceTag.getString("component");
×
227
                IngredientComponent<?, ?> component = IngredientComponent.REGISTRY.getValue(new ResourceLocation(componentName));
×
228
                this.inventoryOutputBuffer.add(new IngredientInstanceWrapper(component,
×
229
                        component.getSerializer().deserializeInstance(instanceTag.get("instance"))));
×
230
            }
×
231

232
            this.craftingJobHandler.readFromNBT(tag);
×
233
            this.channelCrafting = tag.getInt("channelCrafting");
×
234
        }
×
235

236
        @Override
237
        protected int getDefaultUpdateInterval() {
238
            return GeneralConfig.minCraftingInterfaceUpdateFreq;
×
239
        }
240

241
        public void setChannelCrafting(int channelCrafting) {
242
            if (this.channelCrafting != channelCrafting) {
×
243
                // Unregister from the network
244
                if (craftingNetwork != null) {
×
245
                    craftingNetwork.removeCraftingInterface(this.channelCrafting, this);
×
246
                }
247

248
                // Update the channel
249
                this.channelCrafting = channelCrafting;
×
250

251
                // Re-register to the network
252
                if (craftingNetwork != null) {
×
253
                    craftingNetwork.addCraftingInterface(this.channelCrafting, this);
×
254
                }
255

256
                sendUpdate();
×
257
            }
258
        }
×
259

260
        public int getChannelCrafting() {
261
            return channelCrafting;
×
262
        }
263

264
        public void setTarget(PartTarget target) {
265
            this.target = target;
×
266
        }
×
267

268
        public PartTarget getTarget() {
269
            return target;
×
270
        }
271

272
        public void setNetworks(@Nullable INetwork network, @Nullable ICraftingNetwork craftingNetwork,
273
                                @Nullable IPartNetwork partNetwork, int channel,
274
                                @Nullable ValueDeseralizationContext valueDeseralizationContext,
275
                                boolean initialize) {
276
            this.network = network;
×
277
            this.craftingNetwork = craftingNetwork;
×
278
            this.partNetwork = partNetwork;
×
279
            this.channel = channel;
×
280
            this.valueDeseralizationContext = valueDeseralizationContext;
×
281
            reloadRecipes(initialize);
×
282
            if (network != null) {
×
283
                this.getCraftingJobHandler().reRegisterObservers(network);
×
284
            }
285
        }
×
286

287
        public void reloadRecipes(boolean initialize) {
288
            // Do nothing
289
        }
×
290

291
        public void setLastPlayer(Player lastPlayer) {
292
            this.lastPlayer = lastPlayer;
×
293
        }
×
294

295
        public ICraftingNetwork getCraftingNetwork() {
296
            return craftingNetwork;
×
297
        }
298

299
        @Override
300
        public int getChannel() {
301
            return channel;
×
302
        }
303

304
        @Override
305
        public boolean canScheduleCraftingJobs() {
306
            return getCraftingJobHandler().canScheduleCraftingJobs();
×
307
        }
308

309
        @Override
310
        public void scheduleCraftingJob(CraftingJob craftingJob) {
311
            getCraftingJobHandler().scheduleCraftingJob(craftingJob);
×
312
        }
×
313

314
        @Override
315
        public void fillCraftingJobBufferFromStorage(CraftingJob craftingJob, Function<IngredientComponent<?, ?>, IIngredientComponentStorage> storageGetter) {
316
            getCraftingJobHandler().fillCraftingJobBufferFromStorage(craftingJob, storageGetter);
×
317
        }
×
318

319
        @Override
320
        public int getCraftingJobsCount() {
321
            return this.craftingJobHandler.getAllCraftingJobs().size();
×
322
        }
323

324
        @Override
325
        public Iterator<CraftingJob> getCraftingJobs() {
326
            return this.craftingJobHandler.getAllCraftingJobs().values().iterator();
×
327
        }
328

329
        @Override
330
        public List<Map<IngredientComponent<?, ?>, List<IPrototypedIngredient<?, ?>>>> getPendingCraftingJobOutputs(int craftingJobId) {
331
            List<Map<IngredientComponent<?, ?>, List<IPrototypedIngredient<?, ?>>>> pending = this.craftingJobHandler.getProcessingCraftingJobsPendingIngredients().get(craftingJobId);
×
332
            if (pending == null) {
×
333
                pending = Lists.newArrayList();
×
334
            }
335
            return pending;
×
336
        }
337

338
        @Override
339
        public CraftingJobStatus getCraftingJobStatus(ICraftingNetwork network, int channel, int craftingJobId) {
340
            return craftingJobHandler.getCraftingJobStatus(network, channel, craftingJobId);
×
341
        }
342

343
        @Override
344
        public void cancelCraftingJob(int channel, int craftingJobId) {
345
            craftingJobHandler.markCraftingJobFinished(craftingJobId);
×
346
        }
×
347

348
        @Override
349
        public PrioritizedPartPos getPosition() {
350
            return PrioritizedPartPos.of(getTarget().getCenter(), getPriority());
×
351
        }
352

353
        public CraftingJobHandler getCraftingJobHandler() {
354
            return craftingJobHandler;
×
355
        }
356

357
        public boolean shouldAddToCraftingNetwork() {
358
            return shouldAddToCraftingNetwork;
×
359
        }
360

361
        public void setShouldAddToCraftingNetwork(boolean shouldAddToCraftingNetwork) {
362
            this.shouldAddToCraftingNetwork = shouldAddToCraftingNetwork;
×
363
        }
×
364

365
        public List<IngredientInstanceWrapper<?, ?>> getInventoryOutputBuffer() {
366
            return inventoryOutputBuffer;
×
367
        }
368

369
        @Override
370
        public <T> LazyOptional<T> getCapability(Capability<T> capability, INetwork network, IPartNetwork partNetwork, PartTarget target) {
371
            if (capability == CraftingInterfaceConfig.CAPABILITY) {
×
372
                return LazyOptional.of(() -> this).cast();
×
373
            }
374

375
            // Expose the whole storage
376
            if (this.network != null) {
×
377
                IngredientComponent<?, ?> ingredientComponent = IngredientComponent.getIngredientComponentForStorageCapability(capability);
×
378
                if (ingredientComponent != null) {
×
379
                    T cap = wrapStorageCapability(capability, ingredientComponent);
×
380
                    if (cap != null) {
×
381
                        return LazyOptional.of(() -> cap);
×
382
                    }
383
                }
384
            }
385

386
            return super.getCapability(capability, network, partNetwork, target);
×
387
        }
388

389
        protected <C, T, M> C wrapStorageCapability(Capability<C> capability, IngredientComponent<T, M> ingredientComponent) {
390
            IIngredientComponentStorage<T, M> storage = CraftingHelpers.getNetworkStorage(this.network, this.channelCrafting,
×
391
                    ingredientComponent, false);
392

393
            // Don't allow extraction, only insertion
394
            storage = new IngredientComponentStorageSlottedInsertProxy<>(storage);
×
395

396
            return ingredientComponent.getStorageWrapperHandler(capability).wrapStorage(storage);
×
397
        }
398

399
        @Override
400
        public <T, M> void addResult(IngredientComponent<T, M> ingredientComponent, T instance) {
401
            this.getInventoryOutputBuffer().add(new IngredientInstanceWrapper<>(ingredientComponent, instance));
×
402

403
            // Try to flush buffer immediately
404
            if (this.network != null) {
×
405
                this.flushInventoryOutputBuffer(this.network);
×
406
            }
407
        }
×
408

409
        public void setIngredientComponentTargetSideOverride(IngredientComponent<?, ?> ingredientComponent, Direction side) {
410
            if (getTarget().getTarget().getSide() == side) {
×
411
                craftingJobHandler.setIngredientComponentTarget(ingredientComponent, null);
×
412
            } else {
413
                craftingJobHandler.setIngredientComponentTarget(ingredientComponent, side);
×
414
            }
415
            sendUpdate();
×
416
        }
×
417

418
        public Direction getIngredientComponentTargetSideOverride(IngredientComponent<?, ?> ingredientComponent) {
419
            Direction side = craftingJobHandler.getIngredientComponentTarget(ingredientComponent);
×
420
            if (side == null) {
×
421
                side = getTarget().getTarget().getSide();
×
422
            }
423
            return side;
×
424
        }
425

426
        public void flushInventoryOutputBuffer(INetwork network) {
427
            // Try to insert each ingredient in the buffer into the network.
428
            ListIterator<IngredientInstanceWrapper<?, ?>> outputBufferIt = this.getInventoryOutputBuffer().listIterator();
×
429
            while (outputBufferIt.hasNext()) {
×
430
                IngredientInstanceWrapper<?, ?> remainingInstance = outputBufferIt.next();
×
431

432
                // First try to give the ingredients to pending crafting jobs.
433
                remainingInstance = getCraftingJobHandler().beforeFlushIngredientToNetwork(remainingInstance, channelCrafting);
×
434

435
                // If none of the jobs need it, dump it into the network.
436
                remainingInstance = insertIntoNetwork(remainingInstance,
×
437
                        network, this.getChannelCrafting());
×
438
                if (remainingInstance == null) {
×
439
                    outputBufferIt.remove();
×
440
                } else {
441
                    outputBufferIt.set(remainingInstance);
×
442
                }
443
            }
×
444
        }
×
445
    }
446

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

© 2025 Coveralls, Inc