E-MailRelay

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gclientptr.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2018 Graeme Walker <graeme_walker@users.sourceforge.net>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gclientptr.h
19 ///
20
21 #ifndef G_NET_CLIENT_PTR__H
22 #define G_NET_CLIENT_PTR__H
23
24 #include "gdef.h"
25 #include "gclient.h"
26 #include "gexception.h"
27 #include "gassert.h"
28 #include "gslot.h"
29 #include <memory>
30
31 namespace GNet
32 {
33 template <typename T> class ClientPtr ;
34 }
35
36 /// \class GNet::ClientPtr
37 /// A smart pointer class for GNet::HeapClient that keeps track of when the
38 /// contained instance deletes itself. When the smart pointer goes out of
39 /// scope the HeapClient object is told to delete itself asynchronously
40 /// using its doDelete() mechanism. The GNet::Client's slots-and-signals
41 /// are managed automatically so that ClientPtr users do not have to
42 /// disconnect and reconnect them.
43 ///
44 template <typename T>
45 class GNet::ClientPtr
46 {
47 public:
48 G_EXCEPTION( InvalidState , "invalid state of network client handle" ) ;
49
50 explicit ClientPtr( T * p = nullptr ) ;
51 ///< Constructor. Takes ownership of the new-ed client.
52
53 ~ClientPtr() ;
54 ///< Destructor.
55
56 bool busy() const ;
57 ///< Returns true if the pointer is not nullptr.
58
59 void reset( T * p = nullptr ) ;
60 ///< Resets the pointer. The old client object, if any, is
61 ///< told to delete itself asynchronously and it will be
62 ///< released from this smart pointer while it does so,
63 ///< with its signals going nowhere.
64
65 void resetForExit() ;
66 ///< Resets the pointer. The old client object, if any, is
67 ///< deleted synchronously. This should only be used from
68 ///< outside of EventLoop::run(), just as the TimerList
69 ///< is going away.
70
71 T * release() ;
72 ///< Releases the pointer so ownership is transfered to the
73 ///< caller. The released object's signals are disconnected.
74
75 T * get() ;
76 ///< Returns the pointer, or nullptr if deleted.
77
78 T * operator->() ;
79 ///< Returns the pointer. Throws if deleted.
80
81 const T * operator->() const ;
82 ///< Returns the pointer. Throws if deleted.
83
84 G::Slot::Signal1<std::string> & doneSignal() ;
85 ///< Returns a signal which indicates that client processing
86 ///< is complete and the client instance has deleted
87 ///< itself. The signal parameter is the failure
88 ///< reason.
89
90 G::Slot::Signal2<std::string,std::string> & eventSignal() ;
91 ///< Returns a signal which indicates something interesting.
92
93 G::Slot::Signal0 & connectedSignal() ;
94 ///< Returns a signal which indicates that the
95 ///< connection has been established successfully.
96
97 private:
98 ClientPtr( const ClientPtr & ) ; // not implemented
99 void operator=( const ClientPtr & ) ; // not implemented
100 void doneSlot( std::string ) ;
101 void eventSlot( std::string , std::string ) ;
102 void connectedSlot() ;
103 void connectSignalsToSlots() ;
104 void disconnectSignals() ;
105
106 private:
107 T * m_p ;
108 G::Slot::Signal1<std::string> m_done_signal ;
109 G::Slot::Signal2<std::string,std::string> m_event_signal ;
110 G::Slot::Signal0 m_connected_signal ;
111 } ;
112
113 template <typename T>
114 GNet::ClientPtr<T>::ClientPtr( T * p ) :
115 m_p(p)
116 {
117 try
118 {
119 connectSignalsToSlots() ;
120 }
121 catch(...)
122 {
123 // should p->doDelete() here
124 throw ;
125 }
126 }
127
128 template <typename T>
129 GNet::ClientPtr<T>::~ClientPtr()
130 {
131 if( m_p != nullptr )
132 {
133 disconnectSignals() ;
134 m_p->doDelete( std::string() ) ;
135 }
136 }
137
138 template <typename T>
139 T * GNet::ClientPtr<T>::release()
140 {
141 T * result = nullptr ;
142 if( m_p != nullptr )
143 {
144 disconnectSignals() ;
145 result = m_p ;
146 m_p = nullptr ;
147 }
148 return result ;
149 }
150
151 template <typename T>
152 void GNet::ClientPtr<T>::connectSignalsToSlots()
153 {
154 if( m_p != nullptr )
155 {
156 m_p->doneSignal().connect( G::Slot::slot(*this,&ClientPtr::doneSlot) ) ;
157 m_p->eventSignal().connect( G::Slot::slot(*this,&ClientPtr::eventSlot) ) ;
158 m_p->connectedSignal().connect( G::Slot::slot(*this,&ClientPtr::connectedSlot) ) ;
159 }
160 }
161
162 template <typename T>
163 void GNet::ClientPtr<T>::reset( T * p )
164 {
165 disconnectSignals() ;
166 T * old = m_p ;
167 m_p = p ;
168 if( old != nullptr )
169 {
170 old->doDelete( std::string() ) ;
171 }
172 connectSignalsToSlots() ;
173 }
174
175 template <typename T>
176 void GNet::ClientPtr<T>::resetForExit()
177 {
178 disconnectSignals() ;
179 T * p = m_p ;
180 m_p = nullptr ;
181 if( p != nullptr )
182 p->doDelete( std::string() ) ;
183 delete p ;
184 }
185
186 template <typename T>
187 G::Slot::Signal1<std::string> & GNet::ClientPtr<T>::doneSignal()
188 {
189 return m_done_signal ;
190 }
191
192 template <typename T>
193 G::Slot::Signal2<std::string,std::string> & GNet::ClientPtr<T>::eventSignal()
194 {
195 return m_event_signal ;
196 }
197
198 template <typename T>
199 G::Slot::Signal0 & GNet::ClientPtr<T>::connectedSignal()
200 {
201 return m_connected_signal ;
202 }
203
204 template <typename T>
205 void GNet::ClientPtr<T>::doneSlot( std::string reason )
206 {
207 G_ASSERT( m_p != nullptr ) ;
208 disconnectSignals() ;
209 m_p = nullptr ;
210 m_done_signal.emit( reason ) ;
211 }
212
213 template <typename T>
214 void GNet::ClientPtr<T>::disconnectSignals()
215 {
216 if( m_p != nullptr )
217 {
218 m_p->doneSignal().disconnect() ;
219 m_p->eventSignal().disconnect() ;
220 m_p->connectedSignal().disconnect() ;
221 }
222 }
223
224 template <typename T>
225 void GNet::ClientPtr<T>::connectedSlot()
226 {
227 G_ASSERT( m_p != nullptr ) ;
228 m_connected_signal.emit() ;
229 }
230
231 template <typename T>
232 void GNet::ClientPtr<T>::eventSlot( std::string s1 , std::string s2 )
233 {
234 m_event_signal.emit( s1 , s2 ) ;
235 }
236
237 template <typename T>
238 T * GNet::ClientPtr<T>::get()
239 {
240 return m_p ;
241 }
242
243 template <typename T>
244 bool GNet::ClientPtr<T>::busy() const
245 {
246 return m_p != nullptr ;
247 }
248
249 template <typename T>
250 T * GNet::ClientPtr<T>::operator->()
251 {
252 if( m_p == nullptr )
253 throw InvalidState() ;
254 return m_p ;
255 }
256
257 template <typename T>
258 const T * GNet::ClientPtr<T>::operator->() const
259 {
260 if( m_p == nullptr )
261 throw InvalidState() ;
262 return m_p ;
263 }
264
265 #endif
GNet::ClientPtr::eventSignal
G::Slot::Signal2< std::string, std::string > & eventSignal()
Returns a signal which indicates something interesting.
Definition: gclientptr.h:193
GNet::ClientPtr::resetForExit
void resetForExit()
Resets the pointer.
Definition: gclientptr.h:176
GNet
Network classes.
Definition: gaddress.h:29
G::Slot::Signal2< std::string, std::string >
GNet::ClientPtr::get
T * get()
Returns the pointer, or nullptr if deleted.
Definition: gclientptr.h:238
gclient.h
GNet::ClientPtr::~ClientPtr
~ClientPtr()
Destructor.
Definition: gclientptr.h:129
GNet::ClientPtr::ClientPtr
ClientPtr(T *p=nullptr)
Constructor. Takes ownership of the new-ed client.
Definition: gclientptr.h:114
gslot.h
GNet::ClientPtr::connectedSignal
G::Slot::Signal0 & connectedSignal()
Returns a signal which indicates that the connection has been established successfully.
Definition: gclientptr.h:199
GNet::ClientPtr::release
T * release()
Releases the pointer so ownership is transfered to the caller.
Definition: gclientptr.h:139
gassert.h
G::Slot::slot
Slot0 slot(T &object, void(T::*fn)())
A slot factory function overloaded for a zero-parameter callback.
Definition: gslot.h:209
GNet::ClientPtr::doneSignal
G::Slot::Signal1< std::string > & doneSignal()
Returns a signal which indicates that client processing is complete and the client instance has delet...
Definition: gclientptr.h:187
G::Slot::Signal0
A signal class for zero-parameter callbacks.
Definition: gslot.h:193
gexception.h
GNet::ClientPtr::operator->
T * operator->()
Returns the pointer. Throws if deleted.
Definition: gclientptr.h:250
GNet::ClientPtr
A smart pointer class for GNet::HeapClient that keeps track of when the contained instance deletes it...
Definition: gclientptr.h:33
G::Slot::Signal1< std::string >
GNet::ClientPtr::busy
bool busy() const
Returns true if the pointer is not nullptr.
Definition: gclientptr.h:244
GNet::ClientPtr::reset
void reset(T *p=nullptr)
Resets the pointer.
Definition: gclientptr.h:163