-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
TickRegion.java
118 lines (103 loc) · 3.31 KB
/
TickRegion.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
package me.nallar.tickthreading.minecraft.tickregion;
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 TickRegion 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;
TickRegion(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() {
TickRegion tickRegion = getCallable(regionX + 1, regionZ);
if (tickRegion != null) {
tickRegion.xMinusLock = thisLock;
this.xPlusLock = tickRegion.thisLock;
}
tickRegion = getCallable(regionX - 1, regionZ);
if (tickRegion != null) {
tickRegion.xPlusLock = thisLock;
this.xMinusLock = tickRegion.thisLock;
}
tickRegion = getCallable(regionX, regionZ + 1);
if (tickRegion != null) {
tickRegion.zMinusLock = thisLock;
this.zPlusLock = tickRegion.thisLock;
}
tickRegion = getCallable(regionX, regionZ - 1);
if (tickRegion != null) {
tickRegion.zPlusLock = thisLock;
this.zMinusLock = tickRegion.thisLock;
}
}
public void die() {
thisLock = null;
TickRegion tickRegion = getCallable(regionX + 1, regionZ);
if (tickRegion != null) {
tickRegion.xMinusLock = null;
}
tickRegion = getCallable(regionX - 1, regionZ);
if (tickRegion != null) {
tickRegion.xPlusLock = null;
}
tickRegion = getCallable(regionX, regionZ + 1);
if (tickRegion != null) {
tickRegion.zMinusLock = null;
}
tickRegion = getCallable(regionX, regionZ - 1);
if (tickRegion != null) {
tickRegion.zPlusLock = null;
}
}
@Override
public void run() {
if (shouldTick()) {
long startTime = System.currentTimeMillis();
doTick();
averageTickTime = ((averageTickTime * 511) + (System.currentTimeMillis() - startTime)) / 512;
}
}
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 boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TickRegion)) {
return false;
}
TickRegion otherTickRegion = (TickRegion) other;
return otherTickRegion.hashCode == this.hashCode && this.getClass().isInstance(other);
}
protected abstract TickRegion getCallable(int regionX, int regionZ);
public abstract boolean isEmpty();
}