Automap (OSS) GIT software repository
Revisión | 8c8161c8be42749b0fd0cc90bf3298052a13d355 (tree) |
---|---|
Tiempo | 2022-05-28 05:53:19 |
Autor | ![]() |
Commiter | melchior |
Revisit(er) & ReadOnly chunk use
Plus minor fix for possible null BlockEntity.pos
@@ -161,9 +161,9 @@ namespace Automap | ||
161 | 161 | |
162 | 162 | internal static void DecodePostSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) |
163 | 163 | { |
164 | -#if DEBUG | |
164 | + #if DEBUG | |
165 | 165 | clientAPI.Logger.VerboseDebug("Post-sign Designator Invoked!"); |
166 | -#endif | |
166 | + #endif | |
167 | 167 | //sign post Text into a POI field... |
168 | 168 | BlockEntitySignPost signEntity = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntitySignPost; |
169 | 169 |
@@ -185,6 +185,9 @@ namespace Automap | ||
185 | 185 | |
186 | 186 | internal static void KeepTrackOfMerchant(ICoreClientAPI clientAPI, EntitiesOfInterest poi, BlockPos posn, Entity entity) |
187 | 187 | { |
188 | + #if DEBUG | |
189 | + clientAPI.Logger.VerboseDebug("TRADER Designator Invoked!"); | |
190 | + #endif | |
188 | 191 | //clientAPI.Logger.VerboseDebug("Trader: {0} @ {1}", entity.GetName(), posn); |
189 | 192 | |
190 | 193 | var traderJoe = entity as EntityTrader; |
@@ -44,6 +44,7 @@ namespace Automap | ||
44 | 44 | private static Regex chunkShardRegex = new Regex(@"(?<X>[\d]+)_(?<Z>[\d]+)\.png", RegexOptions.Singleline); |
45 | 45 | |
46 | 46 | private ConcurrentDictionary<Vec2i, ColumnCounter> columnCounters = new ConcurrentDictionary<Vec2i, ColumnCounter>(3, 150); |
47 | + private Queue<Vec2i> revisitChunkList = new Queue<Vec2i>(); | |
47 | 48 | private ColumnsMetadata chunkTopMetadata; |
48 | 49 | internal PointsOfInterest POIs = new PointsOfInterest(); |
49 | 50 | internal EntitiesOfInterest EOIs = new EntitiesOfInterest(); |
@@ -175,7 +176,7 @@ namespace Automap | ||
175 | 176 | } |
176 | 177 | else if (snapshot != null && snapshot.Finished) { |
177 | 178 | #if DEBUG |
178 | - Logger.VerboseDebug("COMPLETED Snapshot: {0} Wx{1} Hx{2}, taking {3}", snapshot.fileName, snapshot.Width, snapshot.Height, snapshot.Timer.Elapsed); | |
179 | + Logger.VerboseDebug("COMPLETED Snapshot: {0} Wx{1} Hx{2}, taking {3}", snapshot.fileName, snapshot.Width, snapshot.Height, snapshot.Timer.Elapsed); | |
179 | 180 | #endif |
180 | 181 | snapshot = null; |
181 | 182 | CurrentState = CommandType.Run; |
@@ -195,10 +196,50 @@ namespace Automap | ||
195 | 196 | uint updatedChunks = 0; |
196 | 197 | uint updatedPixels = 0; |
197 | 198 | |
198 | - //-- Should dodge enumerator changing underfoot....at a cost. | |
199 | - if (!columnCounters.IsEmpty) | |
200 | - { | |
201 | - var tempSet = columnCounters.ToArray().Where(cks => cks.Value.WeightedSum > editThreshold) .OrderByDescending(kvp => kvp.Value.WeightedSum); | |
199 | + | |
200 | + //Revisit failed chunks first; | |
201 | + while (revisitChunkList.Count > 0) | |
202 | + { | |
203 | + var revisitCoord = revisitChunkList.Dequeue( ); | |
204 | + var rv_mapChunk = ClientAPI.World.BlockAccessor.GetMapChunk(revisitCoord); | |
205 | + | |
206 | + if (rv_mapChunk == null) continue; | |
207 | + | |
208 | + ColumnMeta rv_chunkMeta; | |
209 | + if (chunkTopMetadata.Contains(revisitCoord)) | |
210 | + { | |
211 | + rv_chunkMeta = chunkTopMetadata[revisitCoord]; | |
212 | + #if DEBUG | |
213 | + Logger.VerboseDebug("(re)Loaded meta-chunk {0}", revisitCoord); | |
214 | + #endif | |
215 | + } | |
216 | + else | |
217 | + { | |
218 | + rv_chunkMeta = CreateColumnMetadata(revisitCoord, rv_mapChunk); | |
219 | + #if DEBUG | |
220 | + Logger.VerboseDebug("(re)Created meta-chunk {0}", revisitCoord); | |
221 | + #endif | |
222 | + } | |
223 | + | |
224 | + ProcessChunkBlocks(revisitCoord, rv_mapChunk, ref rv_chunkMeta); | |
225 | + | |
226 | + ChunkRenderer.SetupPngImage(revisitCoord, path, _chunkPath, ref rv_chunkMeta); | |
227 | + ChunkRenderer.GenerateChunkPngShard(revisitCoord, rv_mapChunk, rv_chunkMeta, ref chunkTopMetadata, out updatedPixels); | |
228 | + | |
229 | + if (updatedPixels > 0) | |
230 | + { | |
231 | + #if DEBUG | |
232 | + Logger.VerboseDebug("(re)Wrote top-chunk shard: ({0}), Pixels#:{2}", revisitCoord, updatedPixels); | |
233 | + #endif | |
234 | + updatedChunks++; | |
235 | + chunkTopMetadata.Update(rv_chunkMeta); | |
236 | + } | |
237 | + }//*********** REVISIT'd ****************** | |
238 | + | |
239 | + if (!columnCounters.IsEmpty) | |
240 | + {//-- Should dodge enumerator changing underfoot....at a cost. | |
241 | + var tempSet = columnCounters.ToArray().Where(cks => cks.Value.WeightedSum > editThreshold) .OrderByDescending(kvp => kvp.Value.WeightedSum); | |
242 | + | |
202 | 243 | UpdateEntityMetadata(); |
203 | 244 | |
204 | 245 | foreach (var mostActiveCol in tempSet) |
@@ -206,13 +247,13 @@ namespace Automap | ||
206 | 247 | var mapChunk = ClientAPI.World.BlockAccessor.GetMapChunk(mostActiveCol.Key); |
207 | 248 | |
208 | 249 | if (mapChunk == null) |
209 | - { | |
210 | - //TODO: REVISIT THIS CHUNK! | |
250 | + { | |
211 | 251 | #if DEBUG |
212 | 252 | Logger.Warning("SKIP CHUNK: ({0}) - Map Chunk NULL!", mostActiveCol.Key); |
213 | 253 | #endif |
214 | 254 | nullMapCount++; |
215 | 255 | columnCounters.TryRemove(mostActiveCol.Key, out ejectedItem); |
256 | + revisitChunkList.Enqueue(mostActiveCol.Key); | |
216 | 257 | continue; |
217 | 258 | } |
218 | 259 |
@@ -252,6 +293,7 @@ namespace Automap | ||
252 | 293 | #if DEBUG |
253 | 294 | Logger.VerboseDebug("Un-painted chunk shard: ({0}) ", mostActiveCol.Key); |
254 | 295 | #endif |
296 | + revisitChunkList.Enqueue(mostActiveCol.Key); | |
255 | 297 | } |
256 | 298 | } |
257 | 299 | } |
@@ -276,32 +318,32 @@ namespace Automap | ||
276 | 318 | columnCounters.Clear( ); |
277 | 319 | |
278 | 320 | //Then sleep until interupted again, and repeat |
279 | -#if DEBUG | |
321 | + #if DEBUG | |
280 | 322 | Logger.VerboseDebug("Thread '{0}' about to sleep indefinitely.", Thread.CurrentThread.Name); |
281 | -#endif | |
323 | + #endif | |
282 | 324 | Thread.Sleep(Timeout.Infinite); |
283 | 325 | |
284 | 326 | } |
285 | 327 | catch (ThreadInterruptedException) |
286 | 328 | { |
287 | 329 | |
288 | -#if DEBUG | |
330 | + #if DEBUG | |
289 | 331 | Logger.VerboseDebug("Thread '{0}' interupted [awoken]", Thread.CurrentThread.Name); |
290 | -#endif | |
332 | + #endif | |
291 | 333 | goto wake; |
292 | 334 | |
293 | 335 | } |
294 | 336 | catch (ThreadAbortException) |
295 | 337 | { |
296 | -#if DEBUG | |
338 | + #if DEBUG | |
297 | 339 | Logger.VerboseDebug("Thread '{0}' aborted.", Thread.CurrentThread.Name); |
298 | -#endif | |
340 | + #endif | |
299 | 341 | } |
300 | 342 | finally |
301 | 343 | { |
302 | -#if DEBUG | |
344 | + #if DEBUG | |
303 | 345 | Logger.VerboseDebug("Thread '{0}' executing finally block.", Thread.CurrentThread.Name); |
304 | -#endif | |
346 | + #endif | |
305 | 347 | PersistPointsData(); |
306 | 348 | Write_PlainMetadata( ); |
307 | 349 | } |
@@ -310,23 +352,23 @@ namespace Automap | ||
310 | 352 | private void Snap() |
311 | 353 | { |
312 | 354 | snapshotTake: |
313 | -#if DEBUG | |
355 | + #if DEBUG | |
314 | 356 | Logger.VerboseDebug("Snapshot started"); |
315 | -#endif | |
357 | + #endif | |
316 | 358 | try |
317 | 359 | { |
318 | 360 | snapshot.Take(); |
319 | -#if DEBUG | |
361 | + #if DEBUG | |
320 | 362 | Logger.VerboseDebug("Snapshot sleeping"); |
321 | -#endif | |
363 | + #endif | |
322 | 364 | CurrentState = CommandType.Run; |
323 | 365 | Thread.Sleep(Timeout.Infinite); |
324 | 366 | } |
325 | 367 | catch (ThreadInterruptedException) |
326 | 368 | { |
327 | -#if DEBUG | |
369 | + #if DEBUG | |
328 | 370 | Logger.VerboseDebug("Snapshot intertupted"); |
329 | -#endif | |
371 | + #endif | |
330 | 372 | goto snapshotTake; |
331 | 373 | } |
332 | 374 | } |
@@ -512,6 +554,19 @@ namespace Automap | ||
512 | 554 | return data; |
513 | 555 | } |
514 | 556 | |
557 | + private ColumnMeta CreateColumnMetadata(Vec2i coords, IMapChunk mapChunk) | |
558 | + { | |
559 | + ColumnMeta data = new ColumnMeta(coords, ClientAPI, ( byte )chunkSize, (ClientAPI.World.BlockAccessor.MapSizeY / chunkSize)); | |
560 | + BlockPos equivBP = new BlockPos(coords.X * chunkSize, | |
561 | + mapChunk.YMax, | |
562 | + coords.Y * chunkSize); | |
563 | + | |
564 | + var climate = ClientAPI.World.BlockAccessor.GetClimateAt(equivBP); | |
565 | + data.UpdateFieldsFrom(climate, mapChunk, TimeSpan.FromHours(ClientAPI.World.Calendar.TotalHours)); | |
566 | + | |
567 | + return data; | |
568 | + } | |
569 | + | |
515 | 570 | /// <summary> |
516 | 571 | /// Reload chunk bounds from chunk shards |
517 | 572 | /// </summary> |
@@ -626,7 +681,7 @@ namespace Automap | ||
626 | 681 | if (worldChunk == null || worldChunk.BlockEntities == null) |
627 | 682 | { |
628 | 683 | #if DEBUG |
629 | - Logger.VerboseDebug("WORLD chunk: null or empty X{0} Y{1} Z{2} !", key.X, targetChunkY, key.Y); | |
684 | + Logger.VerboseDebug("WORLD chunk: null, B.E. null X{0} Y{1} Z{2} !", key.X, targetChunkY, key.Y); | |
630 | 685 | #endif |
631 | 686 | nullChunkCount++; |
632 | 687 | continue; |
@@ -637,7 +692,13 @@ namespace Automap | ||
637 | 692 | #if DEBUG |
638 | 693 | Logger.VerboseDebug("WORLD chunk: Compressed: X{0} Y{1} Z{2}", key.X, targetChunkY, key.Y); |
639 | 694 | #endif |
640 | - worldChunk.Unpack( );//RESEARCH: Thread Unsafe? | |
695 | + //VALIDATE: check Read-only applicable | |
696 | + if (worldChunk.Unpack_ReadOnly( ) == false) | |
697 | + { | |
698 | + Logger.Warning("Failed to unpack chunk: X{0} Y{1} Z{2}", key.X, targetChunkY, key.Y); | |
699 | + nullChunkCount++; | |
700 | + continue; | |
701 | + }; | |
641 | 702 | } |
642 | 703 | |
643 | 704 | /*************** Chunk Entities Scanning *********************/ |
@@ -649,7 +710,7 @@ namespace Automap | ||
649 | 710 | |
650 | 711 | foreach (var blockEnt in worldChunk.BlockEntities) |
651 | 712 | { |
652 | - if (blockEnt.Key != null && blockEnt.Value != null && blockEnt.Value.Block != null && BlockID_Designators.ContainsKey(blockEnt.Value.Block.BlockId)) | |
713 | + if (blockEnt.Key != null && blockEnt.Value != null && blockEnt.Value.Block != null && blockEnt.Value.Pos != null && BlockID_Designators.ContainsKey(blockEnt.Value.Block.BlockId)) | |
653 | 714 | { |
654 | 715 | var designator = BlockID_Designators[blockEnt.Value.Block.BlockId]; |
655 | 716 | designator?.SpecialAction(ClientAPI, POIs, blockEnt.Value.Pos.Copy(), blockEnt.Value.Block); |
@@ -663,7 +724,7 @@ namespace Automap | ||
663 | 724 | int X_index, Y_index, Z_index; |
664 | 725 | |
665 | 726 | //First Chance fail-safe; |
666 | - if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) { | |
727 | + if (worldChunk.MaybeBlocks == null || worldChunk.MaybeBlocks.Length <= 0) { | |
667 | 728 | #if DEBUG |
668 | 729 | Logger.VerboseDebug("WORLD chunk; Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", key.X, targetChunkY, key.Y); |
669 | 730 | #endif |
@@ -682,7 +743,7 @@ namespace Automap | ||
682 | 743 | var indicie = MapUtil.Index3d(X_index, Y_index, Z_index, chunkSize, chunkSize); |
683 | 744 | |
684 | 745 | //'Last' Chance fail-safe; |
685 | - if (worldChunk.Blocks == null || worldChunk.Blocks.Length <= 0) { | |
746 | + if (worldChunk.MaybeBlocks == null || worldChunk.MaybeBlocks.Length <= 0) { | |
686 | 747 | #if DEBUG |
687 | 748 | Logger.VerboseDebug("Processing Block: Missing block DATA⁈ X{0} Y{1} Z{2} ⁈", X_index, Y_index, Z_index); |
688 | 749 | #endif |
@@ -690,7 +751,7 @@ namespace Automap | ||
690 | 751 | goto loop_bustout; |
691 | 752 | } |
692 | 753 | |
693 | - int aBlockId = worldChunk.Blocks[indicie]; | |
754 | + int aBlockId = worldChunk.MaybeBlocks[indicie]; | |
694 | 755 | |
695 | 756 | if (aBlockId == 0 || AiryIdCodes.ContainsKey(aBlockId)) {//Airy blocks,,, |
696 | 757 | chunkMeta.AirBlocks++; |
@@ -7,7 +7,7 @@ | ||
7 | 7 | "version": "0.1.8", |
8 | 8 | "side":"Client", |
9 | 9 | "dependencies": { |
10 | - "game": "1.16.4" | |
10 | + "game": "1.16.5" | |
11 | 11 | }, |
12 | 12 | "website": "http://automap.osdn.io/" |
13 | 13 | } |
\ No newline at end of file |