aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/threads/RunnableCableUpdate.java
blob: 7ed4e28554041476a9e7f3597dab8dd1bd7c67fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package gregtech.api.threads;

import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;

import com.gtnewhorizon.gtnhlib.util.CoordinatePacker;

import gregtech.GTMod;
import gregtech.api.interfaces.tileentity.IMachineBlockUpdateable;
import gregtech.api.metatileentity.BaseMetaPipeEntity;
import gregtech.api.metatileentity.implementations.MTECable;
import gregtech.common.GTProxy;

public class RunnableCableUpdate extends RunnableMachineUpdate {

    protected RunnableCableUpdate(World aWorld, int posX, int posY, int posZ) {
        super(aWorld, posX, posY, posZ);
    }

    public static void setCableUpdateValues(World aWorld, int posX, int posY, int posZ) {
        if (isEnabled) {
            EXECUTOR_SERVICE.submit(new RunnableCableUpdate(aWorld, posX, posY, posZ));
        }
    }

    @Override
    public void run() {
        int posX, posY, posZ;
        try {
            while (!tQueue.isEmpty()) {
                final long packedCoords = tQueue.dequeueLong();
                posX = CoordinatePacker.unpackX(packedCoords);
                posY = CoordinatePacker.unpackY(packedCoords);
                posZ = CoordinatePacker.unpackZ(packedCoords);

                final TileEntity tTileEntity;

                GTProxy.TICK_LOCK.lock();
                try {
                    // we dont want to go over cables that are in unloaded chunks
                    // keeping the lock just to make sure no CME happens
                    if (world.blockExists(posX, posY, posZ)) {
                        tTileEntity = world.getTileEntity(posX, posY, posZ);
                    } else {
                        tTileEntity = null;
                    }
                } finally {
                    GTProxy.TICK_LOCK.unlock();
                }

                // See if the block itself needs an update
                if (tTileEntity instanceof IMachineBlockUpdateable)
                    ((IMachineBlockUpdateable) tTileEntity).onMachineBlockUpdate();

                // Now see if we should add the nearby blocks to the queue:
                // only add blocks the cable is connected to
                if (tTileEntity instanceof BaseMetaPipeEntity metaPipe
                    && metaPipe.getMetaTileEntity() instanceof MTECable cable) {
                    for (int i = 0; i < ForgeDirection.VALID_DIRECTIONS.length; i++) {
                        final ForgeDirection side = ForgeDirection.VALID_DIRECTIONS[i];
                        if (cable.isConnectedAtSide(side)) {
                            final long tCoords = CoordinatePacker
                                .pack(posX + side.offsetX, posY + side.offsetY, posZ + side.offsetZ);
                            if (visited.add(tCoords)) {
                                tQueue.enqueue(tCoords);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            GTMod.GT_FML_LOGGER.error(
                "Well this update was broken... " + initialX
                    + ", "
                    + initialY
                    + ", "
                    + initialZ
                    + ", mWorld={"
                    + world.getProviderName()
                    + " @dimId "
                    + world.provider.dimensionId
                    + "}",
                e);
        }
    }
}