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