00001 //---------------------------------------------------------------------------- 00002 /** @file SgMarker.h 00003 Class SgMarker. */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef SG_MARKER_H 00007 #define SG_MARKER_H 00008 00009 #include "SgArray.h" 00010 #include "SgPoint.h" 00011 #include "SgPointSet.h" 00012 00013 //---------------------------------------------------------------------------- 00014 00015 /** Used to mark points on the board. 00016 Like SgPointSet but uses more memory and is faster at marking and clearing 00017 all marks. */ 00018 class SgMarker 00019 { 00020 public: 00021 SgMarker(); 00022 00023 void Include(SgPoint p); 00024 00025 bool Contains(SgPoint p) const; 00026 00027 /** Mark a point and return true if it was not already marked */ 00028 bool NewMark(SgPoint p); 00029 00030 void Clear(); 00031 00032 void GetPoints(SgPointSet* points) const; 00033 00034 private: 00035 void Init(); 00036 00037 /** Current marker number */ 00038 int m_thisMark; 00039 00040 /** Marked points */ 00041 SgArray<int,SG_MAXPOINT> m_mark; 00042 00043 #ifndef NDEBUG 00044 /** See ReserveBoardMarker */ 00045 bool m_markerInUse; 00046 00047 friend class SgReserveMarker; 00048 #endif 00049 00050 /** Not implemented. */ 00051 SgMarker(const SgMarker&); 00052 00053 /** Not implemented. */ 00054 SgMarker& operator=(const SgMarker&); 00055 }; 00056 00057 inline SgMarker::SgMarker() 00058 #ifndef NDEBUG 00059 : m_markerInUse(false) 00060 #endif 00061 { 00062 Init(); 00063 } 00064 00065 inline void SgMarker::Clear() 00066 { 00067 if (++m_thisMark == 0) 00068 Init(); 00069 } 00070 00071 inline bool SgMarker::Contains(SgPoint p) const 00072 { 00073 return m_mark[p] == m_thisMark; 00074 } 00075 00076 inline void SgMarker::GetPoints(SgPointSet* points) const 00077 { 00078 points->Clear(); 00079 for (SgPoint p = 0; p < SG_MAXPOINT; ++p) 00080 if (Contains(p)) 00081 points->Include(p); 00082 } 00083 00084 inline void SgMarker::Include(SgPoint p) 00085 { 00086 SG_ASSERT_BOARDRANGE(p); 00087 m_mark[p] = m_thisMark; 00088 } 00089 00090 inline void SgMarker::Init() 00091 { 00092 m_thisMark = 1; 00093 m_mark.Fill(0); 00094 } 00095 00096 inline bool SgMarker::NewMark(SgPoint p) 00097 { 00098 if (Contains(p)) 00099 return false; 00100 Include(p); 00101 return true; 00102 } 00103 00104 //---------------------------------------------------------------------------- 00105 00106 /** Declare a variable of this class on the stack to reserve a board marker. 00107 It asserts that nobody else is using the same marker at the same time. */ 00108 class SgReserveMarker 00109 { 00110 public: 00111 /** In debug build, assert that the marker is not already in use. */ 00112 SgReserveMarker(SgMarker& marker); 00113 00114 ~SgReserveMarker(); 00115 00116 private: 00117 #ifndef NDEBUG 00118 SgMarker& m_marker; 00119 #endif 00120 }; 00121 00122 #ifndef NDEBUG 00123 00124 inline SgReserveMarker::SgReserveMarker(SgMarker& marker) 00125 : m_marker(marker) 00126 { 00127 SG_ASSERT(! marker.m_markerInUse); 00128 m_marker.m_markerInUse = true; 00129 } 00130 00131 inline SgReserveMarker::~SgReserveMarker() 00132 { 00133 m_marker.m_markerInUse = false; 00134 } 00135 00136 #else 00137 00138 inline SgReserveMarker::SgReserveMarker(SgMarker& marker) 00139 { 00140 SG_UNUSED(marker); 00141 } 00142 00143 inline SgReserveMarker::~SgReserveMarker() 00144 { 00145 } 00146 00147 #endif 00148 00149 //---------------------------------------------------------------------------- 00150 00151 #endif // SG_MARKER_H