]> git.saurik.com Git - wxWidgets.git/blame - samples/thread/test.cpp
Compilation fixes
[wxWidgets.git] / samples / thread / test.cpp
CommitLineData
82052aff
GL
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
3222fde2 9// Licence: wxWindows license
82052aff
GL
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__
3222fde2 21 #pragma hdrstop
82052aff
GL
22#endif
23
24#ifndef WX_PRECOMP
3222fde2 25 #include "wx/wx.h"
82052aff
GL
26#endif
27
3222fde2
VZ
28#if !wxUSE_THREADS
29 #error "This sample requires thread support!"
30#endif // wxUSE_THREADS
31
82052aff
GL
32#include "wx/thread.h"
33#include "wx/dynarray.h"
3222fde2 34#include "wx/time.h"
82052aff
GL
35
36// Define a new application type
37class MyApp: public wxApp
38{
a6b0bd49 39public:
82052aff
GL
40 bool OnInit(void);
41};
42
a6b0bd49 43WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
82052aff
GL
44
45// Define a new frame type
46class MyFrame: public wxFrame
47{
a6b0bd49
VZ
48public:
49 // ctor
82052aff 50 MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h);
3222fde2 51
a6b0bd49
VZ
52 // operations
53 void WriteText(const wxString& text) { m_txtctrl->WriteText(text); }
54
55 // callbacks
82052aff
GL
56 void OnQuit(wxCommandEvent& event);
57 void OnAbout(wxCommandEvent& event);
a6b0bd49 58
82052aff
GL
59 void OnStartThread(wxCommandEvent& event);
60 void OnStopThread(wxCommandEvent& event);
61 void OnPauseThread(wxCommandEvent& event);
a6b0bd49
VZ
62 void OnResumeThread(wxCommandEvent& event);
63
f3855ef0 64 void OnSize(wxSizeEvent &event);
3222fde2
VZ
65 void OnIdle(wxIdleEvent &event);
66 bool OnClose() { return TRUE; }
67
a6b0bd49
VZ
68public:
69 wxArrayThread m_threads;
82052aff 70
a6b0bd49
VZ
71private:
72 wxTextCtrl *m_txtctrl;
3222fde2 73
a6b0bd49 74 DECLARE_EVENT_TABLE()
82052aff
GL
75};
76
77class MyThread: public wxThread
78{
a6b0bd49 79public:
82052aff 80 MyThread(MyFrame *frame);
3222fde2
VZ
81
82 // thread execution starts here
83 virtual void *Entry();
84
85 // write something to the text control
86 void WriteText(const wxString& text);
a6b0bd49
VZ
87
88public:
89 size_t m_count;
82052aff
GL
90 MyFrame *m_frame;
91};
92
93MyThread::MyThread(MyFrame *frame)
a6b0bd49 94 : wxThread()
82052aff 95{
a6b0bd49
VZ
96 m_count = 0;
97 m_frame = frame;
82052aff
GL
98}
99
3222fde2
VZ
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
82052aff
GL
112void *MyThread::Entry()
113{
a6b0bd49 114 wxString text;
3222fde2 115
a6b0bd49 116 DeferDestroy(TRUE);
a6b0bd49 117
3222fde2
VZ
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);
a6b0bd49 129
a6b0bd49
VZ
130 wxSleep(1);
131 }
3222fde2
VZ
132
133 text.Printf("Thread 0x%x finished.\n", GetID());
134 WriteText(text);
135
a6b0bd49 136 return NULL;
82052aff
GL
137}
138
139// ID for the menu commands
3222fde2
VZ
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};
82052aff
GL
150
151BEGIN_EVENT_TABLE(MyFrame, wxFrame)
a6b0bd49
VZ
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)
3222fde2
VZ
160
161 EVT_IDLE(MyFrame::OnIdle)
82052aff
GL
162END_EVENT_TABLE()
163
164// Create a new application object
3222fde2 165IMPLEMENT_APP (MyApp)
82052aff
GL
166
167// `Main program' equivalent, creating windows and returning main app frame
3222fde2 168bool MyApp::OnInit()
82052aff 169{
a6b0bd49 170 // Create the main frame window
3222fde2
VZ
171 MyFrame *frame = new MyFrame((wxFrame *)NULL, "", 50, 50, 450, 340);
172
a6b0bd49
VZ
173 // Make a menubar
174 wxMenu *file_menu = new wxMenu;
3222fde2 175
a6b0bd49
VZ
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");
3222fde2 180
a6b0bd49 181 wxMenu *thread_menu = new wxMenu;
3222fde2
VZ
182 thread_menu->Append(TEST_START_THREAD, "&Start a new thread");
183 thread_menu->Append(TEST_STOP_THREAD, "S&top a running thread");
a6b0bd49 184 thread_menu->AppendSeparator();
3222fde2
VZ
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");
a6b0bd49 188 frame->SetMenuBar(menu_bar);
3222fde2 189
a6b0bd49
VZ
190 // Show the frame
191 frame->Show(TRUE);
3222fde2 192
a6b0bd49 193 SetTopWindow(frame);
3222fde2 194
a6b0bd49 195 return TRUE;
82052aff
GL
196}
197
198// My frame constructor
a6b0bd49
VZ
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))
82052aff 201{
a6b0bd49 202 wxPanel *panel = new wxPanel(this, -1, wxPoint(0, 0), wxSize(400, 200),
3222fde2
VZ
203 wxTAB_TRAVERSAL);
204
a6b0bd49
VZ
205 m_txtctrl = new wxTextCtrl(panel, -1, "", wxPoint(10,30), wxSize(390, 190),
206 wxTE_MULTILINE);
82052aff 207
a6b0bd49
VZ
208 (void)new wxStaticText(panel, -1, "Log window", wxPoint(10,10));
209}
82052aff 210
a6b0bd49
VZ
211void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) )
212{
213 MyThread *thread = new MyThread(this);
3222fde2 214
a6b0bd49 215 thread->Create();
3222fde2 216
a6b0bd49 217 m_threads.Add(thread);
82052aff
GL
218}
219
e3e65dac 220void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) )
82052aff 221{
a6b0bd49 222 int no_thrd = m_threads.Count()-1;
3222fde2 223
a6b0bd49
VZ
224 if (no_thrd < 0)
225 return;
3222fde2
VZ
226
227 delete m_threads[no_thrd];
a6b0bd49
VZ
228 m_threads.Remove(no_thrd);
229}
82052aff 230
a6b0bd49
VZ
231void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) )
232{
3222fde2 233 // resume first suspended thread
a6b0bd49
VZ
234 size_t n = 0;
235 while ( n < m_threads.Count() && m_threads[n]->IsPaused() )
236 n--;
3222fde2 237
a6b0bd49
VZ
238 if ( n < 0 )
239 wxLogError("No thread to pause!");
240 else
241 m_threads[n]->Resume();
82052aff
GL
242}
243
e3e65dac 244void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) )
f3855ef0 245{
3222fde2 246 // pause last running thread
a6b0bd49
VZ
247 int n = m_threads.Count() - 1;
248 while ( n >= 0 && !m_threads[n]->IsRunning() )
249 n--;
3222fde2 250
a6b0bd49
VZ
251 if ( n < 0 )
252 wxLogError("No thread to pause!");
253 else
254 m_threads[n]->Pause();
f3855ef0
RR
255}
256
3222fde2
VZ
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)
f3855ef0 275{
a6b0bd49 276 wxFrame::OnSize(event);
3222fde2 277
a6b0bd49 278 wxSize size( GetClientSize() );
3222fde2 279
a6b0bd49 280 m_txtctrl->SetSize( 10, 30, size.x-20, size.y-40 );
f3855ef0 281}
82052aff 282
e3e65dac 283void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) )
82052aff 284{
3222fde2
VZ
285 for ( size_t i = 0; i < m_threads.Count(); i++ )
286 delete m_threads[i];
287
a6b0bd49 288 Close(TRUE);
82052aff
GL
289}
290
e3e65dac 291void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event) )
82052aff 292{
3222fde2
VZ
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
a6b0bd49 298 dialog.ShowModal();
82052aff
GL
299}
300
301