Panda3D

cConnectionRepository.h

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
 All Classes Functions Variables Enumerations