-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
TickCallable.java
132 lines (114 loc) · 3.66 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
123
124
125
126
127
128
129
130
131
132
package me.nallar.tickthreading.minecraft.tickcallables;
import java.util.concurrent.Callable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import me.nallar.tickthreading.minecraft.TickManager;
import net.minecraft.src.World;
public abstract class TickCallable<T> implements Callable<T> {
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;
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 T call() {
if (shouldTick()) {
long startTime = System.currentTimeMillis();
doTick();
averageTickTime = ((averageTickTime * 100) + (System.currentTimeMillis() - startTime)) / 101;
}
return null;
}
public boolean shouldTick() {
return !manager.variableTickRate || averageTickTime < 55 || Math.random() < ((float) 55) / averageTickTime;
}
public abstract void doTick();
/**
* Called in processChanges thread, to be used for data processing
* and anything else which is not part of a tick
*/
public void processChanges() {
}
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();
}