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