1999-10-06 13:48:34 -04:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: samples/console/console.cpp
|
|
|
|
// Purpose: a sample console (as opposed to GUI) progam using wxWindows
|
|
|
|
// Author: Vadim Zeitlin
|
|
|
|
// Modified by:
|
|
|
|
// Created: 04.10.99
|
|
|
|
// RCS-ID: $Id$
|
|
|
|
// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
|
|
|
|
// Licence: wxWindows license
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
1999-10-22 05:24:15 -04:00
|
|
|
// ============================================================================
|
|
|
|
// declarations
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// headers
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
1999-10-06 13:48:34 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <wx/string.h>
|
1999-10-07 14:12:57 -04:00
|
|
|
#include <wx/file.h>
|
1999-10-06 13:48:34 -04:00
|
|
|
#include <wx/app.h>
|
1999-10-22 05:24:15 -04:00
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// conditional compilation
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// what to test?
|
1999-11-15 10:49:59 -05:00
|
|
|
|
|
|
|
//#define TEST_ARRAYS
|
1999-11-27 17:57:06 -05:00
|
|
|
//#define TEST_LOG
|
|
|
|
#define TEST_THREADS
|
1999-10-22 05:24:15 -04:00
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
// implementation
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// threads
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#ifdef TEST_THREADS
|
|
|
|
|
1999-10-07 14:12:57 -04:00
|
|
|
#include <wx/thread.h>
|
1999-10-06 13:48:34 -04:00
|
|
|
|
1999-10-07 14:12:57 -04:00
|
|
|
static size_t gs_counter = (size_t)-1;
|
|
|
|
static wxCriticalSection gs_critsect;
|
1999-11-27 17:57:06 -05:00
|
|
|
static wxCondition gs_cond;
|
1999-10-07 14:12:57 -04:00
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
class MyJoinableThread : public wxThread
|
1999-10-07 14:12:57 -04:00
|
|
|
{
|
|
|
|
public:
|
1999-11-27 17:57:06 -05:00
|
|
|
MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
|
|
|
|
{ m_n = n; Create(); }
|
1999-10-07 14:12:57 -04:00
|
|
|
|
|
|
|
// thread execution starts here
|
1999-11-27 17:57:06 -05:00
|
|
|
virtual ExitCode Entry();
|
1999-10-07 14:12:57 -04:00
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
private:
|
|
|
|
size_t m_n;
|
1999-10-07 14:12:57 -04:00
|
|
|
};
|
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
wxThread::ExitCode MyJoinableThread::Entry()
|
1999-10-07 14:12:57 -04:00
|
|
|
{
|
1999-11-27 17:57:06 -05:00
|
|
|
unsigned long res = 1;
|
|
|
|
for ( size_t n = 1; n < m_n; n++ )
|
|
|
|
{
|
|
|
|
res *= n;
|
|
|
|
|
|
|
|
// it's a loooong calculation :-)
|
|
|
|
Sleep(100);
|
|
|
|
}
|
1999-10-07 14:12:57 -04:00
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
return (ExitCode)res;
|
1999-10-07 14:12:57 -04:00
|
|
|
}
|
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
class MyDetachedThread : public wxThread
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MyDetachedThread(char ch) { m_ch = ch; Create(); }
|
|
|
|
|
|
|
|
// thread execution starts here
|
|
|
|
virtual ExitCode Entry();
|
|
|
|
|
|
|
|
// and stops here
|
|
|
|
virtual void OnExit();
|
|
|
|
|
|
|
|
private:
|
|
|
|
char m_ch;
|
|
|
|
};
|
|
|
|
|
|
|
|
wxThread::ExitCode MyDetachedThread::Entry()
|
1999-10-07 14:12:57 -04:00
|
|
|
{
|
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(gs_critsect);
|
|
|
|
if ( gs_counter == (size_t)-1 )
|
|
|
|
gs_counter = 1;
|
|
|
|
else
|
|
|
|
gs_counter++;
|
|
|
|
}
|
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
static const size_t nIter = 10;
|
|
|
|
for ( size_t n = 0; n < nIter; n++ )
|
1999-10-07 14:12:57 -04:00
|
|
|
{
|
|
|
|
if ( TestDestroy() )
|
|
|
|
break;
|
|
|
|
|
|
|
|
putchar(m_ch);
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
wxThread::Sleep(100);
|
|
|
|
}
|
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
return 0;
|
1999-10-07 14:12:57 -04:00
|
|
|
}
|
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
void MyDetachedThread::OnExit()
|
1999-10-07 14:12:57 -04:00
|
|
|
{
|
|
|
|
wxCriticalSectionLocker lock(gs_critsect);
|
1999-11-27 17:57:06 -05:00
|
|
|
if ( !--gs_counter )
|
|
|
|
gs_cond.Signal();
|
1999-10-07 14:12:57 -04:00
|
|
|
}
|
|
|
|
|
1999-10-22 05:24:15 -04:00
|
|
|
#endif // TEST_THREADS
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// arrays
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#ifdef TEST_ARRAYS
|
|
|
|
|
|
|
|
void PrintArray(const char* name, const wxArrayString& array)
|
|
|
|
{
|
|
|
|
printf("Dump of the array '%s'\n", name);
|
|
|
|
|
|
|
|
size_t nCount = array.GetCount();
|
|
|
|
for ( size_t n = 0; n < nCount; n++ )
|
|
|
|
{
|
|
|
|
printf("\t%s[%u] = '%s'\n", name, n, array[n].c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // TEST_ARRAYS
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// entry point
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
1999-10-07 14:12:57 -04:00
|
|
|
int main(int argc, char **argv)
|
1999-10-06 13:48:34 -04:00
|
|
|
{
|
|
|
|
if ( !wxInitialize() )
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Failed to initialize the wxWindows library, aborting.");
|
|
|
|
}
|
|
|
|
|
1999-10-22 05:24:15 -04:00
|
|
|
#ifdef TEST_ARRAYS
|
|
|
|
wxArrayString a1;
|
|
|
|
a1.Add("tiger");
|
|
|
|
a1.Add("cat");
|
|
|
|
a1.Add("lion");
|
|
|
|
a1.Add("dog");
|
|
|
|
a1.Add("human");
|
|
|
|
a1.Add("ape");
|
|
|
|
|
|
|
|
puts("*** Initially:");
|
|
|
|
|
|
|
|
PrintArray("a1", a1);
|
|
|
|
|
|
|
|
wxArrayString a2(a1);
|
|
|
|
PrintArray("a2", a2);
|
|
|
|
|
|
|
|
wxSortedArrayString a3(a1);
|
|
|
|
PrintArray("a3", a3);
|
|
|
|
|
|
|
|
puts("*** After deleting a string from a1");
|
|
|
|
a1.Remove(2);
|
|
|
|
|
|
|
|
PrintArray("a1", a1);
|
|
|
|
PrintArray("a2", a2);
|
|
|
|
PrintArray("a3", a3);
|
|
|
|
|
|
|
|
puts("*** After reassigning a1 to a2 and a3");
|
|
|
|
a3 = a2 = a1;
|
|
|
|
PrintArray("a2", a2);
|
|
|
|
PrintArray("a3", a3);
|
|
|
|
#endif // TEST_ARRAYS
|
|
|
|
|
1999-11-15 10:49:59 -05:00
|
|
|
#ifdef TEST_LOG
|
|
|
|
wxString s;
|
|
|
|
for ( size_t n = 0; n < 8000; n++ )
|
|
|
|
{
|
|
|
|
s << (char)('A' + (n % 26));
|
|
|
|
}
|
|
|
|
|
|
|
|
wxString msg;
|
|
|
|
msg.Printf("A very very long message: '%s', the end!\n", s.c_str());
|
|
|
|
|
|
|
|
// this one shouldn't be truncated
|
|
|
|
printf(msg);
|
|
|
|
|
|
|
|
// but this one will because log functions use fixed size buffer
|
1999-11-27 17:57:06 -05:00
|
|
|
// (note that it doesn't need '\n' at the end neither - will be added
|
|
|
|
// by wxLog anyhow)
|
|
|
|
wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
|
1999-11-15 10:49:59 -05:00
|
|
|
#endif // TEST_LOG
|
|
|
|
|
1999-10-22 05:24:15 -04:00
|
|
|
#ifdef TEST_THREADS
|
1999-11-27 17:57:06 -05:00
|
|
|
puts("Testing detached threads...");
|
|
|
|
|
1999-10-07 14:12:57 -04:00
|
|
|
static const size_t nThreads = 3;
|
1999-11-27 17:57:06 -05:00
|
|
|
MyDetachedThread *threads[nThreads];
|
1999-10-07 14:12:57 -04:00
|
|
|
size_t n;
|
|
|
|
for ( n = 0; n < nThreads; n++ )
|
|
|
|
{
|
1999-11-27 17:57:06 -05:00
|
|
|
threads[n] = new MyDetachedThread('A' + n);
|
1999-10-07 14:12:57 -04:00
|
|
|
}
|
|
|
|
|
1999-11-27 17:57:06 -05:00
|
|
|
threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
|
|
|
|
threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
|
1999-10-06 13:48:34 -04:00
|
|
|
|
1999-10-07 14:12:57 -04:00
|
|
|
for ( n = 0; n < nThreads; n++ )
|
|
|
|
{
|
1999-11-27 17:57:06 -05:00
|
|
|
threads[n]->Run();
|
1999-10-07 14:12:57 -04:00
|
|
|
}
|
1999-11-27 17:57:06 -05:00
|
|
|
|
|
|
|
// wait until all threads terminate
|
|
|
|
wxMutex mutex;
|
|
|
|
mutex.Lock();
|
|
|
|
gs_cond.Wait(mutex);
|
|
|
|
mutex.Unlock();
|
|
|
|
|
|
|
|
puts("\n\nTesting a joinable thread used for a loooong calculation...");
|
|
|
|
|
|
|
|
// calc 10! in the background
|
|
|
|
MyJoinableThread thread(10);
|
|
|
|
thread.Run();
|
|
|
|
|
|
|
|
printf("\nThread terminated with exit code %lu.\n",
|
|
|
|
(unsigned long)thread.Wait());
|
1999-10-22 05:24:15 -04:00
|
|
|
#endif // TEST_THREADS
|
1999-10-06 13:48:34 -04:00
|
|
|
|
|
|
|
wxUninitialize();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|