001: /////////////////////////////////////////////////////////////////////////////

002: //Projectname         : 

003: //Filename                : UKPuzzleAdmin.cpp 

004: //Classname                : CIUKPuzzleAdmin

005: //                                : CUKPuzzleAdmin

006: //Author                : Ulrich Kraemer [uk]

007: //Date                        : 25.03.2003

008: //Changes                : 

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: //Commands

033: UKPUZ_STATE CIUKPuzzleAdmin::StartPuzzle(DWORD nTime2Wait) //Start Thread or Programm

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: //Commands (for thread only)

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: //No realy synchronization used at the moment

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:                 ;//do nothing loop

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:                 //coul'd be changed

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:                                 //do not clear cmd

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:         #ifdef _DEBUG //*/
233:                 SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
234:         /*

235:         #else

236:                 //The time bonus is minimal, about 5 Percent on my system

237:                 SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);

238:         #endif

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: