]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/thread/test.cpp
Compilation fixes
[wxWidgets.git] / samples / thread / test.cpp
... / ...
CommitLineData
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
37class MyApp: public wxApp
38{
39public:
40 bool OnInit(void);
41};
42
43WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
44
45// Define a new frame type
46class MyFrame: public wxFrame
47{
48public:
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
68public:
69 wxArrayThread m_threads;
70
71private:
72 wxTextCtrl *m_txtctrl;
73
74 DECLARE_EVENT_TABLE()
75};
76
77class MyThread: public wxThread
78{
79public:
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
88public:
89 size_t m_count;
90 MyFrame *m_frame;
91};
92
93MyThread::MyThread(MyFrame *frame)
94 : wxThread()
95{
96 m_count = 0;
97 m_frame = frame;
98}
99
100void 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
112void *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
140enum
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
151BEGIN_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)
162END_EVENT_TABLE()
163
164// Create a new application object
165IMPLEMENT_APP (MyApp)
166
167// `Main program' equivalent, creating windows and returning main app frame
168bool 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
199MyFrame::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
211void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
212{
213 MyThread *thread = new MyThread(this);
214
215 thread->Create();
216
217 m_threads.Add(thread);
218}
219
220void 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
231void 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
244void 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
258void 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
274void 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
283void 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
291void 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