]> git.saurik.com Git - wxWidgets.git/blob - samples/thread/test.cpp
Compilation fixes
[wxWidgets.git] / samples / thread / test.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: test.cpp
3 // Purpose: wxWindows thread sample
4 // Author: Julian Smart(minimal)/Guilhem Lavaux(thread test)
5 // Modified by:
6 // Created: 06/16/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart, Markus Holzem, Guilhem Lavaux
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "test.cpp"
14 #pragma interface "test.cpp"
15 #endif
16
17 // For compilers that support precompilation, includes "wx/wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #ifndef WX_PRECOMP
25 #include "wx/wx.h"
26 #endif
27
28 #if !wxUSE_THREADS
29 #error "This sample requires thread support!"
30 #endif // wxUSE_THREADS
31
32 #include "wx/thread.h"
33 #include "wx/dynarray.h"
34 #include "wx/time.h"
35
36 // Define a new application type
37 class MyApp: public wxApp
38 {
39 public:
40 bool OnInit(void);
41 };
42
43 WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
44
45 // Define a new frame type
46 class MyFrame: public wxFrame
47 {
48 public:
49 // ctor
50 MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
51
52 // operations
53 void WriteText(const wxString& text) { m_txtctrl->WriteText(text); }
54
55 // callbacks
56 void OnQuit(wxCommandEvent& event);
57 void OnAbout(wxCommandEvent& event);
58
59 void OnStartThread(wxCommandEvent& event);
60 void OnStopThread(wxCommandEvent& event);
61 void OnPauseThread(wxCommandEvent& event);
62 void OnResumeThread(wxCommandEvent& event);
63
64 void OnSize(wxSizeEvent &event);
65 void OnIdle(wxIdleEvent &event);
66 bool OnClose() { return TRUE; }
67
68 public:
69 wxArrayThread m_threads;
70
71 private:
72 wxTextCtrl *m_txtctrl;
73
74 DECLARE_EVENT_TABLE()
75 };
76
77 class MyThread: public wxThread
78 {
79 public:
80 MyThread(MyFrame *frame);
81
82 // thread execution starts here
83 virtual void *Entry();
84
85 // write something to the text control
86 void WriteText(const wxString& text);
87
88 public:
89 size_t m_count;
90 MyFrame *m_frame;
91 };
92
93 MyThread::MyThread(MyFrame *frame)
94 : wxThread()
95 {
96 m_count = 0;
97 m_frame = frame;
98 }
99
100 void MyThread::WriteText(const wxString& text)
101 {
102 wxString msg;
103 msg << wxTime().FormatTime() << ": " << text;
104
105 // before doing any GUI calls we must ensure that this thread is the only
106 // one doing it!
107 wxMutexGuiEnter();
108 m_frame->WriteText(msg);
109 wxMutexGuiLeave();
110 }
111
112 void *MyThread::Entry()
113 {
114 wxString text;
115
116 DeferDestroy(TRUE);
117
118 text.Printf("Thread 0x%x started.\n", GetID());
119 WriteText(text);
120
121 for ( m_count = 0; m_count < 20; m_count++ )
122 {
123 // check if we were asked to exit
124 if ( TestDestroy() )
125 break;
126
127 text.Printf("[%u] Thread 0x%x here.\n", m_count, GetID());
128 WriteText(text);
129
130 wxSleep(1);
131 }
132
133 text.Printf("Thread 0x%x finished.\n", GetID());
134 WriteText(text);
135
136 return NULL;
137 }
138
139 // ID for the menu commands
140 enum
141 {
142 TEST_QUIT = 1,
143 TEST_TEXT = 101,
144 TEST_ABOUT = 102,
145 TEST_START_THREAD = 103,
146 TEST_STOP_THREAD = 104,
147 TEST_PAUSE_THREAD = 105,
148 TEST_RESUME_THREAD = 106
149 };
150
151 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
152 EVT_MENU(TEST_QUIT, MyFrame::OnQuit)
153 EVT_MENU(TEST_ABOUT, MyFrame::OnAbout)
154 EVT_MENU(TEST_START_THREAD, MyFrame::OnStartThread)
155 EVT_MENU(TEST_STOP_THREAD, MyFrame::OnStopThread)
156 EVT_MENU(TEST_PAUSE_THREAD, MyFrame::OnPauseThread)
157 EVT_MENU(TEST_RESUME_THREAD, MyFrame::OnResumeThread)
158
159 EVT_SIZE(MyFrame::OnSize)
160
161 EVT_IDLE(MyFrame::OnIdle)
162 END_EVENT_TABLE()
163
164 // Create a new application object
165 IMPLEMENT_APP (MyApp)
166
167 // `Main program' equivalent, creating windows and returning main app frame
168 bool MyApp::OnInit()
169 {
170 // Create the main frame window
171 MyFrame *frame = new MyFrame((wxFrame *)NULL, "", 50, 50, 450, 340);
172
173 // Make a menubar
174 wxMenu *file_menu = new wxMenu;
175
176 file_menu->Append(TEST_ABOUT, "&About");
177 file_menu->Append(TEST_QUIT, "E&xit");
178 wxMenuBar *menu_bar = new wxMenuBar;
179 menu_bar->Append(file_menu, "&File");
180
181 wxMenu *thread_menu = new wxMenu;
182 thread_menu->Append(TEST_START_THREAD, "&Start a new thread");
183 thread_menu->Append(TEST_STOP_THREAD, "S&top a running thread");
184 thread_menu->AppendSeparator();
185 thread_menu->Append(TEST_PAUSE_THREAD, "&Pause a running thread");
186 thread_menu->Append(TEST_RESUME_THREAD, "&Resume suspended thread");
187 menu_bar->Append(thread_menu, "&Thread");
188 frame->SetMenuBar(menu_bar);
189
190 // Show the frame
191 frame->Show(TRUE);
192
193 SetTopWindow(frame);
194
195 return TRUE;
196 }
197
198 // My frame constructor
199 MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h)
200 : wxFrame(frame, -1, title, wxPoint(x, y), wxSize(w, h))
201 {
202 wxPanel *panel = new wxPanel(this, -1, wxPoint(0, 0), wxSize(400, 200),
203 wxTAB_TRAVERSAL);
204
205 m_txtctrl = new wxTextCtrl(panel, -1, "", wxPoint(10,30), wxSize(390, 190),
206 wxTE_MULTILINE);
207
208 (void)new wxStaticText(panel, -1, "Log window", wxPoint(10,10));
209 }
210
211 void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
212 {
213 MyThread *thread = new MyThread(this);
214
215 thread->Create();
216
217 m_threads.Add(thread);
218 }
219
220 void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) )
221 {
222 int no_thrd = m_threads.Count()-1;
223
224 if (no_thrd < 0)
225 return;
226
227 delete m_threads[no_thrd];
228 m_threads.Remove(no_thrd);
229 }
230
231 void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) )
232 {
233 // resume first suspended thread
234 size_t n = 0;
235 while ( n < m_threads.Count() && m_threads[n]->IsPaused() )
236 n--;
237
238 if ( n < 0 )
239 wxLogError("No thread to pause!");
240 else
241 m_threads[n]->Resume();
242 }
243
244 void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) )
245 {
246 // pause last running thread
247 int n = m_threads.Count() - 1;
248 while ( n >= 0 && !m_threads[n]->IsRunning() )
249 n--;
250
251 if ( n < 0 )
252 wxLogError("No thread to pause!");
253 else
254 m_threads[n]->Pause();
255 }
256
257 // set the frame title indicating the current number of threads
258 void MyFrame::OnIdle(wxIdleEvent &event)
259 {
260 size_t nRunning = 0,
261 nCount = m_threads.Count();
262 for ( size_t n = 0; n < nCount; n++ )
263 {
264 if ( m_threads[n]->IsRunning() )
265 nRunning++;
266 }
267
268 wxString title;
269 title.Printf("wxWindows thread sample (%u threads, %u running).",
270 nCount, nRunning);
271 SetTitle(title);
272 }
273
274 void MyFrame::OnSize(wxSizeEvent& event)
275 {
276 wxFrame::OnSize(event);
277
278 wxSize size( GetClientSize() );
279
280 m_txtctrl->SetSize( 10, 30, size.x-20, size.y-40 );
281 }
282
283 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
284 {
285 for ( size_t i = 0; i < m_threads.Count(); i++ )
286 delete m_threads[i];
287
288 Close(TRUE);
289 }
290
291 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
292 {
293 wxMessageDialog dialog(this, "wxThread sample (based on minimal)\n"
294 "Julian Smart and Guilhem Lavaux",
295 "About wxThread sample",
296 wxOK | wxICON_INFORMATION);
297
298 dialog.ShowModal();
299 }
300
301