// Filename: pStatClient.h // Created by: drose (09Jul00) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved // // All use of this software is subject to the terms of the Panda 3d // Software license. You should have received a copy of this license // along with this source code; you will also find a current copy of // the license at http://www.panda3d.org/license.txt . // // To contact the maintainers of this program write to // panda3d@yahoogroups.com . // //////////////////////////////////////////////////////////////////// #ifndef PSTATCLIENT_H #define PSTATCLIENT_H #include "pandabase.h" #include "pStatFrameData.h" #include #include "luse.h" #include "pmap.h" #ifdef HAVE_NET #include #include #include #include #endif class PStatServerControlMessage; class PStatCollector; class PStatCollectorDef; class PStatThread; //////////////////////////////////////////////////////////////////// // Class : PStatClient // Description : Manages the communications to report statistics via a // network connection to a remote PStatServer. // // Normally, there is only one PStatClient in the world, // although it is possible to have multiple PStatClients // if extraordinary circumstances require in. Since // each PStatCollector registers itself with the // PStatClient when it is created, having multiple // PStatClients requires special care when constructing // the various PStatCollectors. // // If DO_PSTATS is not defined, we don't want to use // stats at all. This class is therefore defined as a // stub class. //////////////////////////////////////////////////////////////////// #ifdef DO_PSTATS class EXPCL_PANDA PStatClient : public ConnectionManager { public: PStatClient(); ~PStatClient(); INLINE void set_client_name(const string &name); INLINE string get_client_name() const; INLINE void set_max_rate(float rate); INLINE float get_max_rate() const; int get_num_collectors() const; PStatCollector get_collector(int index) const; const PStatCollectorDef &get_collector_def(int index) const; string get_collector_name(int index) const; string get_collector_fullname(int index) const; int get_num_threads() const; PStatThread get_thread(int index) const; string get_thread_name(int index) const; const ClockObject &get_clock() const; PStatThread get_main_thread() const; PUBLISHED: INLINE static bool connect(const string &hostname = string(), int port = -1); INLINE static void disconnect(); INLINE static bool is_connected(); INLINE static void resume_after_pause(); public: static PStatClient *get_global_pstats(); static void main_tick(); void client_main_tick(); bool client_connect(string hostname, int port); void client_disconnect(); bool client_is_connected() const; void client_resume_after_pause(); private: PStatCollector make_collector_with_relname(int parent_index, string relname); PStatCollector make_collector_with_name(int parent_index, const string &name); PStatThread make_thread(const string &name); bool is_active(int collector_index, int thread_index) const; void start(int collector_index, int thread_index); void start(int collector_index, int thread_index, float as_of); void stop(int collector_index, int thread_index); void stop(int collector_index, int thread_index, float as_of); void clear_level(int collector_index, int thread_index); void set_level(int collector_index, int thread_index, float level); void add_level(int collector_index, int thread_index, float increment); float get_level(int collector_index, int thread_index) const; void new_frame(int thread_index); void transmit_frame_data(int thread_index); void transmit_control_data(); // Stats collecting stuff ClockObject _clock; typedef pmap ThingsByName; ThingsByName _threads_by_name; // This is for the data that is per-collector, per-thread. A vector // of these is stored in each Collector object, below, indexed by // thread index. class PerThreadData { public: PerThreadData(); bool _has_level; float _level; int _nested_count; }; typedef pvector PerThread; // This is where the meat of the Collector data is stored. (All the // stuff in PStatCollector and PStatCollectorDef is just fluff.) class Collector { public: PStatCollectorDef *_def; ThingsByName _children; PerThread _per_thread; }; typedef pvector Collectors; Collectors _collectors; // This defines a single thread, i.e. a separate chain of execution, // independent of all other threads. Timing and level data are // maintained separately for each thread. class Thread { public: string _name; PStatFrameData _frame_data; bool _is_active; int _frame_number; float _next_packet; }; typedef pvector Threads; Threads _threads; private: // Networking stuff string get_hostname(); void send_hello(); void report_new_collectors(); void report_new_threads(); void handle_server_control_message(const PStatServerControlMessage &message); virtual void connection_reset(const PT(Connection) &connection, PRErrorCode errcode); bool _is_connected; bool _got_udp_port; NetAddress _server; QueuedConnectionReader _reader; ConnectionWriter _writer; PT(Connection) _tcp_connection; PT(Connection) _udp_connection; int _collectors_reported; int _threads_reported; string _hostname; string _client_name; float _max_rate; static PStatClient *_global_pstats; friend class PStatCollector; friend class PStatThread; }; #include "pStatClient.I" #else // DO_PSTATS class EXPCL_PANDA PStatClient { public: PStatClient() { } ~PStatClient() { } PUBLISHED: INLINE static bool connect(const string & = string(), int = -1) { return false; } INLINE static void disconnect() { } INLINE static bool is_connected() { return false; } INLINE static void resume_after_pause() { } public: static void main_tick() { } }; #endif // DO_PSTATS #endif