-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
ThreadManager.java
143 lines (124 loc) · 4.68 KB
/
ThreadManager.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
133
134
135
136
137
138
139
140
141
142
143
package me.nallar.tickthreading.minecraft;
import java.io.File;
import java.util.Random;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.minecraft.server.MinecraftServer;
import net.minecraft.src.Chunk;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;
import net.minecraftforge.common.Configuration;
public class ThreadManager {
private static class TileEntityTask implements Runnable {
private final int threadID;
private final int worldID = 0;
public TileEntityTask(int threadID) {
super();
this.threadID = threadID;
}
@Override
public void run() {
try {
logger.fine("Started tick thread " + threadID);
//noinspection InfiniteLoopStatement
while (true) {
if (tickNotifyLatch.await() == 0) {
tickNotifyLatch.reset();
}
for (TileEntity tile : tileEntityList[threadID]) {
if (!tile.isInvalid() && tile.worldObj != null) {
tile.updateEntity();
}
if (tile.isInvalid() && tile.worldObj != null) {
World world = tile.worldObj;
logger.fine("Invalid tile!");
while (tileEntityList[threadID].remove(tile)) {
;
}
logger.warning("Removed invalid tile: " + tile.xCoord + ", " + tile.yCoord + ", " + tile.zCoord + "\ttype:" + tile.getClass().toString());//yes, it's blank...
if (world.getChunkProvider().chunkExists(tile.xCoord >> 4, tile.zCoord >> 4)) {
Chunk chunk = world.getChunkFromChunkCoords(tile.xCoord >> 4, tile.zCoord >> 4);
if (chunk != null) {
chunk.cleanChunkBlockTileEntity(tile.xCoord & 0xf, tile.yCoord, tile.zCoord & 0xf);
}
}
}
}
endTickLatch.await();
}
} catch (Exception exception) {
logger.log(Level.FINE, "Exception in tile thread " + threadID + ":", exception);
}
}
}
private static class EntityTask implements Runnable {
private final int threadID;
public EntityTask(int threadID) {
super();
this.threadID = threadID;
}
@Override
public void run() {
/*try{
tickNotify.wait();
}
catch(InterruptedException ignored){}
Iterator entityIterator = entityList[threadID].iterator();
while(entityIterator.hasNext()){
Entity entity = (Entity)entityIterator.next();
}*/
}
}
private static final Configuration conf = new Configuration(new File("TickThreading.conf"));
private static final Logger logger = Logger.getLogger("Minecraft");
private static final Random random = new Random();
public static final CyclicBarrier tickNotifyLatch;
public static final CyclicBarrier endTickLatch;
private static volatile CopyOnWriteArrayList<TileEntity>[] tileEntityList;
private static volatile CopyOnWriteArrayList<TileEntity>[] entityList;
private static volatile ThreadPoolExecutor threadPool = null;
static int numTileThreads = 1;
static int numEntityThreads = 1;
static {
/*Property TileThreads = conf.get("core.TileThreads", Configuration.CATEGORY_GENERAL, numTileThreads);
numTileThreads = Integer.parseInt(TileThreads.value);*/
endTickLatch = new CyclicBarrier(1 + numTileThreads);//+numEntityThreads);
tickNotifyLatch = new CyclicBarrier(1 + numTileThreads);//+numEntityThreads);
//noinspection unchecked
tileEntityList = new CopyOnWriteArrayList[numTileThreads];
//noinspection unchecked
entityList = new CopyOnWriteArrayList[numEntityThreads];
for (int i = 0; i < numTileThreads; i++) {
tileEntityList[i] = new CopyOnWriteArrayList<TileEntity>();
}
for (int i = 0; i < numEntityThreads; i++) {
entityList[i] = new CopyOnWriteArrayList<TileEntity>();
}
threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(numEntityThreads + numTileThreads);
for (int i = 0; i < numTileThreads; i++) {
threadPool.submit(new TileEntityTask(i)); //TODO Get world
}
for (int i = 0; i < numEntityThreads; i++) {
threadPool.submit(new EntityTask(i));
}
}
public static synchronized ThreadGroup getAllThreads() {
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
while ((parentGroup = rootGroup.getParent()) != null) {
rootGroup = parentGroup;
}
return rootGroup;
}
public static synchronized void initialise(MinecraftServer mcserver) {
logger.log(Level.FINE, "Initialised forgeMT thread API!");
}
public static synchronized void addTile(TileEntity TE) {
//logger.fine("Added TE!");
tileEntityList[random.nextInt(numTileThreads)].add(TE);
}
}