Panda3D
|
00001 // Filename: cConnectionRepository.h 00002 // Created by: drose (17May04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef CCONNECTIONREPOSITORY_H 00016 #define CCONNECTIONREPOSITORY_H 00017 00018 #include "directbase.h" 00019 #include "pointerTo.h" 00020 00021 #include "dcbase.h" 00022 #include "dcFile.h" 00023 #include "dcField.h" // to pick up Python.h 00024 #include "pStatCollector.h" 00025 #include "datagramIterator.h" 00026 #include "clockObject.h" 00027 #include "reMutex.h" 00028 #include "reMutexHolder.h" 00029 00030 #ifdef HAVE_NET 00031 #include "queuedConnectionManager.h" 00032 #include "connectionWriter.h" 00033 #include "queuedConnectionReader.h" 00034 #include "connection.h" 00035 #endif 00036 00037 #ifdef WANT_NATIVE_NET 00038 #include "buffered_datagramconnection.h" 00039 #include "socket_address.h" 00040 #endif 00041 00042 class URLSpec; 00043 class HTTPChannel; 00044 class SocketStream; 00045 00046 //////////////////////////////////////////////////////////////////// 00047 // Class : CConnectionRepository 00048 // Description : This class implements the C++ side of the 00049 // ConnectionRepository object. In particular, it 00050 // manages the connection to the server once it has been 00051 // opened (but does not open it directly). It manages 00052 // reading and writing datagrams on the connection and 00053 // monitoring for unexpected disconnects as well as 00054 // handling intentional disconnects. 00055 // 00056 // Certain server messages, like field updates, are 00057 // handled entirely within the C++ layer, while server 00058 // messages that are not understood by the C++ layer are 00059 // returned up to the Python layer for processing. 00060 //////////////////////////////////////////////////////////////////// 00061 class EXPCL_DIRECT CConnectionRepository { 00062 PUBLISHED: 00063 CConnectionRepository(bool has_owner_view = false, 00064 bool threaded_net = false); 00065 ~CConnectionRepository(); 00066 00067 // Any methods of this class that acquire _lock (which is most of 00068 // them) *must* be tagged BLOCKING, to avoid risk of a race 00069 // condition in Python when running in true threaded mode. The 00070 // BLOCKING tag releases the Python GIL during the function call, 00071 // and we re-acquire it when needed within these functions to call 00072 // out to Python. If any functions acquire _lock while already 00073 // holding the Python GIL, there could be a deadlock between these 00074 // functions and the ones that are acquiring the GIL while already 00075 // holding _lock. 00076 00077 INLINE DCFile &get_dc_file(); 00078 00079 INLINE bool has_owner_view() const; 00080 00081 INLINE void set_handle_c_updates(bool handle_c_updates); 00082 INLINE bool get_handle_c_updates() const; 00083 00084 INLINE void set_client_datagram(bool client_datagram); 00085 INLINE bool get_client_datagram() const; 00086 00087 INLINE void set_handle_datagrams_internally(bool handle_datagrams_internally); 00088 INLINE bool get_handle_datagrams_internally() const; 00089 00090 void set_tcp_header_size(int tcp_header_size); 00091 INLINE int get_tcp_header_size() const; 00092 00093 #ifdef HAVE_PYTHON 00094 INLINE void set_python_repository(PyObject *python_repository); 00095 #endif 00096 00097 #ifdef HAVE_OPENSSL 00098 BLOCKING void set_connection_http(HTTPChannel *channel); 00099 BLOCKING SocketStream *get_stream(); 00100 #endif 00101 #ifdef HAVE_NET 00102 BLOCKING bool try_connect_net(const URLSpec &url); 00103 00104 INLINE QueuedConnectionManager &get_qcm(); 00105 INLINE ConnectionWriter &get_cw(); 00106 INLINE QueuedConnectionReader &get_qcr(); 00107 #endif 00108 00109 #ifdef WANT_NATIVE_NET 00110 BLOCKING bool connect_native(const URLSpec &url); 00111 INLINE Buffered_DatagramConnection &get_bdc(); 00112 #endif 00113 00114 #ifdef SIMULATE_NETWORK_DELAY 00115 BLOCKING void start_delay(double min_delay, double max_delay); 00116 BLOCKING void stop_delay(); 00117 #endif 00118 00119 BLOCKING bool check_datagram(); 00120 #ifdef HAVE_PYTHON 00121 #ifdef WANT_NATIVE_NET 00122 BLOCKING bool check_datagram_ai(PyObject *PycallBackFunction); 00123 BLOCKING bool network_based_reader_and_yielder(PyObject *PycallBackFunction,ClockObject &clock, float returnBy); 00124 #endif 00125 #endif 00126 00127 BLOCKING INLINE void get_datagram(Datagram &dg); 00128 BLOCKING INLINE void get_datagram_iterator(DatagramIterator &di); 00129 BLOCKING INLINE CHANNEL_TYPE get_msg_channel(int offset = 0) const; 00130 BLOCKING INLINE int get_msg_channel_count() const; 00131 BLOCKING INLINE CHANNEL_TYPE get_msg_sender() const; 00132 // INLINE unsigned char get_sec_code() const; 00133 BLOCKING INLINE unsigned int get_msg_type() const; 00134 00135 INLINE static const string &get_overflow_event_name(); 00136 00137 BLOCKING bool is_connected(); 00138 00139 BLOCKING bool send_datagram(const Datagram &dg); 00140 00141 BLOCKING INLINE void set_want_message_bundling(bool flag); 00142 BLOCKING INLINE bool get_want_message_bundling() const; 00143 00144 BLOCKING INLINE void set_in_quiet_zone(bool flag); 00145 BLOCKING INLINE bool get_in_quiet_zone() const; 00146 00147 BLOCKING void start_message_bundle(); 00148 BLOCKING INLINE bool is_bundling_messages() const; 00149 BLOCKING void send_message_bundle(unsigned int channel, unsigned int sender_channel); 00150 BLOCKING void abandon_message_bundles(); 00151 BLOCKING void bundle_msg(const Datagram &dg); 00152 00153 BLOCKING bool consider_flush(); 00154 BLOCKING bool flush(); 00155 00156 BLOCKING void disconnect(); 00157 BLOCKING void shutdown(); 00158 00159 INLINE void set_simulated_disconnect(bool simulated_disconnect); 00160 INLINE bool get_simulated_disconnect() const; 00161 00162 INLINE void toggle_verbose(); 00163 INLINE void set_verbose(bool verbose); 00164 INLINE bool get_verbose() const; 00165 00166 INLINE void set_time_warning(float time_warning); 00167 INLINE float get_time_warning() const; 00168 00169 private: 00170 #ifdef HAVE_PYTHON 00171 #ifdef WANT_NATIVE_NET 00172 bool handle_update_field_ai(PyObject *doId2do); 00173 #endif 00174 #endif 00175 00176 00177 bool do_check_datagram(); 00178 bool handle_update_field(); 00179 bool handle_update_field_owner(); 00180 00181 void describe_message(ostream &out, const string &prefix, 00182 const Datagram &dg) const; 00183 00184 private: 00185 ReMutex _lock; 00186 00187 #ifdef HAVE_PYTHON 00188 PyObject *_python_repository; 00189 PyObject *_python_ai_datagramiterator; 00190 #endif 00191 00192 #ifdef HAVE_OPENSSL 00193 SocketStream *_http_conn; 00194 #endif 00195 00196 #ifdef HAVE_NET 00197 QueuedConnectionManager _qcm; 00198 ConnectionWriter _cw; 00199 QueuedConnectionReader _qcr; 00200 PT(Connection) _net_conn; 00201 #endif 00202 00203 #ifdef WANT_NATIVE_NET 00204 Buffered_DatagramConnection _bdc; 00205 bool _native; 00206 #endif 00207 00208 DCFile _dc_file; 00209 bool _has_owner_view; 00210 bool _handle_c_updates; 00211 bool _client_datagram; 00212 bool _handle_datagrams_internally; 00213 int _tcp_header_size; 00214 bool _simulated_disconnect; 00215 bool _verbose; 00216 bool _in_quiet_zone; 00217 float _time_warning; 00218 00219 Datagram _dg; 00220 DatagramIterator _di; 00221 00222 std::vector<CHANNEL_TYPE> _msg_channels; 00223 CHANNEL_TYPE _msg_sender; 00224 unsigned int _msg_type; 00225 00226 static const string _overflow_event_name; 00227 00228 bool _want_message_bundling; 00229 unsigned int _bundling_msgs; 00230 typedef std::vector< string > BundledMsgVector; 00231 BundledMsgVector _bundle_msgs; 00232 00233 static PStatCollector _update_pcollector; 00234 }; 00235 00236 #include "cConnectionRepository.I" 00237 00238 #endif // CCONNECTIONREPOSITORY_H