00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef PEEKABOT_CLIENT_CLIENT_IMPL_HH_INCLUDED
00012 #define PEEKABOT_CLIENT_CLIENT_IMPL_HH_INCLUDED
00013
00014
00015 #include <map>
00016 #include <string>
00017 #include <boost/cstdint.hpp>
00018 #include <boost/thread.hpp>
00019 #include <boost/utility.hpp>
00020 #include <boost/shared_ptr.hpp>
00021 #include <boost/scoped_ptr.hpp>
00022
00023 #include "../Any.hh"
00024 #include "../Types.hh"
00025 #include "Status.hh"
00026 #include "Result.hh"
00027
00028
00029 namespace peekabot
00030 {
00031
00032 template<class> class IDAllocator;
00033 class Action;
00034 class Bundle;
00035
00036 namespace client
00037 {
00038 class Transport;
00039 class ClientExecutionContext;
00040 class ObjectProxyBase;
00041 class DelayedDispatch;
00042
00043
00044
00061 class ClientImpl : public boost::noncopyable,
00062 public boost::enable_shared_from_this<ClientImpl>
00063 {
00064 friend class Transport;
00065 friend class ClientExecutionContext;
00066 friend class ObjectProxyBase;
00067
00068 public:
00069 ClientImpl() throw();
00070
00071 virtual ~ClientImpl() throw();
00072
00092 void connect_master(const std::string &hostname, unsigned int port);
00093
00099 void disconnect_master();
00100
00101 bool is_master_connected() const;
00102
00103 void flush_master() throw();
00104
00111 void flush_all() throw();
00112
00113 void dispatch_action(
00114 boost::shared_ptr<Action> action,
00115 Status *s,
00116 bool bypass_bundling,
00117 bool master_only);
00118
00119 void dispatch_action(
00120 Action *action,
00121 Status *s,
00122 bool bypass_bundling,
00123 bool master_only);
00124
00125 boost::shared_ptr<OperationResult> dispatch_get_action(
00126 boost::shared_ptr<Action> action,
00127 uint32_t request_id,
00128 bool bypass_bundling);
00129
00130 boost::shared_ptr<OperationResult> dispatch_get_action(
00131 Action *action,
00132 uint32_t request_id,
00133 bool bypass_bundling);
00134
00135 void begin_bundle();
00136
00137 boost::shared_ptr<Action> end_bundle();
00138
00139 bool is_bundling() const;
00140
00141 void sync_master();
00142
00143
00144 void disconnect_all();
00145
00146
00147 void start_recording(const std::string &filename);
00148
00149 void stop_recording();
00150
00151 bool is_recording() const;
00152
00153 void flush_recorder();
00154
00155
00156 uint32_t allocate_request_id() throw();
00157
00158 boost::shared_ptr<OperationResult>
00159 register_result_request(uint32_t request_id) throw();
00160
00161 private:
00162 void execute_action(boost::shared_ptr<Action> action) throw();
00163
00164 void release_request_id(uint32_t request_id) throw();
00165
00166 void report_disconnected_transport(Transport *t);
00167
00168 boost::shared_ptr<OperationStatus>
00169 register_status_request(uint32_t request_id) throw();
00170
00171
00172
00173 private:
00174 mutable boost::recursive_mutex m_mutex;
00175
00176 Transport *m_master;
00177 Transport *m_recorder;
00178
00179 struct BundleData
00180 {
00181 boost::shared_ptr<Bundle> m_master_bundle;
00182 boost::shared_ptr<Bundle> m_slave_bundle;
00183 };
00184
00185 boost::thread_specific_ptr<BundleData> m_bundle_data;
00186
00187
00188
00189
00190
00191 typedef std::map<
00192 uint32_t, boost::shared_ptr<OperationStatus> > RequestMap;
00193
00194 RequestMap m_requests;
00195
00196 boost::scoped_ptr<IDAllocator<uint32_t> > m_request_id_allocator;
00197
00198 void report_action_status(
00199 boost::uint32_t request_id,
00200 OperationOutcome outcome,
00201 const std::string &error_msg) throw();
00202
00203 void report_action_result(
00204 boost::uint32_t request_id,
00205 const Any &result) throw();
00206 };
00207
00208 }
00209 }
00210
00211
00212 #endif // PEEKABOT_CLIENT_CLIENT_IMPL_HH_INCLUDED