-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
TickCallable.java
122 lines (106 loc) · 3.43 KB
/
TickCallable.java
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package me.nallar.tickthreading.minecraft.tickcallables;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import me.nallar.tickthreading.minecraft.TickManager;
import net.minecraft.world.World;
public abstract class TickCallable implements Runnable {
volatile Lock thisLock = new ReentrantLock();
volatile Lock xPlusLock = null;
volatile Lock xMinusLock = null;
volatile Lock zPlusLock = null;
volatile Lock zMinusLock = null;
final World world;
final TickManager manager;
public final int hashCode;
private final int regionX;
private final int regionZ;
private float averageTickTime = 1;
TickCallable(World world, TickManager manager, int regionX, int regionZ) {
super();
this.world = world;
this.manager = manager;
this.hashCode = TickManager.getHashCodeFromRegionCoords(regionX, regionZ);
this.regionX = regionX;
this.regionZ = regionZ;
setupLocks();
}
private void setupLocks() {
TickCallable tickCallable = getCallable(regionX + 1, regionZ);
if (tickCallable != null) {
tickCallable.xMinusLock = thisLock;
this.xPlusLock = tickCallable.thisLock;
}
tickCallable = getCallable(regionX - 1, regionZ);
if (tickCallable != null) {
tickCallable.xPlusLock = thisLock;
this.xMinusLock = tickCallable.thisLock;
}
tickCallable = getCallable(regionX, regionZ + 1);
if (tickCallable != null) {
tickCallable.zMinusLock = thisLock;
this.zPlusLock = tickCallable.thisLock;
}
tickCallable = getCallable(regionX, regionZ - 1);
if (tickCallable != null) {
tickCallable.zPlusLock = thisLock;
this.zMinusLock = tickCallable.thisLock;
}
}
public void die() {
thisLock = null;
TickCallable tickCallable = getCallable(regionX + 1, regionZ);
if (tickCallable != null) {
tickCallable.xMinusLock = null;
}
tickCallable = getCallable(regionX - 1, regionZ);
if (tickCallable != null) {
tickCallable.xPlusLock = null;
}
tickCallable = getCallable(regionX, regionZ + 1);
if (tickCallable != null) {
tickCallable.zMinusLock = null;
}
tickCallable = getCallable(regionX, regionZ - 1);
if (tickCallable != null) {
tickCallable.zPlusLock = null;
}
}
public void run() {
if (shouldTick()) {
long startTime = System.currentTimeMillis();
doTick();
averageTickTime = ((averageTickTime * 100) + (System.currentTimeMillis() - startTime)) / 101;
}
}
boolean shouldTick() {
return !manager.variableTickRate || averageTickTime < 55 || Math.random() < ((float) 55) / averageTickTime;
}
protected abstract void doTick();
public float getAverageTickTime() {
return averageTickTime;
}
public String getStats() {
return "X: " + regionX * manager.regionSize + ", Z: " + regionZ * manager.regionSize + ", time: " + getAverageTickTime() + "ms";
}
@Override
public String toString() {
return "rX: " + regionX + ", rZ: " + regionZ + ", hashCode: " + hashCode;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TickCallable)) {
return false;
}
TickCallable otherTickCallable = (TickCallable) other;
return otherTickCallable.hashCode == this.hashCode && this.getClass().isInstance(other);
}
protected abstract TickCallable getCallable(int regionX, int regionZ);
public abstract boolean isEmpty();
}