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
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
///////////////////////////////////////////////////////////////////////////////
13
// ============================================================================
15
// ============================================================================
17
// ----------------------------------------------------------------------------
19
// ----------------------------------------------------------------------------
21
// For compilers that support precompilation, includes "wx.h".
22
#include "wx/wxprec.h"
32
// Settings common to both executables: determines whether
33
// we're using TCP/IP or real DDE.
36
#include "connection.h"
39
#include "wx/datetime.h"
40
#include "wx/vector.h"
44
// ----------------------------------------------------------------------------
46
// ----------------------------------------------------------------------------
48
class MyApp : public wxApp
51
MyApp() { Connect(wxEVT_IDLE, wxIdleEventHandler(MyApp::OnIdle)); }
53
virtual bool OnInit();
57
void OnIdle(wxIdleEvent& event);
62
class MyConnection : public MyConnectionBase
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();
72
class MyClient : public wxClient,
79
bool Connect(const wxString& sHost, const wxString& sService, const wxString& sTopic);
81
wxConnectionBase *OnMakeConnection();
82
bool IsConnected() { return m_connection != NULL; };
84
virtual void Notify();
86
void StartNextTestIfNecessary();
92
void TestStartAdvise();
93
void TestStopAdvise();
94
void TestDisconnect();
97
MyConnection *m_connection;
99
// the test functions to be executed by StartNextTestIfNecessary()
100
typedef void (MyClient::*MyClientTestFunc)();
101
wxVector<MyClientTestFunc> m_tests;
103
// number of seconds since the start of the test
107
// ============================================================================
109
// ============================================================================
111
IMPLEMENT_APP_CONSOLE(MyApp)
113
// ----------------------------------------------------------------------------
115
// ----------------------------------------------------------------------------
117
// The `main program' equivalent, creating the windows and returning the
121
if ( !wxApp::OnInit() )
124
// Create a new client
125
m_client = new MyClient;
126
bool retval = m_client->Connect("localhost", "4242", "IPC TEST");
128
wxLogMessage("Client host=\"localhost\" port=\"4242\" topic=\"IPC TEST\" %s",
129
retval ? "connected" : "failed to connect");
141
void MyApp::OnIdle(wxIdleEvent& event)
144
m_client->StartNextTestIfNecessary();
149
// ----------------------------------------------------------------------------
151
// ----------------------------------------------------------------------------
161
MyClient::Connect(const wxString& sHost,
162
const wxString& sService,
163
const wxString& sTopic)
165
// suppress the log messages from MakeConnection()
168
m_connection = (MyConnection *)MakeConnection(sHost, sService, sTopic);
177
wxConnectionBase *MyClient::OnMakeConnection()
179
return new MyConnection;
182
void MyClient::Disconnect()
186
m_connection->Disconnect();
187
wxDELETE(m_connection);
188
wxLogMessage("Client disconnected from server");
190
wxGetApp().ExitMainLoop();
193
MyClient::~MyClient()
198
void MyClient::Notify()
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;
210
testfunc = &MyClient::TestRequest;
214
testfunc = &MyClient::TestPoke;
218
testfunc = &MyClient::TestExecute;
222
testfunc = &MyClient::TestStartAdvise;
226
testfunc = &MyClient::TestStopAdvise;
230
testfunc = &MyClient::TestDisconnect;
231
// We don't need the timer any more, we're going to exit soon.
236
// No need to wake up idle handling.
240
m_tests.push_back(testfunc);
245
void MyClient::StartNextTestIfNecessary()
247
while ( !m_tests.empty() )
249
MyClientTestFunc testfunc = m_tests.front();
250
m_tests.erase(m_tests.begin());
255
void MyClient::TestRequest()
258
m_connection->Request("Date");
259
m_connection->Request("Date+len", &size);
260
m_connection->Request("bytes[3]", &size, wxIPC_PRIVATE);
263
void MyClient::TestPoke()
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);
270
bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
271
m_connection->Poke("bytes[3]", bytes, 3, wxIPC_PRIVATE);
274
void MyClient::TestExecute()
277
m_connection->Execute(s);
278
m_connection->Execute((const char *)s.c_str(), s.length() + 1);
283
m_connection->Execute(bytes, WXSIZEOF(bytes));
286
void MyClient::TestStartAdvise()
288
wxLogMessage("StartAdvise(\"something\")");
289
m_connection->StartAdvise("something");
292
void MyClient::TestStopAdvise()
294
wxLogMessage("StopAdvise(\"something\")");
295
m_connection->StopAdvise("something");
298
void MyClient::TestDisconnect()
303
// ----------------------------------------------------------------------------
305
// ----------------------------------------------------------------------------
307
bool MyConnection::OnAdvise(const wxString& topic, const wxString& item, const void *data,
308
size_t size, wxIPCFormat format)
310
Log("OnAdvise", topic, item, data, size, format);
314
bool MyConnection::OnDisconnect()
316
wxLogMessage("OnDisconnect()");
317
wxGetApp().ExitMainLoop();
321
bool MyConnection::DoExecute(const void *data, size_t size, wxIPCFormat format)
323
Log("Execute", wxEmptyString, wxEmptyString, data, size, format);
324
bool retval = wxConnection::DoExecute(data, size, format);
327
wxLogMessage("Execute failed!");
332
const void *MyConnection::Request(const wxString& item, size_t *size, wxIPCFormat format)
334
const void *data = wxConnection::Request(item, size, format);
335
Log("Request", wxEmptyString, item, data, size ? *size : wxNO_LEN, format);
339
bool MyConnection::DoPoke(const wxString& item, const void *data, size_t size, wxIPCFormat format)
341
Log("Poke", wxEmptyString, item, data, size, format);
342
return wxConnection::DoPoke(item, data, size, format);