X-Git-Url: http://git.osdn.net/view?p=automap%2Fautomap.git;a=blobdiff_plain;f=Automap%2FSubsystems%2FAutomapSystem.cs;h=6770ecfc2657f03da54e44938e3630a35ffd1a1c;hp=32cda383711866c677e55b9120e486ac8f0a6232;hb=8c8161c8be42749b0fd0cc90bf3298052a13d355;hpb=1c8849af29a916822885541c010ffc4b7bb90d5a diff --git a/Automap/Subsystems/AutomapSystem.cs b/Automap/Subsystems/AutomapSystem.cs index 32cda38..6770ecf 100644 --- a/Automap/Subsystems/AutomapSystem.cs +++ b/Automap/Subsystems/AutomapSystem.cs @@ -44,6 +44,7 @@ namespace Automap private static Regex chunkShardRegex = new Regex(@"(?[\d]+)_(?[\d]+)\.png", RegexOptions.Singleline); private ConcurrentDictionary columnCounters = new ConcurrentDictionary(3, 150); + private Queue revisitChunkList = new Queue(); private ColumnsMetadata chunkTopMetadata; internal PointsOfInterest POIs = new PointsOfInterest(); internal EntitiesOfInterest EOIs = new EntitiesOfInterest(); @@ -175,7 +176,7 @@ namespace Automap } else if (snapshot != null && snapshot.Finished) { #if DEBUG - Logger.VerboseDebug("COMPLETED Snapshot: {0} Wx{1} Hx{2}, taking {3}", snapshot.fileName, snapshot.Width, snapshot.Height, snapshot.Timer.Elapsed); + Logger.VerboseDebug("COMPLETED Snapshot: {0} Wx{1} Hx{2}, taking {3}", snapshot.fileName, snapshot.Width, snapshot.Height, snapshot.Timer.Elapsed); #endif snapshot = null; CurrentState = CommandType.Run; @@ -195,10 +196,50 @@ namespace Automap uint updatedChunks = 0; uint updatedPixels = 0; - //-- Should dodge enumerator changing underfoot....at a cost. - if (!columnCounters.IsEmpty) - { - var tempSet = columnCounters.ToArray().Where(cks => cks.Value.WeightedSum > editThreshold) .OrderByDescending(kvp => kvp.Value.WeightedSum); + + //Revisit failed chunks first; + while (revisitChunkList.Count > 0) + { + var revisitCoord = revisitChunkList.Dequeue( ); + var rv_mapChunk = ClientAPI.World.BlockAccessor.GetMapChunk(revisitCoord); + + if (rv_mapChunk == null) continue; + + ColumnMeta rv_chunkMeta; + if (chunkTopMetadata.Contains(revisitCoord)) + { + rv_chunkMeta = chunkTopMetadata[revisitCoord]; + #if DEBUG + Logger.VerboseDebug("(re)Loaded meta-chunk {0}", revisitCoord); + #endif + } + else + { + rv_chunkMeta = CreateColumnMetadata(revisitCoord, rv_mapChunk); + #if DEBUG + Logger.VerboseDebug("(re)Created meta-chunk {0}", revisitCoord); + #endif + } + + ProcessChunkBlocks(revisitCoord, rv_mapChunk, ref rv_chunkMeta); + + ChunkRenderer.SetupPngImage(revisitCoord, path, _chunkPath, ref rv_chunkMeta); + ChunkRenderer.GenerateChunkPngShard(revisitCoord, rv_mapChunk, rv_chunkMeta, ref chunkTopMetadata, out updatedPixels); + + if (updatedPixels > 0) + { + #if DEBUG + Logger.VerboseDebug("(re)Wrote top-chunk shard: ({0}), Pixels#:{2}", revisitCoord, updatedPixels); + #endif + updatedChunks++; + chunkTopMetadata.Update(rv_chunkMeta); + } + }//*********** REVISIT'd ****************** + + if (!columnCounters.IsEmpty) + {//-- Should dodge enumerator changing underfoot....at a cost. + var tempSet = columnCounters.ToArray().Where(cks => cks.Value.WeightedSum > editThreshold) .OrderByDescending(kvp => kvp.Value.WeightedSum); + UpdateEntityMetadata(); foreach (var mostActiveCol in tempSet) @@ -206,13 +247,13 @@ namespace Automap var mapChunk = ClientAPI.World.BlockAccessor.GetMapChunk(mostActiveCol.Key); if (mapChunk == null) - { - //TODO: REVISIT THIS CHUNK! + { #if DEBUG Logger.Warning("SKIP CHUNK: ({0}) - Map Chunk NULL!", mostActiveCol.Key); #endif nullMapCount++; columnCounters.TryRemove(mostActiveCol.Key, out ejectedItem); + revisitChunkList.Enqueue(mostActiveCol.Key); continue; } @@ -252,6 +293,7 @@ namespace Automap #if DEBUG Logger.VerboseDebug("Un-painted chunk shard: ({0}) ", mostActiveCol.Key); #endif + revisitChunkList.Enqueue(mostActiveCol.Key); } } } @@ -276,32 +318,32 @@ namespace Automap columnCounters.Clear( ); //Then sleep until interupted again, and repeat -#if DEBUG + #if DEBUG Logger.VerboseDebug("Thread '{0}' about to sleep indefinitely.", Thread.CurrentThread.Name); -#endif + #endif Thread.Sleep(Timeout.Infinite); } catch (ThreadInterruptedException) { -#if DEBUG + #if DEBUG Logger.VerboseDebug("Thread '{0}' interupted [awoken]", Thread.CurrentThread.Name); -#endif + #endif goto wake; } catch (ThreadAbortException) { -#if DEBUG + #if DEBUG Logger.VerboseDebug("Thread '{0}' aborted.", Thread.CurrentThread.Name); -#endif + #endif } finally { -#if DEBUG + #if DEBUG Logger.VerboseDebug("Thread '{0}' executing finally block.", Thread.CurrentThread.Name); -#endif + #endif PersistPointsData(); Write_PlainMetadata( ); } @@ -310,23 +352,23 @@ namespace Automap private void Snap() { snapshotTake: -#if DEBUG + #if DEBUG Logger.VerboseDebug("Snapshot started"); -#endif + #endif try { snapshot.Take(); -#if DEBUG + #if DEBUG Logger.VerboseDebug("Snapshot sleeping"); -#endif + #endif CurrentState = CommandType.Run; Thread.Sleep(Timeout.Infinite); } catch (ThreadInterruptedException) { -#if DEBUG + #if DEBUG Logger.VerboseDebug("Snapshot intertupted"); -#endif + #endif goto snapshotTake; } } @@ -512,6 +554,19 @@ namespace Automap return data; } + private ColumnMeta CreateColumnMetadata(Vec2i coords, IMapChunk mapChunk) + { + ColumnMeta data = new ColumnMeta(coords, ClientAPI, ( byte )chunkSize, (ClientAPI.World.BlockAccessor.MapSizeY / chunkSize)); + BlockPos equivBP = new BlockPos(coords.X * chunkSize, + mapChunk.YMax, + coords.Y * chunkSize); + + var climate = ClientAPI.World.BlockAccessor.GetClimateAt(equivBP); + data.UpdateFieldsFrom(climate, mapChunk, TimeSpan.FromHours(ClientAPI.World.Calendar.TotalHours)); + + return data; + } + /// /// Reload chunk bounds from chunk shards /// @@ -626,7 +681,7 @@ namespace Automap if (worldChunk == null || worldChunk.BlockEntities == null) { #if DEBUG - Logger.VerboseDebug("WORLD chunk: null or empty X{0} Y{1} Z{2} !", key.X, targetChunkY, key.Y); + Logger.VerboseDebug("WORLD chunk: null, B.E. null X{0} Y{1} Z{2} !", key.X, targetChunkY, key.Y); #endif nullChunkCount++; continue; @@ -637,7 +692,13 @@ namespace Automap #if DEBUG Logger.VerboseDebug("WORLD chunk: Compressed: X{0} Y{1} Z{2}", key.X, targetChunkY, key.Y); #endif - worldChunk.Unpack( );//RESEARCH: Thread Unsafe? + //VALIDATE: check Read-only applicable + if (worldChunk.Unpack_ReadOnly( ) == false) + { + Logger.Warning("Failed to unpack chunk: X{0} Y{1} Z{2}", key.X, targetChunkY, key.Y); + nullChunkCount++; + continue; + }; } /*************** Chunk Entities Scanning *********************/ @@ -649,7 +710,7 @@ namespace Automap foreach (var blockEnt in worldChunk.BlockEntities) { - if (blockEnt.Key != null && blockEnt.Value != null && blockEnt.Value.Block != null && BlockID_Designators.ContainsKey(blockEnt.Value.Block.BlockId)) + if (blockEnt.Key != null && blockEnt.Value != null && blockEnt.Value.Block != null && blockEnt.Value.Pos != null && BlockID_Designators.ContainsKey(blockEnt.Value.Block.BlockId)) { var designator = BlockID_Designators[blockEnt.Value.Block.BlockId]; designator?.SpecialAction(ClientAPI, POIs, blockEnt.Value.Pos.Copy(), blockEnt.Value.Block); @@ -663,7 +724,7 @@ namespace Automap int X_index, Y_index, Z_index; //First Chance fail-safe; - if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) { + if (worldChunk.MaybeBlocks == null || worldChunk.MaybeBlocks.Length <= 0) { #if DEBUG Logger.VerboseDebug("WORLD chunk; Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", key.X, targetChunkY, key.Y); #endif @@ -682,7 +743,7 @@ namespace Automap var indicie = MapUtil.Index3d(X_index, Y_index, Z_index, chunkSize, chunkSize); //'Last' Chance fail-safe; - if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) { + if (worldChunk.MaybeBlocks == null || worldChunk.MaybeBlocks.Length <= 0) { #if DEBUG Logger.VerboseDebug("Processing Block: Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", X_index, Y_index, Z_index); #endif @@ -690,7 +751,7 @@ namespace Automap goto loop_bustout; } - int aBlockId = worldChunk.Blocks[indicie]; + int aBlockId = worldChunk.MaybeBlocks[indicie]; if (aBlockId == 0 || AiryIdCodes.ContainsKey(aBlockId)) {//Airy blocks,,, chunkMeta.AirBlocks++;