public ChunkGenThreadEntry(int fromX, int toX, ChunkGeneratorPool pool, Action <CustomChunkGenerator, int> action) { threadBody = action; fromChunkX = fromX; toChunkX = toX; genPool = pool; }
public void Generate() { ManualResetEvent[] genWait = new ManualResetEvent[threadsNum]; ThreadPool.SetMaxThreads(threadsNum, threadsNum); int totalLoops = (Math.Abs(fromChunkX) + Math.Abs(toChunkX)); int basePartition = totalLoops / threadsNum; int remainder = totalLoops - (basePartition * threadsNum); int currStartX, currEndX, oldEndX; currStartX = currEndX = oldEndX = fromChunkX; int extraWork; GenPool = new ChunkGeneratorPool(threadsNum, worldSeed); for (int i = 0; i < threadsNum; ++i) { extraWork = remainder > 0 ? 1 : 0; --remainder; currStartX = oldEndX; currEndX += basePartition + extraWork; oldEndX = currEndX; genWait[i] = new ManualResetEvent(false); ChunkGenThreadEntry chunkGenEntry = new ChunkGenThreadEntry(currStartX, currEndX, GenPool, (chunkGen, x) => { int xComponent = (x + Math.Abs(fromChunkX)) * (toChunkX - fromChunkX); for (int z = fromChunkX; z < toChunkX; ++z) { ushort index = WorldBehaviour.ChunkIndexFromCoords(x, z); Chunk chunk = new Chunk(x, z, worldManager, (z + x) % 2 == 0 ? Color.black : Color.gray); chunkGen.GenerateChunk(chunk, x, z); int entryIndex = xComponent + (z + Math.Abs(fromChunkX)); chunkEntries[entryIndex] = new ChunkMeshThreadEntry(chunk); WorldBehaviour.ChunksMap[index] = chunk; } }); ThreadPool.QueueUserWorkItem(new WaitCallback(chunkGenEntry.ThreadCallback), genWait[i]); } WaitHandle.WaitAll(genWait); }