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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
package gregtech.common;
import static gregtech.common.misc.GlobalVariableStorage.GlobalWirelessComputation;
import java.util.UUID;
import gregtech.api.interfaces.tileentity.IGregTechTileEntity;
import gregtech.common.misc.spaceprojects.SpaceProjectManager;
import tectech.mechanics.dataTransport.QuantumDataPacket;
public class WirelessComputationPacket {
public boolean wirelessEnabled = false;
// The main idea: 'Clearing' the computation net advances the index and sets the computation stored
// for this index to zero. Uploading is always done to the current index, downloading is always done from the
// other index. This is essentially just a double buffered computation storage. The reason for this is that
// every upload needs to be done before every download happens.
private final long[] computationStored = new long[] { 0, 0 };
private int currentIndex = 0;
private long lastUpdateTick = -1;
private int uploadIndex() {
return currentIndex;
}
private int downloadIndex() {
return (currentIndex + 1) % 2;
}
public long getAvailableComputationStored() {
return computationStored[downloadIndex()];
}
private QuantumDataPacket download(long dataIn, long aTick) {
if (!wirelessEnabled) return new QuantumDataPacket(0L);
// If the net hasn't been updated yet this tick, make sure to do so
if (lastUpdateTick < aTick) {
this.update();
lastUpdateTick = aTick;
}
// If we have enough computation 'stored', download it
// Note that this means that if you do not have enough computation to go to all
// destinations, it won't be distributed equally. This is fine.
// This also means that if you don't have enough computation for a hatch, it will not receive any computation
// at all. This is also fine.
if (getAvailableComputationStored() >= dataIn) {
computationStored[downloadIndex()] -= dataIn;
return new QuantumDataPacket(dataIn);
} else return new QuantumDataPacket(0L);
}
private void update() {
// The reason we want this complex index cycling system is because hatches may upload and download computation
// in the same tick as the currently stored computation is cleared. To avoid interruptions, we want to
// try to double buffer these updates. This means that we keep two computation values around, and every update
// we only clear one of them.
// Remove downloaded computation previous index (which is also the next index since there are only two),
// then remove the leftover from current index.
computationStored[downloadIndex()] = 0;
currentIndex = (currentIndex + 1) % 2;
}
private void setWirelessEnabled(boolean wirelessEnabled) {
this.wirelessEnabled = wirelessEnabled;
}
private void upload(long dataOut, long aTick) {
// If the net hasn't been updated yet this tick, make sure to do so
if (lastUpdateTick < aTick) {
this.update();
lastUpdateTick = aTick;
}
// Store computation that is uploaded internally
computationStored[uploadIndex()] += dataOut;
}
public static QuantumDataPacket downloadData(UUID userId, long dataIn, long aTick) {
return getPacketByUserId(userId).download(dataIn, aTick);
}
public static void uploadData(UUID userId, long dataOut, long aTick) {
getPacketByUserId(userId).upload(dataOut, aTick);
}
public static void enableWirelessNetWork(IGregTechTileEntity entity) {
getPacketByUserId(entity.getOwnerUuid()).setWirelessEnabled(true);
}
public static void disableWirelessNetWork(IGregTechTileEntity entity) {
getPacketByUserId(entity.getOwnerUuid()).setWirelessEnabled(false);
}
public static WirelessComputationPacket getPacketByUserId(UUID userId) {
UUID team = SpaceProjectManager.getLeader(userId);
if (GlobalWirelessComputation.get(team) == null) {
GlobalWirelessComputation.put(team, new WirelessComputationPacket());
}
return GlobalWirelessComputation.get(team);
}
}
|