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
9 // Copyright: (c) 2007 Anders Larsen
10 // License: 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();
189 wxLogMessage("Client disconnected from server");
191 wxGetApp().ExitMainLoop();
194 MyClient::~MyClient()
199 void MyClient::Notify()
201 // we shouldn't call wxIPC methods from here directly as we may be called
202 // from inside an IPC call when using TCP/IP as the sockets are used in
203 // non-blocking code and so can dispatch events, including the timer ones,
204 // while waiting for IO and so starting another IPC call would result in
205 // fatal reentrancies -- instead, just set a flag and perform the test
206 // indicated by it later from our idle event handler
207 MyClientTestFunc testfunc
= NULL
;
211 testfunc
= &MyClient::TestRequest
;
215 testfunc
= &MyClient::TestPoke
;
219 testfunc
= &MyClient::TestExecute
;
223 testfunc
= &MyClient::TestStartAdvise
;
227 testfunc
= &MyClient::TestStopAdvise
;
231 testfunc
= &MyClient::TestDisconnect
;
232 // We don't need the timer any more, we're going to exit soon.
237 // No need to wake up idle handling.
241 m_tests
.push_back(testfunc
);
246 void MyClient::StartNextTestIfNecessary()
248 while ( !m_tests
.empty() )
250 MyClientTestFunc testfunc
= m_tests
.front();
251 m_tests
.erase(m_tests
.begin());
256 void MyClient::TestRequest()
259 m_connection
->Request("Date");
260 m_connection
->Request("Date+len", &size
);
261 m_connection
->Request("bytes[3]", &size
, wxIPC_PRIVATE
);
264 void MyClient::TestPoke()
266 wxString s
= wxDateTime::Now().Format();
267 m_connection
->Poke("Date", s
);
268 s
= wxDateTime::Now().FormatTime() + " " + wxDateTime::Now().FormatDate();
269 m_connection
->Poke("Date", (const char *)s
.c_str(), s
.length() + 1);
271 bytes
[0] = '1'; bytes
[1] = '2'; bytes
[2] = '3';
272 m_connection
->Poke("bytes[3]", bytes
, 3, wxIPC_PRIVATE
);
275 void MyClient::TestExecute()
278 m_connection
->Execute(s
);
279 m_connection
->Execute((const char *)s
.c_str(), s
.length() + 1);
284 m_connection
->Execute(bytes
, WXSIZEOF(bytes
));
287 void MyClient::TestStartAdvise()
289 wxLogMessage("StartAdvise(\"something\")");
290 m_connection
->StartAdvise("something");
293 void MyClient::TestStopAdvise()
295 wxLogMessage("StopAdvise(\"something\")");
296 m_connection
->StopAdvise("something");
299 void MyClient::TestDisconnect()
304 // ----------------------------------------------------------------------------
306 // ----------------------------------------------------------------------------
308 bool MyConnection::OnAdvise(const wxString
& topic
, const wxString
& item
, const void *data
,
309 size_t size
, wxIPCFormat format
)
311 Log("OnAdvise", topic
, item
, data
, size
, format
);
315 bool MyConnection::OnDisconnect()
317 wxLogMessage("OnDisconnect()");
318 wxGetApp().ExitMainLoop();
322 bool MyConnection::DoExecute(const void *data
, size_t size
, wxIPCFormat format
)
324 Log("Execute", wxEmptyString
, wxEmptyString
, data
, size
, format
);
325 bool retval
= wxConnection::DoExecute(data
, size
, format
);
328 wxLogMessage("Execute failed!");
333 const void *MyConnection::Request(const wxString
& item
, size_t *size
, wxIPCFormat format
)
335 const void *data
= wxConnection::Request(item
, size
, format
);
336 Log("Request", wxEmptyString
, item
, data
, size
? *size
: wxNO_LEN
, format
);
340 bool MyConnection::DoPoke(const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
)
342 Log("Poke", wxEmptyString
, item
, data
, size
, format
);
343 return wxConnection::DoPoke(item
, data
, size
, format
);