public void CollectInfo() { m_text.Length = 0; m_lines = 13; m_text.ConcatFormat("Currently allocated: {0}\n", m_allocMem.GetKiloString()); m_text.ConcatFormat("Peak allocated: {0}\n", m_peakAlloc.GetKiloString()); m_text.ConcatFormat("Last collected: {0}\n", m_collectAlloc.GetKiloString()); m_text.ConcatFormat("Allocation rate: {0}\n", m_allocRate.GetKiloString()); m_text.ConcatFormat("Collection freq: {0:0.00}s\n", m_delta); m_text.ConcatFormat("Last collect delta: {0:0.000}s ({1:0.0} FPS)\n", m_lastDeltaTime, 1f / m_lastDeltaTime); if (World != null) { ++m_lines; m_text.ConcatFormat("Chunks: {0}\n", World.Count); } // Tasks m_text.Append("-------------------------------------------------------\n"); m_text.ConcatFormat("TP tasks: {0}\n", WorkPoolManager.ToString()); m_text.ConcatFormat("IO tasks: {0}\n", IOPoolManager.ToString()); // Individual object pools m_text.Append("-------------------------------------------------------\n"); m_text.ConcatFormat("{0}\n", GameObjectProvider.Instance.ToString()); m_text.ConcatFormat("Main pools: {0}\n", Globals.MemPools.ToString()); // the main thread pool m_text.ConcatFormat("IO pools: {0}\n", Globals.IOPool.Pools.ToString()); // io pool for (int i = 0; i < Globals.WorkPool.Size; i++) { ++m_lines; m_text.ConcatFormat("TP #{0} pools: {1}\n", i + 1, Globals.WorkPool.GetPool(i).ToString()); // thread pool } }
public PathFinder(Vector3Int start, Vector3Int target, World world, float range = 0.5f, int entityHeight = 1) { // Don't search the path if our target is too close if (start.Distance2(ref target) <= range * range) { return; } path = new List <Vector3Int>(); open = new Dictionary <Vector3Int, Heuristics>(); closed = new Dictionary <Vector3Int, Heuristics>(); this.world = world; this.range = range; this.entityHeight = entityHeight; this.start = start; this.target = target; distanceFromStartToTarget = start.Distance2(ref target); open.Add(start, new Heuristics(0, distanceFromStartToTarget, start)); status = Status.working; WorkPoolManager.Add( new ThreadPoolItem <PathFinder>( Globals.WorkPool, arg => { arg.ComputePath(); }, this ), false); }
private bool GenerateData() { m_pendingStates = m_pendingStates.Reset(CurrStateGenerateData); m_completedStates = m_completedStates.Reset(CurrStateGenerateData | CurrStateLoadData); m_completedStatesSafe = m_completedStates; m_taskRunning = true; if (chunk.world.networking.isServer) { // Let server generate chunk data WorkPoolManager.Add( new ThreadPoolItem( chunk.ThreadID, arg => { ChunkStateManagerClient stateManager = (ChunkStateManagerClient)arg; OnGenerateData(stateManager); }, this) ); } else { // Client only asks for data chunk.world.networking.client.RequestChunk(chunk.pos); } return(true); }
private void ProcessUpdateRequests() { Blocks = 0; // Process removal requests for (int i = 0; i < m_updateRequests.Count;) { Chunk chunk = m_updateRequests[i]; OnProcessChunk(chunk); // Process chunk events chunk.UpdateChunk(); Blocks += chunk.NonEmptyBlocks; // Automatically collect chunks which are ready to be removed form the world if (chunk.IsFinished()) { // Remove the chunk from our provider and unregister it from chunk storage ChunkProvider.ReleaseChunk(chunk); m_chunks.Remove(chunk.Pos.X, chunk.Pos.Y, chunk.Pos.Z); // Unregister from updates m_updateRequests.RemoveAt(i); continue; } ++i; } // Commit collected work items WorkPoolManager.Commit(); IOPoolManager.Commit(); }
private bool PerformGenericWork() { m_pendingStates = m_pendingStates.Reset(CurrStateGenericWork); m_completedStates = m_completedStates.Reset(CurrStateGenericWork); // If there's nothing to do we can skip this state if (m_genericWorkItems.Count <= 0) { OnGenericWorkDone(this); m_completedStatesSafe = m_completedStates; return(false); } m_completedStatesSafe = m_completedStates; // We have work to do SGenericWorkItem workItem = new SGenericWorkItem(this, m_genericWorkItems.Dequeue()); m_taskRunning = true; WorkPoolManager.Add( new ThreadPoolItem( chunk.ThreadID, arg => { SGenericWorkItem item = (SGenericWorkItem)arg; OnGenericWork(ref item); }, workItem) ); return(true); }
private bool GenerateBlueprints() { Assert.IsTrue(m_completedTasks.Check(ChunkState.Generate), string.Format("[{0},{1},{2}] - GenerateBlueprints set sooner than Generate completed. Pending:{3}, Completed:{4}", Pos.X, Pos.Y, Pos.Z, m_pendingTasks, m_completedTasks) ); if (!m_completedTasks.Check(ChunkState.Generate)) { return(true); } m_pendingTasks = m_pendingTasks.Reset(CurrStateGenerateBlueprints); if (m_completedTasks.Check(CurrStateGenerateBlueprints)) { OnGenerateBlueprintsDone(this); return(false); } m_completedTasks = m_completedTasks.Reset(CurrStateGenerateBlueprints); m_taskRunning = true; WorkPoolManager.Add(new ThreadItem( m_threadID, arg => { Chunk chunk = (Chunk)arg; OnGenerateBlueprints(chunk); }, this) ); return(true); }
private bool GenerateData(bool possiblyVisible) { if (m_completedTasks.Check(CurrStateGenerateData)) { m_pendingTasks = m_pendingTasks.Reset(CurrStateGenerateData); OnGenerateDataDone(this); return(false); } // In order to save performance only generate data on-demand if (!possiblyVisible) { return(true); } m_pendingTasks = m_pendingTasks.Reset(CurrStateGenerateData); m_completedTasks = m_completedTasks.Reset(CurrStateGenerateData); m_taskRunning = true; WorkPoolManager.Add(new ThreadItem( m_threadID, arg => { Chunk chunk = (Chunk)arg; OnGenerateData(chunk); }, this) ); return(true); }
private bool FinalizeData() { #if ENABLE_BLUEPRINTS // All sections must have blueprints generated first Assert.IsTrue( m_completedTasks.Check(ChunkState.GenerateBlueprints), string.Format("[{0},{1},{2}] - FinalizeData set sooner than GenerateBlueprints completed. Pending:{3}, Completed:{4}", Pos.X, Pos.Y, Pos.Z, m_pendingTasks, m_completedTasks) ); if (!m_completedTasks.Check(ChunkState.GenerateBlueprints)) { return(true); } #else Assert.IsTrue( m_completedTasks.Check(ChunkState.Generate), string.Format("[{0},{1},{2}] - FinalizeData set sooner than Generate completed. Pending:{3}, Completed:{4}", Pos.X, Pos.Y, Pos.Z, m_pendingTasks, m_completedTasks) ); if (!m_completedTasks.Check(ChunkState.Generate)) { return(true); } #endif m_pendingTasks = m_pendingTasks.Reset(CurrStateFinalizeData); // Nothing here for us to do if the chunk was not changed if (m_completedTasks.Check(CurrStateFinalizeData) && !m_refreshTasks.Check(CurrStateFinalizeData)) { OnFinalizeDataDone(this); return(false); } m_refreshTasks = m_refreshTasks.Reset(CurrStateFinalizeData); m_completedTasks = m_completedTasks.Reset(CurrStateFinalizeData); m_taskRunning = true; WorkPoolManager.Add(new ThreadItem( m_threadID, arg => { Chunk chunk = (Chunk)arg; OnFinalizeData(chunk); }, this) ); return(true); }
private bool PerformGenericWork() { // When we get here we expect all generic tasks to be processed Assert.IsTrue(Interlocked.CompareExchange(ref m_genericWorkItemsLeftToProcess, 0, 0) == 0); m_pendingTasks = m_pendingTasks.Reset(CurrStateGenericWork); // Nothing here for us to do if the chunk was not changed if (m_completedTasks.Check(CurrStateGenericWork) && !m_refreshTasks.Check(CurrStateGenericWork)) { m_genericWorkItemsLeftToProcess = 0; OnGenericWorkDone(this); return(false); } m_refreshTasks = m_refreshTasks.Reset(CurrStateGenericWork); m_completedTasks = m_completedTasks.Reset(CurrStateGenericWork); // If there's nothing to do we can skip this state if (m_genericWorkItems.Count <= 0) { m_genericWorkItemsLeftToProcess = 0; OnGenericWorkDone(this); return(false); } m_taskRunning = true; m_genericWorkItemsLeftToProcess = m_genericWorkItems.Count; for (int i = 0; i < m_genericWorkItems.Count; i++) { SGenericWorkItem workItem = new SGenericWorkItem(this, m_genericWorkItems[i]); WorkPoolManager.Add( new ThreadItem( m_threadID, arg => { SGenericWorkItem item = (SGenericWorkItem)arg; OnGenericWork(ref item); }, workItem) ); } m_genericWorkItems.Clear(); return(true); }
/// <summary> /// Build this minichunk's render buffers /// </summary> private void GenerateVertices() { /*Assert.IsTrue( * m_completedTasks.Check(ChunkState.FinalizeData), * string.Format("[{0},{1},{2}] - GenerateVertices set sooner than FinalizeData completed. Pending:{3}, Completed:{4}", Pos.X, Pos.Y, Pos.Z, m_pendingTasks, m_completedTasks) * );*/ if (!m_completedTasks.Check(ChunkState.FinalizeData)) { return; } m_pendingTasks = m_pendingTasks.Reset(CurrStateGenerateVertices); // Nothing here for us to do if the chunk was not changed since the last time geometry was built if (m_completedTasks.Check(CurrStateGenerateVertices) && !m_refreshTasks.Check(CurrStateGenerateVertices)) { OnGenerateVerticesDone(this); return; } m_refreshTasks = m_refreshTasks.Reset(CurrStateGenerateVertices); m_completedTasks = m_completedTasks.Reset(CurrStateGenerateVertices); if (NonEmptyBlocks > 0) { IsBuilt = false; var workItem = new SGenerateVerticesWorkItem( this, MinRenderX, MaxRenderX, MinRenderY, MaxRenderY, MinRenderZ, MaxRenderZ, LOD ); m_taskRunning = true; WorkPoolManager.Add(new ThreadItem( m_threadID, arg => { SGenerateVerticesWorkItem item = (SGenerateVerticesWorkItem)arg; OnGenerateVerices(item.Chunk, item.MinX, item.MaxX, item.MinY, item.MaxY, item.MinZ, item.MaxZ, item.LOD); }, workItem) ); } else { OnGenerateVerticesDone(this); } }
/// <summary> /// Build this chunk's collision geometry /// </summary> private bool GenerateCollider() { if (!m_completedStates.Check(ChunkState.LoadData)) { return(true); } if (!SynchronizeChunk()) { return(true); } m_pendingStates = m_pendingStates.Reset(CurrStateGenerateCollider); m_completedStates = m_completedStates.Reset(CurrStateGenerateCollider); m_completedStatesSafe = m_completedStates; if (chunk.blocks.NonEmptyBlocks > 0) { var workItem = new SGenerateColliderWorkItem( this, m_minRenderX, m_maxRenderX, m_minRenderY, m_maxRenderY, m_minRenderZ, m_maxRenderZ ); m_taskRunning = true; WorkPoolManager.Add( new ThreadPoolItem( chunk.ThreadID, arg => { SGenerateColliderWorkItem item = (SGenerateColliderWorkItem)arg; OnGenerateCollider(ref item); }, workItem) ); return(true); } OnGenerateColliderDone(this); return(false); }
/// <summary> /// Build this chunk's geometry /// </summary> private bool GenerateVertices() { if (!SynchronizeChunk()) { return(true); } bool priority = m_pendingStates.Check(ChunkState.BuildVerticesNow); m_pendingStates = m_pendingStates.Reset(CurrStateGenerateVertices); m_completedStates = m_completedStates.Reset(CurrStateGenerateVertices); m_completedStatesSafe = m_completedStates; if (chunk.NonEmptyBlocks > 0) { var workItem = new SGenerateVerticesWorkItem( this, chunk.MinRenderX, chunk.MaxRenderX, chunk.MinRenderY, chunk.MaxRenderY, chunk.MinRenderZ, chunk.MaxRenderZ, chunk.LOD ); m_taskRunning = true; WorkPoolManager.Add( new ThreadPoolItem( chunk.ThreadID, arg => { SGenerateVerticesWorkItem item = (SGenerateVerticesWorkItem)arg; OnGenerateVerices(item.StateManager, item.MinX, item.MaxX, item.MinY, item.MaxY, item.MinZ, item.MaxZ, item.LOD); }, workItem, priority ? Globals.Watch.ElapsedTicks : long.MaxValue) ); } else { OnGenerateVerticesDone(this); } return(true); }
/// <summary> /// Build this chunk's geometry /// </summary> private bool GenerateVertices() { if (!m_completedStates.Check(ChunkState.LoadData)) { return(true); } if (!SynchronizeChunk()) { return(true); } bool priority = m_pendingStates.Check(ChunkState.BuildVerticesNow); m_pendingStates = m_pendingStates.Reset(CurrStateGenerateVertices); m_completedStates = m_completedStates.Reset(CurrStateGenerateVertices); m_completedStatesSafe = m_completedStates; if (chunk.blocks.NonEmptyBlocks > 0) { var workItem = new SGenerateVerticesWorkItem(this); m_taskRunning = true; WorkPoolManager.Add( new ThreadPoolItem( chunk.ThreadID, arg => { SGenerateVerticesWorkItem item = (SGenerateVerticesWorkItem)arg; OnGenerateVerices(ref item); }, workItem, priority ? Globals.Watch.ElapsedTicks : long.MaxValue) ); return(true); } OnGenerateVerticesDone(this); return(false); }
private void UpdateCache() { #if DEBUG // Make it possible to see results in real-time m_clipmap.Init(ForceLOD, LODCoef); #endif // Register new chunks in chunk manager foreach (var chunkPos in m_chunksToLoadByPos) { int xx = ViewerChunkPos.X + chunkPos.X; int yy = ViewerChunkPos.Y + chunkPos.Y; int zz = ViewerChunkPos.Z + chunkPos.Z; RegisterChunk(xx, yy, zz); } // Commit collected work items WorkPoolManager.Commit(); IOPoolManager.Commit(); }
/// <summary> /// Build this chunk's geometry /// </summary> private bool BuildVertices() { if (!m_completedStates.Check(ChunkState.Generate)) { return(true); } if (!SynchronizeChunk()) { return(true); } bool priority = m_pendingStates.Check(ChunkState.BuildVerticesNow); m_pendingStates = m_pendingStates.Reset(ChunkStates.CurrStateBuildVertices); m_completedStates = m_completedStates.Reset(ChunkStates.CurrStateBuildVertices); m_completedStatesSafe = m_completedStates; if (chunk.blocks.NonEmptyBlocks > 0) { var task = Globals.MemPools.SMThreadPI.Pop(); m_poolState = m_poolState.Set(ChunkPoolItemState.ThreadPI); m_threadPoolItem = task; task.Set( chunk.ThreadID, actionOnBuildVertices, this, priority ? Globals.Watch.ElapsedTicks : long.MinValue ); m_taskRunning = true; WorkPoolManager.Add(task, priority); return(true); } OnBuildVerticesDone(this); return(false); }
private bool GenerateData() { m_pendingStates = m_pendingStates.Reset(CurrStateGenerateData); m_completedStates = m_completedStates.Reset(CurrStateGenerateData | CurrStateLoadData); m_completedStatesSafe = m_completedStates; m_taskRunning = true; // Let server generate chunk data WorkPoolManager.Add( new ThreadPoolItem( chunk.ThreadID, arg => { ChunkStateManagerServer stateManager = (ChunkStateManagerServer)arg; OnGenerateData(stateManager); }, this) ); return(true); }
private bool GenerateData() { if (!m_completedStates.Check(ChunkState.LoadData)) { return(true); } m_pendingStates = m_pendingStates.Reset(CurrStateGenerateData); m_completedStates = m_completedStates.Reset(CurrStateGenerateData); m_completedStatesSafe = m_completedStates; var task = Globals.MemPools.SMThreadPI.Pop(); m_poolState = m_poolState.Set(ChunkPoolItemState.ThreadPI); m_threadPoolItem = task; task.Set(chunk.ThreadID, actionOnGenerateData, this); m_taskRunning = true; WorkPoolManager.Add(task, false); return(true); }
private bool FinalizeData() { if (!m_completedStates.Check(ChunkState.Generate)) { return(true); } m_pendingStates = m_pendingStates.Reset(CurrStateFinalizeData); m_completedStatesSafe = m_completedStates = m_completedStates.Reset(CurrStateFinalizeData); m_taskRunning = true; WorkPoolManager.Add(new ThreadPoolItem( chunk.ThreadID, arg => { ChunkStateManagerClient stateManager = (ChunkStateManagerClient)arg; OnFinalizeData(stateManager); }, this) ); return(true); }
public PathFinder(Vector3Int start, Vector3Int target, World world, float range = 0.5f, int entityHeight = 1) { status = Status.working; this.range = range; startLocation = start.Add(Direction.down); targetLocation = target.Add(Direction.down); distanceFromStartToTarget = Distance(startLocation, targetLocation); this.world = world; this.entityHeight = entityHeight; open.Add(startLocation, new Heuristics(0, distanceFromStartToTarget, startLocation)); WorkPoolManager.Add( new ThreadPoolItem( Globals.WorkPool, arg => { PathFinder pf = arg as PathFinder; pf.ComputePath(); }, this )); }
void Update() { IOPoolManager.Commit(); WorkPoolManager.Commit(); }