1 /* 2 * This file is part of the "GKMap". 3 * GKMap project borrowed from GMap.NET (by radioman). 4 * 5 * Copyright (C) 2009-2018 by radioman (email@radioman.lt). 6 * This program is licensed under the FLAT EARTH License. 7 */ 8 9 using System; 10 using System.Collections.Generic; 11 12 namespace GKMap 13 { 14 /// <summary> 15 /// matrix for tiles 16 /// </summary> 17 internal class TileMatrix : IDisposable 18 { 19 private List<Dictionary<GPoint, Tile>> fLevels; 20 private RWLock fLock; 21 private List<KeyValuePair<GPoint, Tile>> fTemp; 22 TileMatrix()23 public TileMatrix() 24 { 25 fLevels = new List<Dictionary<GPoint, Tile>>(33); 26 fLock = new RWLock(); 27 fTemp = new List<KeyValuePair<GPoint, Tile>>(44); 28 29 for (int i = 0; i < fLevels.Capacity; i++) { 30 fLevels.Add(new Dictionary<GPoint, Tile>(55, new GPointComparer())); 31 } 32 } 33 ClearAllLevels()34 public void ClearAllLevels() 35 { 36 fLock.AcquireWriterLock(); 37 try { 38 foreach (var matrix in fLevels) { 39 foreach (var t in matrix) { 40 t.Value.Dispose(); 41 } 42 matrix.Clear(); 43 } 44 } finally { 45 fLock.ReleaseWriterLock(); 46 } 47 } 48 ClearLevel(int zoom)49 public void ClearLevel(int zoom) 50 { 51 fLock.AcquireWriterLock(); 52 try { 53 if (zoom < fLevels.Count) { 54 var l = fLevels[zoom]; 55 56 foreach (var t in l) { 57 t.Value.Dispose(); 58 } 59 60 l.Clear(); 61 } 62 } finally { 63 fLock.ReleaseWriterLock(); 64 } 65 } 66 ClearLevelAndPointsNotIn(int zoom, List<DrawTile> list)67 public void ClearLevelAndPointsNotIn(int zoom, List<DrawTile> list) 68 { 69 fLock.AcquireWriterLock(); 70 try { 71 if (zoom < fLevels.Count) { 72 var l = fLevels[zoom]; 73 74 fTemp.Clear(); 75 76 foreach (var t in l) { 77 if (!list.Exists(p => p.PosXY == t.Key)) { 78 fTemp.Add(t); 79 } 80 } 81 82 foreach (var r in fTemp) { 83 l.Remove(r.Key); 84 r.Value.Dispose(); 85 } 86 87 fTemp.Clear(); 88 } 89 } finally { 90 fLock.ReleaseWriterLock(); 91 } 92 } 93 ClearLevelsBelow(int zoom)94 public void ClearLevelsBelow(int zoom) 95 { 96 fLock.AcquireWriterLock(); 97 try { 98 if (zoom - 1 < fLevels.Count) { 99 for (int i = zoom - 1; i >= 0; i--) { 100 var l = fLevels[i]; 101 102 foreach (var t in l) { 103 t.Value.Dispose(); 104 } 105 106 l.Clear(); 107 } 108 } 109 } finally { 110 fLock.ReleaseWriterLock(); 111 } 112 } 113 ClearLevelsAbove(int zoom)114 public void ClearLevelsAbove(int zoom) 115 { 116 fLock.AcquireWriterLock(); 117 try { 118 if (zoom + 1 < fLevels.Count) { 119 for (int i = zoom + 1; i < fLevels.Count; i++) { 120 var l = fLevels[i]; 121 122 foreach (var t in l) { 123 t.Value.Dispose(); 124 } 125 126 l.Clear(); 127 } 128 } 129 } finally { 130 fLock.ReleaseWriterLock(); 131 } 132 } 133 EnterReadLock()134 public void EnterReadLock() 135 { 136 fLock.AcquireReaderLock(); 137 } 138 LeaveReadLock()139 public void LeaveReadLock() 140 { 141 fLock.ReleaseReaderLock(); 142 } 143 GetTileWithNoLock(int zoom, GPoint p)144 public Tile GetTileWithNoLock(int zoom, GPoint p) 145 { 146 Tile ret; 147 fLevels[zoom].TryGetValue(p, out ret); 148 149 return ret; 150 } 151 GetTileWithReadLock(int zoom, GPoint p)152 public Tile GetTileWithReadLock(int zoom, GPoint p) 153 { 154 Tile ret; 155 156 fLock.AcquireReaderLock(); 157 try { 158 ret = GetTileWithNoLock(zoom, p); 159 } finally { 160 fLock.ReleaseReaderLock(); 161 } 162 163 return ret; 164 } 165 SetTile(Tile t)166 public void SetTile(Tile t) 167 { 168 fLock.AcquireWriterLock(); 169 try { 170 if (t.Zoom < fLevels.Count) { 171 fLevels[t.Zoom][t.Pos] = t; 172 } 173 } finally { 174 fLock.ReleaseWriterLock(); 175 } 176 } 177 ~TileMatrix()178 ~TileMatrix() 179 { 180 Dispose(false); 181 } 182 Dispose(bool disposing)183 void Dispose(bool disposing) 184 { 185 if (fLock != null) { 186 if (disposing) { 187 ClearAllLevels(); 188 } 189 190 fLevels.Clear(); 191 fLevels = null; 192 193 fTemp.Clear(); 194 fTemp = null; 195 196 fLock.Dispose(); 197 fLock = null; 198 } 199 } 200 Dispose()201 public void Dispose() 202 { 203 this.Dispose(true); 204 GC.SuppressFinalize(this); 205 } 206 } 207 } 208