001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011: #include "stdafx.h"
012: #include "UKPuzzleAdmin.h"
013:
014: CIUKPuzzleAdmin::CIUKPuzzleAdmin(long nFirstStoneOnPos_0,long nLastStoneOnPos_0,LPCTSTR szIniFileName,LPCTSTR szOutputFileName)
015: :m_PuzzleCore(nFirstStoneOnPos_0,nLastStoneOnPos_0,szIniFileName,szOutputFileName),
016: m_nCmd(0),
017: m_nProgressState(0)
018: {}
019:
020: CIUKPuzzleAdmin::~CIUKPuzzleAdmin()
021: {}
022:
023: DWORD CIUKPuzzleAdmin::GetSolutions()
024: {
025: return m_PuzzleCore.GetSolutions();
026: }
027: DWORD CIUKPuzzleAdmin::GetProgressState()
028: {
029: return m_nProgressState;
030: }
031:
032:
033: UKPUZ_STATE CIUKPuzzleAdmin::StartPuzzle(DWORD nTime2Wait)
034: {
035: if (m_nProgressState==enFinished)
036: return UKPUZ_UNKNOWNERROR;
037:
038: if (m_nProgressState!=enUndefined)
039: return UKPUZ_UNKNOWNERROR;
040: return CommandSetAndWait(enCmd_Start,nTime2Wait);
041: }
042:
043: UKPUZ_STATE CIUKPuzzleAdmin::PausePuzzle(DWORD nTime2Wait)
044: {
045: if (m_nProgressState==enFinished)
046: return UKPUZ_NOERROR;
047:
048: if (m_nProgressState!=enRunning)
049: return UKPUZ_UNKNOWNERROR;
050:
051: return CommandSetAndWait(enCmd_Pause,nTime2Wait);
052: }
053:
054: UKPUZ_STATE CIUKPuzzleAdmin::ContinuePuzzle(DWORD nTime2Wait)
055: {
056: if (m_nProgressState==enFinished)
057: return UKPUZ_NOERROR;
058:
059: if (m_nProgressState!=enPaused)
060: return UKPUZ_UNKNOWNERROR;
061:
062: return CommandSetAndWait(enCmd_Continue,nTime2Wait);
063: }
064:
065: UKPUZ_STATE CIUKPuzzleAdmin::StopPuzzle(DWORD nTime2Wait)
066: {
067: if (m_nProgressState!=enPaused && m_nProgressState!=enRunning && m_nProgressState!=enFinished)
068: return UKPUZ_UNKNOWNERROR;
069:
070: return CommandSetAndWait(enCmd_Stop,nTime2Wait);
071: }
072:
073:
074: UKPUZ_STATE CIUKPuzzleAdmin::CommandSetAndWait(DWORD nCmd,DWORD nTime2Wait)
075: {
076: DWORD nTimer=GetTickCount();
077: ASSERT(m_nCmd==0);
078: m_nCmd=nCmd;
079: while (m_nCmd!=0 && m_nProgressState!=enError && GetTickCount()-nTimer < nTime2Wait)
080: ;
081:
082: if (m_nProgressState==enError)
083: return UKPUZ_UNKNOWNERROR;
084:
085: if (m_nCmd==0)
086: return UKPUZ_NOERROR;
087:
088: m_nCmd=0;
089: return UKPUZ_TIMEERROR;
090: }
091:
092: void CIUKPuzzleAdmin::MainLoop()
093: {
094: CString strMsg;
095:
096: if (!m_PuzzleCore.Init())
097: {
098: m_nProgressState=enError;
099: m_nCmd=0;
100: return;
101: }
102:
103: while (m_nCmd!=enCmd_Stop && m_nProgressState!=enFinished)
104: {
105:
106: switch (m_nCmd)
107: {
108: case enCmd_Start:
109: m_nProgressState=enRunning;
110: m_nCmd=0;
111: PuzzleIsRunning();
112: break;
113: case enCmd_Pause:
114: m_nProgressState=enPaused;
115: m_nCmd=0;
116: PuzzleHasPaused();
117: while (m_nCmd!=enCmd_Continue && m_nCmd!=enCmd_Stop)
118: {
119: if (m_nCmd!=0 && m_nCmd!=enCmd_Continue && m_nCmd!=enCmd_Stop)
120: {
121: strMsg.Format("Command(%d) ignored",m_nCmd);
122: WriteLn(strMsg);
123: m_nCmd=0;
124: }
125: Sleep(100);
126: }
127: break;
128: case enCmd_Continue:
129: m_nProgressState=enRunning;
130: m_nCmd=0;
131: PuzzleIsRunning();
132: break;
133: case enCmd_Stop:
134:
135: break;
136: }
137: m_PuzzleCore.DoNextStep();
138:
139: if (m_nProgressState==enRunning && m_PuzzleCore.HasFinished())
140: m_nProgressState=enFinished;
141:
142: }
143:
144: if (m_nProgressState==enFinished)
145: PuzzleHasFinished();
146:
147: while (m_nCmd!=enCmd_Stop)
148: Sleep(100);
149:
150: PuzzleHasStopped();
151:
152: m_PuzzleCore.Deinit();
153:
154: m_nProgressState=0;
155: m_nCmd=0;
156: }
157:
158: void CIUKPuzzleAdmin::PuzzleIsRunning()
159: {
160: CString strMsg;
161: strMsg.Format("State info (%d)-> Puzzle is running",GetCurrentThreadId());
162: WriteLn(strMsg);
163: }
164: void CIUKPuzzleAdmin::PuzzleHasPaused()
165: {
166: CString strMsg;
167: strMsg.Format("State info (%d)-> Puzzle has paused",GetCurrentThreadId());
168: WriteLn(strMsg);
169: }
170: void CIUKPuzzleAdmin::PuzzleHasFinished()
171: {
172: CString strMsg;
173: strMsg.Format("State info (%d)-> Puzzle has finished",GetCurrentThreadId());
174: WriteLn(strMsg);
175: }
176: void CIUKPuzzleAdmin::PuzzleHasStopped()
177: {
178: CString strMsg;
179: strMsg.Format("State info (%d)-> Puzzle has stopped",GetCurrentThreadId());
180: WriteLn(strMsg);
181: }
182:
183:
184:
185: CUKPuzzleAdmin::CUKPuzzleAdmin(CWnd* pWnd,long nFirstStoneOnPos_0,long nLastStoneOnPos_0,LPCTSTR szIniFileName,LPCTSTR szOutputFileName)
186: :CIUKPuzzleAdmin(nFirstStoneOnPos_0,nLastStoneOnPos_0,szIniFileName,szOutputFileName),
187: m_pMessageReceiver(pWnd)
188: {
189: ASSERT(m_pMessageReceiver);
190: }
191:
192: CUKPuzzleAdmin::~CUKPuzzleAdmin()
193: {}
194:
195: UKPUZ_STATE CUKPuzzleAdmin::StartPuzzle(DWORD nTime2Wait)
196: {
197: if (AfxBeginThread(RunPuzzleAdmin,this))
198: return CIUKPuzzleAdmin::StartPuzzle(nTime2Wait);
199: else
200: return UKPUZ_UNKNOWNERROR;
201: }
202:
203: void CUKPuzzleAdmin::Write(LPCTSTR szOutText)
204: {
205: CString strText=szOutText;
206: ASSERT(m_pMessageReceiver);
207: m_pMessageReceiver->PostMessage(WM_UK_WRITE,0,(LPARAM)(LPVOID)strText.AllocSysString());
208: }
209:
210: void CUKPuzzleAdmin::WriteLn(LPCTSTR szOutText)
211: {
212: CString strText=CString(szOutText);
213: ASSERT(m_pMessageReceiver);
214: m_pMessageReceiver->PostMessage(WM_UK_WRITE,1,(LPARAM)(LPVOID)strText.AllocSysString());
215: }
216:
217: void CUKPuzzleAdmin::SolutionFound()
218: {
219: ASSERT(m_pMessageReceiver);
220: m_pMessageReceiver->PostMessage(WM_UK_NOTIFY,enUKPUZZLE_SOLUTIONFOUND);
221: }
222:
223: UINT __cdecl CUKPuzzleAdmin::RunPuzzleAdmin(LPVOID pVoid)
224: {
225: ((CUKPuzzleAdmin*)pVoid)->MainLoop();
226: return 0;
227: }
228:
229: void CUKPuzzleAdmin::PuzzleIsRunning()
230: {
231:
232:
233: SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
234:
235:
236:
237:
238:
239:
240:
241: CIUKPuzzleAdmin::PuzzleIsRunning();
242: }
243: void CUKPuzzleAdmin::PuzzleHasPaused()
244: {
245: SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
246: CIUKPuzzleAdmin::PuzzleHasPaused();
247: }
248: void CUKPuzzleAdmin::PuzzleHasFinished()
249: {
250: ASSERT(m_pMessageReceiver);
251: SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_BELOW_NORMAL);
252: CIUKPuzzleAdmin::PuzzleHasFinished();
253:
254: m_pMessageReceiver->PostMessage(WM_UK_NOTIFY,enUKPUZZLE_FINISHED);
255: }
256: void CUKPuzzleAdmin::PuzzleHasStopped()
257: {
258: SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
259: CIUKPuzzleAdmin::PuzzleHasStopped();
260: }
261: