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 using System.Threading;
12 
13 namespace GKMap
14 {
15     /// <summary>
16     /// represent tile
17     /// </summary>
18     public struct Tile : IDisposable
19     {
20         public static readonly Tile Empty = new Tile();
21 
22         private GPoint fPos;
23         private PureImage[] fOverlays;
24         private long fOverlaysCount;
25         private int fZoom;
26 
27         public readonly bool NotEmpty;
28 
29 
30         public IEnumerable<PureImage> Overlays
31         {
32             get {
33                 for (long i = 0, size = Interlocked.Read(ref fOverlaysCount); i < size; i++) {
34                     yield return fOverlays[i];
35                 }
36             }
37         }
38 
39         internal bool HasAnyOverlays
40         {
41             get {
42                 return Interlocked.Read(ref fOverlaysCount) > 0;
43             }
44         }
45 
46         public int Zoom
47         {
48             get {
49                 return fZoom;
50             }
51         }
52 
53         public GPoint Pos
54         {
55             get {
56                 return fPos;
57             }
58         }
59 
60 
TileGKMap.Tile61         public Tile(int zoom, GPoint pos)
62         {
63             NotEmpty = true;
64             fZoom = zoom;
65             fPos = pos;
66             fOverlays = null;
67             fOverlaysCount = 0;
68         }
69 
AddOverlayGKMap.Tile70         internal void AddOverlay(PureImage i)
71         {
72             if (fOverlays == null) {
73                 fOverlays = new PureImage[4];
74             }
75             fOverlays[Interlocked.Increment(ref fOverlaysCount) - 1] = i;
76         }
77 
DisposeGKMap.Tile78         public void Dispose()
79         {
80             if (fOverlays != null) {
81                 for (long i = Interlocked.Read(ref fOverlaysCount) - 1; i >= 0; i--) {
82                     Interlocked.Decrement(ref fOverlaysCount);
83                     fOverlays[i].Dispose();
84                     fOverlays[i] = null;
85                 }
86                 fOverlays = null;
87             }
88         }
89 
operator ==GKMap.Tile90         public static bool operator ==(Tile m1, Tile m2)
91         {
92             return m1.fPos == m2.fPos && m1.fZoom == m2.fZoom;
93         }
94 
operator !=GKMap.Tile95         public static bool operator !=(Tile m1, Tile m2)
96         {
97             return !(m1 == m2);
98         }
99 
EqualsGKMap.Tile100         public override bool Equals(object obj)
101         {
102             if (!(obj is Tile))
103                 return false;
104 
105             Tile comp = (Tile)obj;
106             return comp.Zoom == Zoom && comp.Pos == Pos;
107         }
108 
GetHashCodeGKMap.Tile109         public override int GetHashCode()
110         {
111             return fZoom ^ fPos.GetHashCode();
112         }
113     }
114 }
115