source: binary-improvements/7dtd-server-fixes/src/FileCache/MapTileCache.cs@ 345

Last change on this file since 345 was 331, checked in by alloc, 6 years ago

Major allocation and execution time improvements on the map rendering code

File size: 3.3 KB
RevLine 
[199]1using System;
2using System.IO;
[324]3using UnityEngine;
[329]4using UnityEngine.Profiling;
[325]5using Object = UnityEngine.Object;
[199]6
[325]7namespace AllocsFixes.FileCache {
[199]8 // Special "cache" for map tile folder as both map rendering and webserver access files in there.
9 // Only map rendering tiles are cached. Writing is done by WriteThrough.
[325]10 public class MapTileCache : AbstractCache {
11 private readonly byte[] transparentTile;
[199]12 private CurrentZoomFile[] cache;
13
[325]14 public MapTileCache (int _tileSize) {
[324]15 Texture2D tex = new Texture2D (_tileSize, _tileSize);
16 Color nullColor = new Color (0, 0, 0, 0);
[269]17 for (int x = 0; x < _tileSize; x++) {
18 for (int y = 0; y < _tileSize; y++) {
19 tex.SetPixel (x, y, nullColor);
20 }
21 }
[325]22
[269]23 transparentTile = tex.EncodeToPNG ();
[325]24 Object.Destroy (tex);
[199]25 }
26
[325]27 public void SetZoomCount (int count) {
[199]28 cache = new CurrentZoomFile[count];
[329]29 for (int i = 0; i < cache.Length; i++) {
30 cache [i] = new CurrentZoomFile ();
31 }
[199]32 }
33
[325]34 public byte[] LoadTile (int zoomlevel, string filename) {
[199]35 try {
36 lock (cache) {
[329]37 CurrentZoomFile cacheEntry = cache [zoomlevel];
38
39 if (cacheEntry.filename == null || !cacheEntry.filename.Equals (filename)) {
40 cacheEntry.filename = filename;
[199]41
42 if (!File.Exists (filename)) {
[329]43 cacheEntry.pngData = null;
[199]44 return null;
45 }
46
[329]47 Profiler.BeginSample ("ReadPng");
[331]48 cacheEntry.pngData = ReadAllBytes (filename);
[329]49 Profiler.EndSample ();
[199]50 }
[325]51
[329]52 return cacheEntry.pngData;
[199]53 }
54 } catch (Exception e) {
[329]55 Log.Warning ("Error in MapTileCache.LoadTile: " + e);
[199]56 }
[325]57
[199]58 return null;
59 }
60
[329]61 public void SaveTile (int zoomlevel, byte[] contentPng) {
[199]62 try {
63 lock (cache) {
[329]64 CurrentZoomFile cacheEntry = cache [zoomlevel];
[331]65
66 string file = cacheEntry.filename;
67 if (string.IsNullOrEmpty (file)) {
[326]68 return;
[199]69 }
[329]70
71 cacheEntry.pngData = contentPng;
[326]72
[329]73 Profiler.BeginSample ("WritePng");
[331]74 using (Stream stream = new FileStream (file, FileMode.Create, FileAccess.ReadWrite, FileShare.None,
75 4096)) {
76 stream.Write (contentPng, 0, contentPng.Length);
77 }
[329]78 Profiler.EndSample ();
[199]79 }
80 } catch (Exception e) {
[329]81 Log.Warning ("Error in MapTileCache.SaveTile: " + e);
[199]82 }
83 }
84
[325]85 public override byte[] GetFileContent (string filename) {
[199]86 try {
87 lock (cache) {
88 foreach (CurrentZoomFile czf in cache) {
[325]89 if (czf.filename != null && czf.filename.Equals (filename)) {
[329]90 return czf.pngData;
[325]91 }
[199]92 }
93
94 if (!File.Exists (filename)) {
[269]95 return transparentTile;
[199]96 }
[325]97
[331]98 return ReadAllBytes (filename);
[199]99 }
100 } catch (Exception e) {
[329]101 Log.Warning ("Error in MapTileCache.GetFileContent: " + e);
[199]102 }
[325]103
[199]104 return null;
105 }
106
[331]107 private static byte[] ReadAllBytes (string _path) {
108 using (FileStream fileStream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096)) {
109 int bytesRead = 0;
110 int bytesLeft = (int) fileStream.Length;
111 byte[] result = new byte[bytesLeft];
112 while (bytesLeft > 0) {
113 int readThisTime = fileStream.Read (result, bytesRead, bytesLeft);
114 if (readThisTime == 0) {
115 throw new IOException ("Unexpected end of stream");
116 }
117
118 bytesRead += readThisTime;
119 bytesLeft -= readThisTime;
120 }
121
122 return result;
123 }
124 }
125
126
[329]127 private class CurrentZoomFile {
[325]128 public string filename;
[329]129 public byte[] pngData;
[325]130 }
[199]131 }
[325]132}
Note: See TracBrowser for help on using the repository browser.