~brian-sidebotham/wxwidgets-cmake/wxpython-2.9.4

« back to all changes in this revision

Viewing changes to samples/ipc/baseclient.cpp

  • Committer: Brian Sidebotham
  • Date: 2013-08-03 14:30:08 UTC
  • Revision ID: brian.sidebotham@gmail.com-20130803143008-c7806tkych1tp6fc
Initial import into Bazaar

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        samples/ipc/baseclient.cpp
 
3
// Purpose:     IPC sample: console client
 
4
// Author:      Anders Larsen
 
5
//              Most of the code was stolen from: samples/ipc/client.cpp
 
6
//              (c) Julian Smart, Jurgen Doornik
 
7
// Created:     2007-11-08
 
8
// RCS-ID:      $Id: baseclient.cpp 64940 2010-07-13 13:29:13Z VZ $
 
9
// Copyright:   (c) 2007 Anders Larsen
 
10
// Licence:     wxWindows licence
 
11
///////////////////////////////////////////////////////////////////////////////
 
12
 
 
13
// ============================================================================
 
14
// declarations
 
15
// ============================================================================
 
16
 
 
17
// ----------------------------------------------------------------------------
 
18
// headers
 
19
// ----------------------------------------------------------------------------
 
20
 
 
21
// For compilers that support precompilation, includes "wx.h".
 
22
#include "wx/wxprec.h"
 
23
 
 
24
#ifdef __BORLANDC__
 
25
    #pragma hdrstop
 
26
#endif
 
27
 
 
28
#ifndef WX_PRECOMP
 
29
    #include "wx/wx.h"
 
30
#endif
 
31
 
 
32
// Settings common to both executables: determines whether
 
33
// we're using TCP/IP or real DDE.
 
34
#include "ipcsetup.h"
 
35
 
 
36
#include "connection.h"
 
37
 
 
38
#include "wx/timer.h"
 
39
#include "wx/datetime.h"
 
40
#include "wx/vector.h"
 
41
 
 
42
class MyClient;
 
43
 
 
44
// ----------------------------------------------------------------------------
 
45
// classes
 
46
// ----------------------------------------------------------------------------
 
47
 
 
48
class MyApp : public wxApp
 
49
{
 
50
public:
 
51
    MyApp() { Connect(wxEVT_IDLE, wxIdleEventHandler(MyApp::OnIdle)); }
 
52
 
 
53
    virtual bool OnInit();
 
54
    virtual int OnExit();
 
55
 
 
56
private:
 
57
    void OnIdle(wxIdleEvent& event);
 
58
 
 
59
    MyClient *m_client;
 
60
};
 
61
 
 
62
class MyConnection : public MyConnectionBase
 
63
{
 
64
public:
 
65
    virtual bool DoExecute(const void *data, size_t size, wxIPCFormat format);
 
66
    virtual const void *Request(const wxString& item, size_t *size = NULL, wxIPCFormat format = wxIPC_TEXT);
 
67
    virtual bool DoPoke(const wxString& item, const void* data, size_t size, wxIPCFormat format);
 
68
    virtual bool OnAdvise(const wxString& topic, const wxString& item, const void *data, size_t size, wxIPCFormat format);
 
69
    virtual bool OnDisconnect();
 
70
};
 
71
 
 
72
class MyClient : public wxClient,
 
73
                 private wxTimer
 
74
{
 
75
public:
 
76
    MyClient();
 
77
    virtual ~MyClient();
 
78
 
 
79
    bool Connect(const wxString& sHost, const wxString& sService, const wxString& sTopic);
 
80
    void Disconnect();
 
81
    wxConnectionBase *OnMakeConnection();
 
82
    bool IsConnected() { return m_connection != NULL; };
 
83
 
 
84
    virtual void Notify();
 
85
 
 
86
    void StartNextTestIfNecessary();
 
87
 
 
88
private:
 
89
    void TestRequest();
 
90
    void TestPoke();
 
91
    void TestExecute();
 
92
    void TestStartAdvise();
 
93
    void TestStopAdvise();
 
94
    void TestDisconnect();
 
95
 
 
96
 
 
97
    MyConnection *m_connection;
 
98
 
 
99
    // the test functions to be executed by StartNextTestIfNecessary()
 
100
    typedef void (MyClient::*MyClientTestFunc)();
 
101
    wxVector<MyClientTestFunc> m_tests;
 
102
 
 
103
    // number of seconds since the start of the test
 
104
    int m_step;
 
105
};
 
106
 
 
107
// ============================================================================
 
108
// implementation
 
109
// ============================================================================
 
110
 
 
111
IMPLEMENT_APP_CONSOLE(MyApp)
 
112
 
 
113
// ----------------------------------------------------------------------------
 
114
// MyApp
 
115
// ----------------------------------------------------------------------------
 
116
 
 
117
// The `main program' equivalent, creating the windows and returning the
 
118
// main frame
 
119
bool MyApp::OnInit()
 
120
{
 
121
    if ( !wxApp::OnInit() )
 
122
        return false;
 
123
 
 
124
    // Create a new client
 
125
    m_client = new MyClient;
 
126
    bool retval = m_client->Connect("localhost", "4242", "IPC TEST");
 
127
 
 
128
    wxLogMessage("Client host=\"localhost\" port=\"4242\" topic=\"IPC TEST\" %s",
 
129
                 retval ? "connected" : "failed to connect");
 
130
 
 
131
    return retval;
 
132
}
 
133
 
 
134
int MyApp::OnExit()
 
135
{
 
136
    delete m_client;
 
137
 
 
138
    return 0;
 
139
}
 
140
 
 
141
void MyApp::OnIdle(wxIdleEvent& event)
 
142
{
 
143
    if ( m_client )
 
144
        m_client->StartNextTestIfNecessary();
 
145
 
 
146
    event.Skip();
 
147
}
 
148
 
 
149
// ----------------------------------------------------------------------------
 
150
// MyClient
 
151
// ----------------------------------------------------------------------------
 
152
 
 
153
MyClient::MyClient()
 
154
    : wxClient()
 
155
{
 
156
    m_connection = NULL;
 
157
    m_step = 0;
 
158
}
 
159
 
 
160
bool
 
161
MyClient::Connect(const wxString& sHost,
 
162
                  const wxString& sService,
 
163
                  const wxString& sTopic)
 
164
{
 
165
    // suppress the log messages from MakeConnection()
 
166
    wxLogNull nolog;
 
167
 
 
168
    m_connection = (MyConnection *)MakeConnection(sHost, sService, sTopic);
 
169
    if ( !m_connection )
 
170
        return false;
 
171
 
 
172
    Start(1000);
 
173
 
 
174
    return true;
 
175
}
 
176
 
 
177
wxConnectionBase *MyClient::OnMakeConnection()
 
178
{
 
179
    return new MyConnection;
 
180
}
 
181
 
 
182
void MyClient::Disconnect()
 
183
{
 
184
    if (m_connection)
 
185
    {
 
186
        m_connection->Disconnect();
 
187
        wxDELETE(m_connection);
 
188
        wxLogMessage("Client disconnected from server");
 
189
    }
 
190
    wxGetApp().ExitMainLoop();
 
191
}
 
192
 
 
193
MyClient::~MyClient()
 
194
{
 
195
    Disconnect();
 
196
}
 
197
 
 
198
void MyClient::Notify()
 
199
{
 
200
    // we shouldn't call wxIPC methods from here directly as we may be called
 
201
    // from inside an IPC call when using TCP/IP as the sockets are used in
 
202
    // non-blocking code and so can dispatch events, including the timer ones,
 
203
    // while waiting for IO and so starting another IPC call would result in
 
204
    // fatal reentrancies -- instead, just set a flag and perform the test
 
205
    // indicated by it later from our idle event handler
 
206
    MyClientTestFunc testfunc = NULL;
 
207
    switch ( m_step++ )
 
208
    {
 
209
        case 0:
 
210
            testfunc = &MyClient::TestRequest;
 
211
            break;
 
212
 
 
213
        case 1:
 
214
            testfunc = &MyClient::TestPoke;
 
215
            break;
 
216
 
 
217
        case 2:
 
218
            testfunc = &MyClient::TestExecute;
 
219
            break;
 
220
 
 
221
        case 3:
 
222
            testfunc = &MyClient::TestStartAdvise;
 
223
            break;
 
224
 
 
225
        case 10:
 
226
            testfunc = &MyClient::TestStopAdvise;
 
227
            break;
 
228
 
 
229
        case 15:
 
230
            testfunc = &MyClient::TestDisconnect;
 
231
            // We don't need the timer any more, we're going to exit soon.
 
232
            Stop();
 
233
            break;
 
234
 
 
235
        default:
 
236
            // No need to wake up idle handling.
 
237
            return;
 
238
    }
 
239
 
 
240
    m_tests.push_back(testfunc);
 
241
 
 
242
    wxWakeUpIdle();
 
243
}
 
244
 
 
245
void MyClient::StartNextTestIfNecessary()
 
246
{
 
247
    while ( !m_tests.empty() )
 
248
    {
 
249
        MyClientTestFunc testfunc = m_tests.front();
 
250
        m_tests.erase(m_tests.begin());
 
251
        (this->*testfunc)();
 
252
    }
 
253
}
 
254
 
 
255
void MyClient::TestRequest()
 
256
{
 
257
    size_t size;
 
258
    m_connection->Request("Date");
 
259
    m_connection->Request("Date+len", &size);
 
260
    m_connection->Request("bytes[3]", &size, wxIPC_PRIVATE);
 
261
}
 
262
 
 
263
void MyClient::TestPoke()
 
264
{
 
265
    wxString s = wxDateTime::Now().Format();
 
266
    m_connection->Poke("Date", s);
 
267
    s = wxDateTime::Now().FormatTime() + " " + wxDateTime::Now().FormatDate();
 
268
    m_connection->Poke("Date", (const char *)s.c_str(), s.length() + 1);
 
269
    char bytes[3];
 
270
    bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
 
271
    m_connection->Poke("bytes[3]", bytes, 3, wxIPC_PRIVATE);
 
272
}
 
273
 
 
274
void MyClient::TestExecute()
 
275
{
 
276
    wxString s = "Date";
 
277
    m_connection->Execute(s);
 
278
    m_connection->Execute((const char *)s.c_str(), s.length() + 1);
 
279
    char bytes[3];
 
280
    bytes[0] = '1';
 
281
    bytes[1] = '2';
 
282
    bytes[2] = '3';
 
283
    m_connection->Execute(bytes, WXSIZEOF(bytes));
 
284
}
 
285
 
 
286
void MyClient::TestStartAdvise()
 
287
{
 
288
    wxLogMessage("StartAdvise(\"something\")");
 
289
    m_connection->StartAdvise("something");
 
290
}
 
291
 
 
292
void MyClient::TestStopAdvise()
 
293
{
 
294
    wxLogMessage("StopAdvise(\"something\")");
 
295
    m_connection->StopAdvise("something");
 
296
}
 
297
 
 
298
void MyClient::TestDisconnect()
 
299
{
 
300
    Disconnect();
 
301
}
 
302
 
 
303
// ----------------------------------------------------------------------------
 
304
// MyConnection
 
305
// ----------------------------------------------------------------------------
 
306
 
 
307
bool MyConnection::OnAdvise(const wxString& topic, const wxString& item, const void *data,
 
308
    size_t size, wxIPCFormat format)
 
309
{
 
310
    Log("OnAdvise", topic, item, data, size, format);
 
311
    return true;
 
312
}
 
313
 
 
314
bool MyConnection::OnDisconnect()
 
315
{
 
316
    wxLogMessage("OnDisconnect()");
 
317
    wxGetApp().ExitMainLoop();
 
318
    return true;
 
319
}
 
320
 
 
321
bool MyConnection::DoExecute(const void *data, size_t size, wxIPCFormat format)
 
322
{
 
323
    Log("Execute", wxEmptyString, wxEmptyString, data, size, format);
 
324
    bool retval = wxConnection::DoExecute(data, size, format);
 
325
    if (!retval)
 
326
    {
 
327
        wxLogMessage("Execute failed!");
 
328
    }
 
329
    return retval;
 
330
}
 
331
 
 
332
const void *MyConnection::Request(const wxString& item, size_t *size, wxIPCFormat format)
 
333
{
 
334
    const void *data =  wxConnection::Request(item, size, format);
 
335
    Log("Request", wxEmptyString, item, data, size ? *size : wxNO_LEN, format);
 
336
    return data;
 
337
}
 
338
 
 
339
bool MyConnection::DoPoke(const wxString& item, const void *data, size_t size, wxIPCFormat format)
 
340
{
 
341
    Log("Poke", wxEmptyString, item, data, size, format);
 
342
    return wxConnection::DoPoke(item, data, size, format);
 
343
}