public UBitmap Generate2DInFourThreadsSync(PlanetContainer planetContainer, Action<float> callBack, CancellationToken token) { const int CORES = 4; var container = planetContainer.Container2D; __StartTime = DateTime.Now; var genTasks = new Task[CORES]; var bmps = new UColor[CORES][,]; var pg = new PlanetGeneratorNative[CORES]; var percents = new float[CORES]; const int PICTURE_SHIFT = 2; var w = container.Width / 2 + PICTURE_SHIFT; var h = container.Height / 2 + PICTURE_SHIFT; var resultBitmap = new UColor[container.Width, container.Height]; for (int i = 0; i < CORES; i++) { var index = i; genTasks[i] = new Task(() => { pg[index] = new PlanetGeneratorNative(AlgorithmType.Classic); pg[index].OnProgressChange = p => { percents[index] = p; callBack?.Invoke(percents.Sum() / CORES); }; var lx = w * (index / 2); var ly = h * (index % 2); if (lx > 0) lx -= PICTURE_SHIFT; if (ly > 0) ly -= PICTURE_SHIFT; var uBmp = pg[index].Generate(planetContainer, token, lx, ly, w, h); if (token.IsCancellationRequested) return; var tmpBmp = uBmp.Map; bmps[index] = tmpBmp; }, token); } for (int i = 0; i < CORES; i++) genTasks[i].Start(); Task.WaitAll(genTasks); if (token.IsCancellationRequested) return null; for (int i = 0; i < CORES; i++) { var lw = w - PICTURE_SHIFT; var lh = h - PICTURE_SHIFT; var lx = (i / 2) * lw; var ly = (i % 2) * lh; var dx = lx > 0 ? PICTURE_SHIFT : 0; var dy = ly > 0 ? PICTURE_SHIFT : 0; for (int x = 0; x < lw; x++) for (int y = 0; y < lh; y++) resultBitmap[lx + x, ly + y] = bmps[i][x + dx, y + dy]; } return new UBitmap(resultBitmap); }
private UBitmap Generate2DInOneThread(PlanetContainer planetContainer, Action<float> callBack, CancellationToken token) { var pc = planetContainer; var generator = new PlanetGeneratorNative(pc.Algorithm); generator.OnProgressChange += callBack; return generator.Generate(pc, token); }