source: TFP-WebServer/MapRendering/src/MapTileCache.cs@ 445

Last change on this file since 445 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
Line 
1using System;
2using System.Diagnostics.CodeAnalysis;
3using System.IO;
4using UnityEngine;
5using UnityEngine.Profiling;
6using Webserver.FileCache;
7using Object = UnityEngine.Object;
8
9namespace MapRendering {
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.
12 public class MapTileCache : AbstractCache {
13 private readonly byte[] transparentTile;
14 private CurrentZoomFile[] cache;
15
16 public MapTileCache (int _tileSize) {
17 Texture2D tex = new Texture2D (_tileSize, _tileSize);
18 Color nullColor = new Color (0, 0, 0, 0);
19 for (int x = 0; x < _tileSize; x++) {
20 for (int y = 0; y < _tileSize; y++) {
21 tex.SetPixel (x, y, nullColor);
22 }
23 }
24
25 transparentTile = tex.EncodeToPNG ();
26 Object.Destroy (tex);
27 }
28
29 // SetZoomCount only called before processing happens in MapRenderer.ctor, no locking required
30 [SuppressMessage ("ReSharper", "InconsistentlySynchronizedField")]
31 public void SetZoomCount (int _count) {
32 cache = new CurrentZoomFile[_count];
33 for (int i = 0; i < cache.Length; i++) {
34 cache [i] = new CurrentZoomFile ();
35 }
36 }
37
38 public byte[] LoadTile (int _zoomlevel, string _filename) {
39 try {
40 lock (cache) {
41 CurrentZoomFile cacheEntry = cache [_zoomlevel];
42
43 if (cacheEntry.filename != null && cacheEntry.filename.Equals (_filename)) {
44 return cacheEntry.pngData;
45 }
46
47 cacheEntry.filename = _filename;
48
49 if (!File.Exists (_filename)) {
50 cacheEntry.pngData = null;
51 return null;
52 }
53
54 Profiler.BeginSample ("ReadPng");
55 cacheEntry.pngData = ReadAllBytes (_filename);
56 Profiler.EndSample ();
57
58 return cacheEntry.pngData;
59 }
60 } catch (Exception e) {
61 Log.Warning ($"Error in MapTileCache.LoadTile: {e}");
62 }
63
64 return null;
65 }
66
67 public void SaveTile (int _zoomlevel, byte[] _contentPng) {
68 try {
69 lock (cache) {
70 CurrentZoomFile cacheEntry = cache [_zoomlevel];
71
72 string file = cacheEntry.filename;
73 if (string.IsNullOrEmpty (file)) {
74 return;
75 }
76
77 cacheEntry.pngData = _contentPng;
78
79 Profiler.BeginSample ("WritePng");
80 using (Stream stream = new FileStream (file, FileMode.Create, FileAccess.ReadWrite, FileShare.None,
81 4096)) {
82 stream.Write (_contentPng, 0, _contentPng.Length);
83 }
84 Profiler.EndSample ();
85 }
86 } catch (Exception e) {
87 Log.Warning ($"Error in MapTileCache.SaveTile: {e}");
88 }
89 }
90
91 public void ResetTile (int _zoomlevel) {
92 try {
93 lock (cache) {
94 cache [_zoomlevel].filename = null;
95 cache [_zoomlevel].pngData = null;
96 }
97 } catch (Exception e) {
98 Log.Warning ($"Error in MapTileCache.ResetTile: {e}");
99 }
100 }
101
102 public override byte[] GetFileContent (string _filename) {
103 try {
104 lock (cache) {
105 foreach (CurrentZoomFile czf in cache) {
106 if (czf.filename != null && czf.filename.Equals (_filename)) {
107 return czf.pngData;
108 }
109 }
110
111 return !File.Exists (_filename) ? transparentTile : ReadAllBytes (_filename);
112 }
113 } catch (Exception e) {
114 Log.Warning ($"Error in MapTileCache.GetFileContent: {e}");
115 }
116
117 return null;
118 }
119
120 public override (int, int) Invalidate () {
121 return (0, 0);
122 }
123
124 private static byte[] ReadAllBytes (string _path) {
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");
134 }
135
136 bytesRead += readThisTime;
137 bytesLeft -= readThisTime;
138 }
139
140 return result;
141 }
142
143
144 private class CurrentZoomFile {
145 public string filename;
146 public byte[] pngData;
147 }
148 }
149}
Note: See TracBrowser for help on using the repository browser.