private static bool BuildThreadPrefix(HeightmapBuilder __instance)
        {
            ZLog.Log("Builder started");
            while (!__instance.m_stop)
            {
                if (!BetterContinents.ConfigExperimentalParallelChunksBuild.Value)
                {
                    __instance.m_lock.WaitOne();
                    bool flag = __instance.m_toBuild.Count > 0;
                    __instance.m_lock.ReleaseMutex();
                    if (flag)
                    {
                        __instance.m_lock.WaitOne();
                        HeightmapBuilder.HMBuildData hmbuildData = __instance.m_toBuild[0];
                        __instance.m_lock.ReleaseMutex();

                        var st = new Stopwatch();
                        st.Start();
                        __instance.Build(hmbuildData);
                        buildTimes.Add(st.ElapsedMilliseconds);
                        if (buildTimes.Count > 100)
                        {
                            buildTimes.RemoveAt(0);
                        }
                        BetterContinents.Log($"Average chunk build time with vanilla {buildTimes.Average()} ms");

                        __instance.m_lock.WaitOne();
                        __instance.m_toBuild.Remove(hmbuildData);
                        __instance.m_ready.Add(hmbuildData);
                        while (__instance.m_ready.Count > 16)
                        {
                            __instance.m_ready.RemoveAt(0);
                        }
                        __instance.m_lock.ReleaseMutex();
                    }
                    Thread.Sleep(10);
                }
                else
                {
                    __instance.m_lock.WaitOne();
                    var buildTasks = __instance.m_toBuild
                                     .Select(b => new
                    {
                        task      = Task.Run(() => BuildFn(__instance, b)),
                        buildData = b
                    })
                                     .ToList(); // Important to use ToList for force immediate enumeration inside the lock!
                    __instance.m_toBuild.Clear();
                    __instance.m_lock.ReleaseMutex();

                    if (buildTasks.Any())
                    {
                        var st = new Stopwatch();
                        st.Start();
                        Task.WaitAll(buildTasks.Select(bt => bt.task).ToArray());
                        buildTimes.Add(st.ElapsedMilliseconds / (float)buildTasks.Count);
                        if (buildTimes.Count > 100)
                        {
                            buildTimes.RemoveAt(0);
                        }
                        BetterContinents.Log($"Average chunk build time with MT {buildTimes.Average()} ms");

                        __instance.m_lock.WaitOne();
                        foreach (var bt in buildTasks)
                        {
                            __instance.m_ready.Add(bt.buildData);
                        }

                        while (__instance.m_ready.Count > 16)
                        {
                            __instance.m_ready.RemoveAt(0);
                        }

                        __instance.m_lock.ReleaseMutex();
                    }
                }

                Thread.Sleep(10);
            }

            return(false);
        }
示例#2
0
 public static void BeginTerrainChanges()
 {
     // Stop and reset the heightmap generator first
     HeightmapBuilder.instance.Dispose();
     var _ = new HeightmapBuilder();
 }