source: binary-improvements2/MapRendering/src/MapTileCache.cs@ 402

Last change on this file since 402 was 402, checked in by alloc, 22 months ago
  • Major refactoring
  • Using Utf8Json for (de)serialization
  • Moving APIs to REST
  • Removing dependencies from WebServer and MapRenderer to ServerFixes
File size: 3.8 KB
RevLine 
[199]1using System;
[402]2using System.Diagnostics.CodeAnalysis;
[199]3using System.IO;
[324]4using UnityEngine;
[329]5using UnityEngine.Profiling;
[402]6using Webserver.FileCache;
[325]7using Object = UnityEngine.Object;
[199]8
[402]9namespace MapRendering {
[199]10 // Special "cache" for map tile folder as both map rendering and webserver access files in there.
11 // Only map rendering tiles are cached. Writing is done by WriteThrough.
[325]12 public class MapTileCache : AbstractCache {
13 private readonly byte[] transparentTile;
[199]14 private CurrentZoomFile[] cache;
15
[325]16 public MapTileCache (int _tileSize) {
[324]17 Texture2D tex = new Texture2D (_tileSize, _tileSize);
18 Color nullColor = new Color (0, 0, 0, 0);
[269]19 for (int x = 0; x < _tileSize; x++) {
20 for (int y = 0; y < _tileSize; y++) {
21 tex.SetPixel (x, y, nullColor);
22 }
23 }
[325]24
[269]25 transparentTile = tex.EncodeToPNG ();
[325]26 Object.Destroy (tex);
[199]27 }
28
[402]29 // SetZoomCount only called before processing happens in MapRenderer.ctor, no locking required
30 [SuppressMessage ("ReSharper", "InconsistentlySynchronizedField")]
[351]31 public void SetZoomCount (int _count) {
32 cache = new CurrentZoomFile[_count];
[329]33 for (int i = 0; i < cache.Length; i++) {
34 cache [i] = new CurrentZoomFile ();
35 }
[199]36 }
37
[351]38 public byte[] LoadTile (int _zoomlevel, string _filename) {
[199]39 try {
40 lock (cache) {
[351]41 CurrentZoomFile cacheEntry = cache [_zoomlevel];
[199]42
[391]43 if (cacheEntry.filename != null && cacheEntry.filename.Equals (_filename)) {
44 return cacheEntry.pngData;
45 }
[199]46
[391]47 cacheEntry.filename = _filename;
48
49 if (!File.Exists (_filename)) {
50 cacheEntry.pngData = null;
51 return null;
[199]52 }
[325]53
[391]54 Profiler.BeginSample ("ReadPng");
55 cacheEntry.pngData = ReadAllBytes (_filename);
56 Profiler.EndSample ();
57
[329]58 return cacheEntry.pngData;
[199]59 }
60 } catch (Exception e) {
[402]61 Log.Warning ($"Error in MapTileCache.LoadTile: {e}");
[199]62 }
[325]63
[199]64 return null;
65 }
66
[351]67 public void SaveTile (int _zoomlevel, byte[] _contentPng) {
[199]68 try {
69 lock (cache) {
[351]70 CurrentZoomFile cacheEntry = cache [_zoomlevel];
[331]71
72 string file = cacheEntry.filename;
73 if (string.IsNullOrEmpty (file)) {
[326]74 return;
[199]75 }
[329]76
[351]77 cacheEntry.pngData = _contentPng;
[326]78
[329]79 Profiler.BeginSample ("WritePng");
[331]80 using (Stream stream = new FileStream (file, FileMode.Create, FileAccess.ReadWrite, FileShare.None,
81 4096)) {
[351]82 stream.Write (_contentPng, 0, _contentPng.Length);
[331]83 }
[329]84 Profiler.EndSample ();
[199]85 }
86 } catch (Exception e) {
[402]87 Log.Warning ($"Error in MapTileCache.SaveTile: {e}");
[199]88 }
89 }
90
[351]91 public void ResetTile (int _zoomlevel) {
[346]92 try {
93 lock (cache) {
[351]94 cache [_zoomlevel].filename = null;
95 cache [_zoomlevel].pngData = null;
[346]96 }
97 } catch (Exception e) {
[402]98 Log.Warning ($"Error in MapTileCache.ResetTile: {e}");
[346]99 }
100 }
101
[351]102 public override byte[] GetFileContent (string _filename) {
[199]103 try {
104 lock (cache) {
105 foreach (CurrentZoomFile czf in cache) {
[351]106 if (czf.filename != null && czf.filename.Equals (_filename)) {
[329]107 return czf.pngData;
[325]108 }
[199]109 }
110
[391]111 return !File.Exists (_filename) ? transparentTile : ReadAllBytes (_filename);
[199]112 }
113 } catch (Exception e) {
[402]114 Log.Warning ($"Error in MapTileCache.GetFileContent: {e}");
[199]115 }
[325]116
[199]117 return null;
118 }
119
[392]120 public override (int, int) Invalidate () {
121 return (0, 0);
122 }
123
[331]124 private static byte[] ReadAllBytes (string _path) {
[402]125 using FileStream fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096);
126
127 int bytesRead = 0;
128 int bytesLeft = (int) fileStream.Length;
129 byte[] result = new byte[bytesLeft];
130 while (bytesLeft > 0) {
131 int readThisTime = fileStream.Read (result, bytesRead, bytesLeft);
132 if (readThisTime == 0) {
133 throw new IOException ("Unexpected end of stream");
[331]134 }
135
[402]136 bytesRead += readThisTime;
137 bytesLeft -= readThisTime;
[331]138 }
[402]139
140 return result;
[331]141 }
142
143
[329]144 private class CurrentZoomFile {
[325]145 public string filename;
[329]146 public byte[] pngData;
[325]147 }
[199]148 }
[325]149}
Note: See TracBrowser for help on using the repository browser.