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
;
236 m_tests
.push_back(testfunc
);
241 void MyClient::StartNextTestIfNecessary()
243 if ( !m_tests
.empty() )
245 MyClientTestFunc testfunc
= m_tests
.front();
246 m_tests
.erase(m_tests
.begin());
251 void MyClient::TestRequest()
254 m_connection
->Request("Date");
255 m_connection
->Request("Date+len", &size
);
256 m_connection
->Request("bytes[3]", &size
, wxIPC_PRIVATE
);
259 void MyClient::TestPoke()
261 wxString s
= wxDateTime::Now().Format();
262 m_connection
->Poke("Date", s
);
263 s
= wxDateTime::Now().FormatTime() + " " + wxDateTime::Now().FormatDate();
264 m_connection
->Poke("Date", (const char *)s
.c_str(), s
.length() + 1);
266 bytes
[0] = '1'; bytes
[1] = '2'; bytes
[2] = '3';
267 m_connection
->Poke("bytes[3]", bytes
, 3, wxIPC_PRIVATE
);
270 void MyClient::TestExecute()
273 m_connection
->Execute(s
);
274 m_connection
->Execute((const char *)s
.c_str(), s
.length() + 1);
279 m_connection
->Execute(bytes
, WXSIZEOF(bytes
));
282 void MyClient::TestStartAdvise()
284 wxLogMessage("StartAdvise(\"something\")");
285 m_connection
->StartAdvise("something");
288 void MyClient::TestStopAdvise()
290 wxLogMessage("StopAdvise(\"something\")");
291 m_connection
->StopAdvise("something");
294 void MyClient::TestDisconnect()
299 // ----------------------------------------------------------------------------
301 // ----------------------------------------------------------------------------
303 bool MyConnection::OnAdvise(const wxString
& topic
, const wxString
& item
, const void *data
,
304 size_t size
, wxIPCFormat format
)
306 Log("OnAdvise", topic
, item
, data
, size
, format
);
310 bool MyConnection::OnDisconnect()
312 wxLogMessage("OnDisconnect()");
313 wxGetApp().ExitMainLoop();
317 bool MyConnection::DoExecute(const void *data
, size_t size
, wxIPCFormat format
)
319 Log("Execute", wxEmptyString
, wxEmptyString
, data
, size
, format
);
320 bool retval
= wxConnection::DoExecute(data
, size
, format
);
323 wxLogMessage("Execute failed!");
328 const void *MyConnection::Request(const wxString
& item
, size_t *size
, wxIPCFormat format
)
330 const void *data
= wxConnection::Request(item
, size
, format
);
331 Log("Request", wxEmptyString
, item
, data
, size
? *size
: wxNO_LEN
, format
);
335 bool MyConnection::DoPoke(const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
)
337 Log("Poke", wxEmptyString
, item
, data
, size
, format
);
338 return wxConnection::DoPoke(item
, data
, size
, format
);