mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
split out PStatClientImpl
This commit is contained in:
parent
7d5ae1e3f6
commit
db8cdc119d
@ -10,7 +10,9 @@
|
|||||||
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
|
||||||
|
|
||||||
#define SOURCES \
|
#define SOURCES \
|
||||||
config_pstats.h pStatClient.I pStatClient.h pStatClientVersion.I \
|
config_pstats.h pStatClient.I pStatClient.h \
|
||||||
|
pStatClientImpl.I pStatClientImpl.h \
|
||||||
|
pStatClientVersion.I \
|
||||||
pStatClientVersion.h pStatClientControlMessage.h \
|
pStatClientVersion.h pStatClientControlMessage.h \
|
||||||
pStatCollector.I pStatCollector.h pStatCollectorDef.h \
|
pStatCollector.I pStatCollector.h pStatCollectorDef.h \
|
||||||
pStatFrameData.I pStatFrameData.h pStatProperties.h \
|
pStatFrameData.I pStatFrameData.h pStatProperties.h \
|
||||||
@ -18,13 +20,15 @@
|
|||||||
pStatTimer.I pStatTimer.h
|
pStatTimer.I pStatTimer.h
|
||||||
|
|
||||||
#define INCLUDED_SOURCES \
|
#define INCLUDED_SOURCES \
|
||||||
config_pstats.cxx pStatClient.cxx pStatClientVersion.cxx \
|
config_pstats.cxx pStatClient.cxx pStatClientImpl.cxx \
|
||||||
|
pStatClientVersion.cxx \
|
||||||
pStatClientControlMessage.cxx pStatCollectorDef.cxx \
|
pStatClientControlMessage.cxx pStatCollectorDef.cxx \
|
||||||
pStatFrameData.cxx pStatProperties.cxx \
|
pStatFrameData.cxx pStatProperties.cxx \
|
||||||
pStatServerControlMessage.cxx
|
pStatServerControlMessage.cxx
|
||||||
|
|
||||||
#define INSTALL_HEADERS \
|
#define INSTALL_HEADERS \
|
||||||
config_pstats.h pStatClient.I pStatClient.h \
|
config_pstats.h pStatClient.I pStatClient.h \
|
||||||
|
pStatClientImpl.I pStatClientImpl.h \
|
||||||
pStatClientVersion.I pStatClientVersion.h \
|
pStatClientVersion.I pStatClientVersion.h \
|
||||||
pStatClientControlMessage.h pStatCollector.I pStatCollector.h \
|
pStatClientControlMessage.h pStatCollector.I pStatCollector.h \
|
||||||
pStatCollectorDef.h pStatFrameData.I pStatFrameData.h \
|
pStatCollectorDef.h pStatFrameData.I pStatFrameData.h \
|
||||||
|
@ -19,29 +19,29 @@
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::set_client_name
|
// Function: PStatClient::set_client_name
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Sets the name of the client. This is reported to the
|
// Description: Sets the name of the client. This is reported to the
|
||||||
// PStatsServer, and will presumably be written in the
|
// PStatsServer, and will presumably be written in the
|
||||||
// title bar or something.
|
// title bar or something.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void PStatClient::
|
INLINE void PStatClient::
|
||||||
set_client_name(const string &name) {
|
set_client_name(const string &name) {
|
||||||
_client_name = name;
|
get_impl()->set_client_name(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_client_name
|
// Function: PStatClient::get_client_name
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Retrieves the name of the client as set.
|
// Description: Retrieves the name of the client as set.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE string PStatClient::
|
INLINE string PStatClient::
|
||||||
get_client_name() const {
|
get_client_name() const {
|
||||||
return _client_name;
|
return get_impl()->get_client_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::set_max_rate
|
// Function: PStatClient::set_max_rate
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Controls the number of packets that will be sent to
|
// Description: Controls the number of packets that will be sent to
|
||||||
// the server. Normally, one packet is sent per frame,
|
// the server. Normally, one packet is sent per frame,
|
||||||
// but this can flood the server with more packets than
|
// but this can flood the server with more packets than
|
||||||
@ -56,24 +56,71 @@ get_client_name() const {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void PStatClient::
|
INLINE void PStatClient::
|
||||||
set_max_rate(float rate) {
|
set_max_rate(float rate) {
|
||||||
_max_rate = rate;
|
get_impl()->set_max_rate(rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_max_rate
|
// Function: PStatClient::get_max_rate
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the maximum number of packets that will be
|
// Description: Returns the maximum number of packets that will be
|
||||||
// sent to the server per second, per thread. See
|
// sent to the server per second, per thread. See
|
||||||
// set_max_rate().
|
// set_max_rate().
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE float PStatClient::
|
INLINE float PStatClient::
|
||||||
get_max_rate() const {
|
get_max_rate() const {
|
||||||
return _max_rate;
|
return get_impl()->get_max_rate();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_num_collectors
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the total number of collectors the Client
|
||||||
|
// knows about.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int PStatClient::
|
||||||
|
get_num_collectors() const {
|
||||||
|
return _collectors.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_num_threads
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the total number of threads the Client
|
||||||
|
// knows about.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int PStatClient::
|
||||||
|
get_num_threads() const {
|
||||||
|
return _threads.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_thread_name
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the name of the indicated thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE string PStatClient::
|
||||||
|
get_thread_name(int index) const {
|
||||||
|
nassertr(index >= 0 && index < (int)_threads.size(), string());
|
||||||
|
return _threads[index]._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_clock
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a reference to the PStatClient's clock
|
||||||
|
// object. It keeps its own clock, instead of using the
|
||||||
|
// global clock object, so the stats won't get mucked up
|
||||||
|
// if you put the global clock in non-real-time mode or
|
||||||
|
// something.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const ClockObject &PStatClient::
|
||||||
|
get_clock() const {
|
||||||
|
return get_impl()->get_clock();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::connect
|
// Function: PStatClient::connect
|
||||||
// Access: Published
|
// Access: Published, Static
|
||||||
// Description: Attempts to establish a connection to the indicated
|
// Description: Attempts to establish a connection to the indicated
|
||||||
// PStatServer. Returns true if successful, false on
|
// PStatServer. Returns true if successful, false on
|
||||||
// failure.
|
// failure.
|
||||||
@ -85,7 +132,7 @@ connect(const string &hostname, int port) {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::disconnect
|
// Function: PStatClient::disconnect
|
||||||
// Access: Published
|
// Access: Published, Static
|
||||||
// Description: Closes the connection previously established.
|
// Description: Closes the connection previously established.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void PStatClient::
|
INLINE void PStatClient::
|
||||||
@ -95,7 +142,7 @@ disconnect() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::is_connected
|
// Function: PStatClient::is_connected
|
||||||
// Access: Published
|
// Access: Published, Static
|
||||||
// Description: Returns true if the client believes it is connected
|
// Description: Returns true if the client believes it is connected
|
||||||
// to a working PStatServer, false otherwise.
|
// to a working PStatServer, false otherwise.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -106,7 +153,7 @@ is_connected() {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::resume_after_pause
|
// Function: PStatClient::resume_after_pause
|
||||||
// Access: Published
|
// Access: Published, Static
|
||||||
// Description: Resumes the PStatClient after the simulation has been
|
// Description: Resumes the PStatClient after the simulation has been
|
||||||
// paused for a while. This allows the stats to
|
// paused for a while. This allows the stats to
|
||||||
// continue exactly where it left off, instead of
|
// continue exactly where it left off, instead of
|
||||||
@ -116,3 +163,78 @@ INLINE void PStatClient::
|
|||||||
resume_after_pause() {
|
resume_after_pause() {
|
||||||
get_global_pstats()->client_resume_after_pause();
|
get_global_pstats()->client_resume_after_pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::client_connect
|
||||||
|
// Access: Published
|
||||||
|
// Description: The nonstatic implementation of connect().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool PStatClient::
|
||||||
|
client_connect(string hostname, int port) {
|
||||||
|
client_disconnect();
|
||||||
|
return get_impl()->client_connect(hostname, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::client_is_connected
|
||||||
|
// Access: Published
|
||||||
|
// Description: The nonstatic implementation of is_connected().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool PStatClient::
|
||||||
|
client_is_connected() const {
|
||||||
|
return has_impl() && _impl->client_is_connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::client_resume_after_pause
|
||||||
|
// Access: Published
|
||||||
|
// Description: Resumes the PStatClient after the simulation has been
|
||||||
|
// paused for a while. This allows the stats to
|
||||||
|
// continue exactly where it left off, instead of
|
||||||
|
// leaving a big gap that would represent a chug.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void PStatClient::
|
||||||
|
client_resume_after_pause() {
|
||||||
|
if (has_impl()) {
|
||||||
|
_impl->client_resume_after_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::has_impl
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns true if the PStatClientImpl object has been
|
||||||
|
// created for this object yet, false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool PStatClient::
|
||||||
|
has_impl() const {
|
||||||
|
return (_impl != (PStatClientImpl *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_impl
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns the PStatClientImpl object for this object.
|
||||||
|
// If the PStatClientImpl object has not yet been
|
||||||
|
// created, implicitly creates it.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE PStatClientImpl *PStatClient::
|
||||||
|
get_impl() {
|
||||||
|
if (_impl == (PStatClientImpl *)NULL) {
|
||||||
|
_impl = new PStatClientImpl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_impl
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns the PStatClientImpl object for this object.
|
||||||
|
// If the PStatClientImpl object has not yet been
|
||||||
|
// created, implicitly creates it.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const PStatClientImpl *PStatClient::
|
||||||
|
get_impl() const {
|
||||||
|
return ((PStatClient *)this)->get_impl();
|
||||||
|
}
|
||||||
|
@ -22,29 +22,21 @@
|
|||||||
// This file only defines anything interesting if DO_PSTATS is
|
// This file only defines anything interesting if DO_PSTATS is
|
||||||
// defined.
|
// defined.
|
||||||
|
|
||||||
|
#include "pStatClientImpl.h"
|
||||||
#include "pStatClientControlMessage.h"
|
#include "pStatClientControlMessage.h"
|
||||||
#include "pStatServerControlMessage.h"
|
#include "pStatServerControlMessage.h"
|
||||||
#include "pStatCollector.h"
|
#include "pStatCollector.h"
|
||||||
#include "pStatThread.h"
|
#include "pStatThread.h"
|
||||||
#include "config_pstats.h"
|
#include "config_pstats.h"
|
||||||
#include "pStatProperties.h"
|
#include "pStatProperties.h"
|
||||||
#include "cmath.h"
|
|
||||||
#include "mathNumbers.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
PStatCollector PStatClient::_total_size_pcollector("Memory usage");
|
||||||
|
PStatCollector PStatClient::_cpp_size_pcollector("Memory usage:C++");
|
||||||
#ifdef WIN32_VC
|
PStatCollector PStatClient::_interpreter_size_pcollector("Memory usage:Interpreter");
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
PStatCollector PStatClient::_pstats_pcollector("App:PStats");
|
||||||
#include <windows.h>
|
|
||||||
#undef WINDOWS_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PStatClient *PStatClient::_global_pstats = NULL;
|
PStatClient *PStatClient::_global_pstats = NULL;
|
||||||
|
|
||||||
PStatCollector _total_size_pcollector("Memory usage");
|
|
||||||
PStatCollector _cpp_size_pcollector("Memory usage:C++");
|
|
||||||
PStatCollector _interpreter_size_pcollector("Memory usage:Interpreter");
|
|
||||||
PStatCollector _pstats_pcollector("App:PStats");
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::PerThreadData::Constructor
|
// Function: PStatClient::PerThreadData::Constructor
|
||||||
@ -65,17 +57,8 @@ PerThreadData() {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PStatClient::
|
PStatClient::
|
||||||
PStatClient() :
|
PStatClient() :
|
||||||
_reader(this, 0),
|
_impl(NULL)
|
||||||
_writer(this, get_pstats_threaded_write() ? 1 : 0)
|
|
||||||
{
|
{
|
||||||
_is_connected = false;
|
|
||||||
_got_udp_port = false;
|
|
||||||
_collectors_reported = 0;
|
|
||||||
_threads_reported = 0;
|
|
||||||
|
|
||||||
// Make sure our clock is in "normal" mode.
|
|
||||||
_clock.set_mode(ClockObject::M_normal);
|
|
||||||
|
|
||||||
// We always have a collector at index 0 named "Frame". This tracks
|
// We always have a collector at index 0 named "Frame". This tracks
|
||||||
// the total frame time and is the root of all other collectors. We
|
// the total frame time and is the root of all other collectors. We
|
||||||
// have to make this one by hand since it's the root.
|
// have to make this one by hand since it's the root.
|
||||||
@ -87,28 +70,6 @@ PStatClient() :
|
|||||||
|
|
||||||
// We also always have a thread at index 0 named "Main".
|
// We also always have a thread at index 0 named "Main".
|
||||||
make_thread("Main");
|
make_thread("Main");
|
||||||
|
|
||||||
_client_name = get_pstats_name();
|
|
||||||
_max_rate = get_pstats_max_rate();
|
|
||||||
|
|
||||||
_tcp_count = 1;
|
|
||||||
_udp_count = 1;
|
|
||||||
|
|
||||||
double pstats_tcp_ratio = get_pstats_tcp_ratio();
|
|
||||||
|
|
||||||
if (pstats_tcp_ratio >= 1.0f) {
|
|
||||||
_tcp_count_factor = 0.0f;
|
|
||||||
_udp_count_factor = 1.0f;
|
|
||||||
|
|
||||||
} else if (pstats_tcp_ratio <= 0.0f) {
|
|
||||||
_tcp_count_factor = 1.0f;
|
|
||||||
_udp_count_factor = 0.0f;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
csincos(pstats_tcp_ratio * MathNumbers::pi_f / 2.0f,
|
|
||||||
&_udp_count_factor,
|
|
||||||
&_tcp_count_factor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -119,22 +80,15 @@ PStatClient() :
|
|||||||
PStatClient::
|
PStatClient::
|
||||||
~PStatClient() {
|
~PStatClient() {
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
if (has_impl()) {
|
||||||
// Function: PStatClient::get_num_collectors
|
delete _impl;
|
||||||
// Access: Public
|
}
|
||||||
// Description: Returns the total number of collectors the Client
|
|
||||||
// knows about.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
int PStatClient::
|
|
||||||
get_num_collectors() const {
|
|
||||||
return _collectors.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_collector
|
// Function: PStatClient::get_collector
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the nth collector.
|
// Description: Returns the nth collector.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PStatCollector PStatClient::
|
PStatCollector PStatClient::
|
||||||
@ -145,7 +99,7 @@ get_collector(int index) const {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_collector_def
|
// Function: PStatClient::get_collector_def
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the definition body of the nth collector.
|
// Description: Returns the definition body of the nth collector.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
const PStatCollectorDef &PStatClient::
|
const PStatCollectorDef &PStatClient::
|
||||||
@ -160,7 +114,7 @@ get_collector_def(int index) const {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_collector_name
|
// Function: PStatClient::get_collector_name
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the name of the indicated collector.
|
// Description: Returns the name of the indicated collector.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
string PStatClient::
|
string PStatClient::
|
||||||
@ -173,7 +127,7 @@ get_collector_name(int index) const {
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_collector_fullname
|
// Function: PStatClient::get_collector_fullname
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the "full name" of the indicated collector.
|
// Description: Returns the "full name" of the indicated collector.
|
||||||
// This will be the concatenation of all of the
|
// This will be the concatenation of all of the
|
||||||
// collector's parents' names (except Frame) and the
|
// collector's parents' names (except Frame) and the
|
||||||
@ -191,20 +145,9 @@ get_collector_fullname(int index) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::get_num_threads
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the total number of threads the Client
|
|
||||||
// knows about.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
int PStatClient::
|
|
||||||
get_num_threads() const {
|
|
||||||
return _threads.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_thread
|
// Function: PStatClient::get_thread
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns the nth thread.
|
// Description: Returns the nth thread.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PStatThread PStatClient::
|
PStatThread PStatClient::
|
||||||
@ -213,38 +156,9 @@ get_thread(int index) const {
|
|||||||
return PStatThread((PStatClient *)this, index);
|
return PStatThread((PStatClient *)this, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::get_thread_name
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns the name of the indicated thread.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
string PStatClient::
|
|
||||||
get_thread_name(int index) const {
|
|
||||||
nassertr(index >= 0 && index < (int)_threads.size(), string());
|
|
||||||
return _threads[index]._name;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::get_clock
|
|
||||||
// Access: Public
|
|
||||||
// Description: Returns a reference to the PStatClient's clock
|
|
||||||
// object. It keeps its own clock, instead of using the
|
|
||||||
// global clock object, so the stats won't get mucked up
|
|
||||||
// if you put the global clock in non-real-time mode or
|
|
||||||
// something.
|
|
||||||
//
|
|
||||||
// On second thought, it works better to use the global
|
|
||||||
// clock, so we don't lose a lot of time in the stats
|
|
||||||
// while we're waiting at the prompt.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
const ClockObject &PStatClient::
|
|
||||||
get_clock() const {
|
|
||||||
return _clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::get_main_thread
|
// Function: PStatClient::get_main_thread
|
||||||
// Access: Public
|
// Access: Published
|
||||||
// Description: Returns a handle to the client's "Main", or default,
|
// Description: Returns a handle to the client's "Main", or default,
|
||||||
// thread. This is where collectors will be started and
|
// thread. This is where collectors will be started and
|
||||||
// stopped if they don't specify otherwise.
|
// stopped if they don't specify otherwise.
|
||||||
@ -254,6 +168,94 @@ get_main_thread() const {
|
|||||||
return PStatThread((PStatClient *)this, 0);
|
return PStatThread((PStatClient *)this, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::main_tick
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: A convenience function to call new_frame() on the
|
||||||
|
// global PStatClient's main thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClient::
|
||||||
|
main_tick() {
|
||||||
|
// We have code here to report the memory usage. We can't put this
|
||||||
|
// code inside the MemoryUsage class, where it fits a little better,
|
||||||
|
// simply because MemoryUsage is a very low-level class that doesn't
|
||||||
|
// know about PStatClient.
|
||||||
|
|
||||||
|
#ifdef DO_MEMORY_USAGE
|
||||||
|
if (MemoryUsage::has_total_size()) {
|
||||||
|
_total_size_pcollector.set_level(MemoryUsage::get_total_size());
|
||||||
|
}
|
||||||
|
if (MemoryUsage::has_cpp_size()) {
|
||||||
|
_cpp_size_pcollector.set_level(MemoryUsage::get_cpp_size());
|
||||||
|
}
|
||||||
|
if (MemoryUsage::has_interpreter_size()) {
|
||||||
|
_interpreter_size_pcollector.set_level(MemoryUsage::get_interpreter_size());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
get_global_pstats()->client_main_tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::client_main_tick
|
||||||
|
// Access: Published
|
||||||
|
// Description: A convenience function to call new_frame() on the
|
||||||
|
// the given client's main thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClient::
|
||||||
|
client_main_tick() {
|
||||||
|
if (has_impl()) {
|
||||||
|
_impl->client_main_tick();
|
||||||
|
}
|
||||||
|
get_main_thread().new_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::client_disconnect
|
||||||
|
// Access: Published
|
||||||
|
// Description: The nonstatic implementation of disconnect().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClient::
|
||||||
|
client_disconnect() {
|
||||||
|
if (has_impl()) {
|
||||||
|
_impl->client_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
Threads::iterator ti;
|
||||||
|
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
||||||
|
(*ti)._frame_number = 0;
|
||||||
|
(*ti)._is_active = false;
|
||||||
|
(*ti)._next_packet = 0.0;
|
||||||
|
(*ti)._frame_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Collectors::iterator ci;
|
||||||
|
for (ci = _collectors.begin(); ci != _collectors.end(); ++ci) {
|
||||||
|
PerThread::iterator ii;
|
||||||
|
for (ii = (*ci)._per_thread.begin();
|
||||||
|
ii != (*ci)._per_thread.end();
|
||||||
|
++ii) {
|
||||||
|
(*ii)._nested_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClient::get_global_pstats
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Returns a pointer to the global PStatClient object.
|
||||||
|
// It's legal to declare your own PStatClient locally,
|
||||||
|
// but it's also convenient to have a global one that
|
||||||
|
// everyone can register with. This is the global one.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PStatClient *PStatClient::
|
||||||
|
get_global_pstats() {
|
||||||
|
if (_global_pstats == (PStatClient *)NULL) {
|
||||||
|
_global_pstats = new PStatClient;
|
||||||
|
}
|
||||||
|
return _global_pstats;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::make_collector_with_relname
|
// Function: PStatClient::make_collector_with_relname
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -388,175 +390,6 @@ make_thread(const string &name) {
|
|||||||
return PStatThread(this, new_index);
|
return PStatThread(this, new_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::main_tick
|
|
||||||
// Access: Public, Static
|
|
||||||
// Description: A convenience function to call new_frame() on the
|
|
||||||
// global PStatClient's main thread.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
main_tick() {
|
|
||||||
// We have code here to report the memory usage. We can't put this
|
|
||||||
// code inside the MemoryUsage class, where it fits a little better,
|
|
||||||
// simply because MemoryUsage is a very low-level class that doesn't
|
|
||||||
// know about PStatClient.
|
|
||||||
|
|
||||||
#ifdef DO_MEMORY_USAGE
|
|
||||||
if (MemoryUsage::has_total_size()) {
|
|
||||||
_total_size_pcollector.set_level(MemoryUsage::get_total_size());
|
|
||||||
}
|
|
||||||
if (MemoryUsage::has_cpp_size()) {
|
|
||||||
_cpp_size_pcollector.set_level(MemoryUsage::get_cpp_size());
|
|
||||||
}
|
|
||||||
if (MemoryUsage::has_interpreter_size()) {
|
|
||||||
_interpreter_size_pcollector.set_level(MemoryUsage::get_interpreter_size());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
get_global_pstats()->client_main_tick();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::main_tick
|
|
||||||
// Access: Public, Static
|
|
||||||
// Description: A convenience function to call new_frame() on the
|
|
||||||
// the given client's main thread.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
client_main_tick() {
|
|
||||||
_clock.tick();
|
|
||||||
get_main_thread().new_frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::get_global_pstats
|
|
||||||
// Access: Public, Static
|
|
||||||
// Description: Returns a pointer to the global PStatClient object.
|
|
||||||
// It's legal to declare your own PStatClient locally,
|
|
||||||
// but it's also convenient to have a global one that
|
|
||||||
// everyone can register with. This is the global one.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
PStatClient *PStatClient::
|
|
||||||
get_global_pstats() {
|
|
||||||
if (_global_pstats == (PStatClient *)NULL) {
|
|
||||||
_global_pstats = new PStatClient;
|
|
||||||
}
|
|
||||||
return _global_pstats;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::client_connect
|
|
||||||
// Access: Private
|
|
||||||
// Description: The nonstatic implementation of connect().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool PStatClient::
|
|
||||||
client_connect(string hostname, int port) {
|
|
||||||
client_disconnect();
|
|
||||||
|
|
||||||
if (hostname.empty()) {
|
|
||||||
hostname = pstats_host;
|
|
||||||
}
|
|
||||||
if (port < 0) {
|
|
||||||
port = pstats_port;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_server.set_host(hostname, port)) {
|
|
||||||
pstats_cat.error()
|
|
||||||
<< "Unknown host: " << hostname << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
_tcp_connection = open_TCP_client_connection(_server, 5000);
|
|
||||||
|
|
||||||
if (_tcp_connection.is_null()) {
|
|
||||||
pstats_cat.error()
|
|
||||||
<< "Couldn't connect to PStatServer at " << hostname << ":"
|
|
||||||
<< port << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Make sure we're not queuing up multiple TCP sockets--we expect
|
|
||||||
// immediate writes of our TCP datagrams.
|
|
||||||
_tcp_connection->set_collect_tcp(false);
|
|
||||||
|
|
||||||
_reader.add_connection(_tcp_connection);
|
|
||||||
_is_connected = true;
|
|
||||||
|
|
||||||
_udp_connection = open_UDP_connection();
|
|
||||||
|
|
||||||
send_hello();
|
|
||||||
|
|
||||||
return _is_connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::client_disconnect
|
|
||||||
// Access: Private
|
|
||||||
// Description: The nonstatic implementation of disconnect().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
client_disconnect() {
|
|
||||||
if (_is_connected) {
|
|
||||||
_reader.remove_connection(_tcp_connection);
|
|
||||||
close_connection(_tcp_connection);
|
|
||||||
close_connection(_udp_connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
_tcp_connection.clear();
|
|
||||||
_udp_connection.clear();
|
|
||||||
|
|
||||||
_is_connected = false;
|
|
||||||
_got_udp_port = false;
|
|
||||||
|
|
||||||
_collectors_reported = 0;
|
|
||||||
_threads_reported = 0;
|
|
||||||
|
|
||||||
Threads::iterator ti;
|
|
||||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
|
||||||
(*ti)._frame_number = 0;
|
|
||||||
(*ti)._is_active = false;
|
|
||||||
(*ti)._next_packet = 0.0;
|
|
||||||
(*ti)._frame_data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
Collectors::iterator ci;
|
|
||||||
for (ci = _collectors.begin(); ci != _collectors.end(); ++ci) {
|
|
||||||
PerThread::iterator ii;
|
|
||||||
for (ii = (*ci)._per_thread.begin();
|
|
||||||
ii != (*ci)._per_thread.end();
|
|
||||||
++ii) {
|
|
||||||
(*ii)._nested_count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::client_is_connected
|
|
||||||
// Access: Public
|
|
||||||
// Description: The nonstatic implementation of is_connected().
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool PStatClient::
|
|
||||||
client_is_connected() const {
|
|
||||||
return _is_connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::client_resume_after_pause
|
|
||||||
// Access: Published
|
|
||||||
// Description: Resumes the PStatClient after the simulation has been
|
|
||||||
// paused for a while. This allows the stats to
|
|
||||||
// continue exactly where it left off, instead of
|
|
||||||
// leaving a big gap that would represent a chug.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
client_resume_after_pause() {
|
|
||||||
// Simply reset the clock to the beginning of the last frame. This
|
|
||||||
// may lose a frame, but on the other hand we won't skip a whole
|
|
||||||
// slew of frames either.
|
|
||||||
|
|
||||||
double frame_time = _clock.get_frame_time();
|
|
||||||
_clock.set_real_time(frame_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PStatClient::is_active
|
// Function: PStatClient::is_active
|
||||||
// Access: Private
|
// Access: Private
|
||||||
@ -572,7 +405,7 @@ is_active(int collector_index, int thread_index) const {
|
|||||||
nassertr(collector_index >= 0 && collector_index < (int)_collectors.size(), false);
|
nassertr(collector_index >= 0 && collector_index < (int)_collectors.size(), false);
|
||||||
nassertr(thread_index >= 0 && thread_index < (int)_threads.size(), false);
|
nassertr(thread_index >= 0 && thread_index < (int)_threads.size(), false);
|
||||||
|
|
||||||
return (_is_connected &&
|
return (client_is_connected() &&
|
||||||
_collectors[collector_index]._def->_is_active &&
|
_collectors[collector_index]._def->_is_active &&
|
||||||
_threads[thread_index]._is_active);
|
_threads[thread_index]._is_active);
|
||||||
}
|
}
|
||||||
@ -610,13 +443,14 @@ start(int collector_index, int thread_index) {
|
|||||||
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_collectors[collector_index]._def->_is_active &&
|
if (client_is_connected() &&
|
||||||
|
_collectors[collector_index]._def->_is_active &&
|
||||||
_threads[thread_index]._is_active) {
|
_threads[thread_index]._is_active) {
|
||||||
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
||||||
// This collector wasn't already started in this thread; record
|
// This collector wasn't already started in this thread; record
|
||||||
// a new data point.
|
// a new data point.
|
||||||
_threads[thread_index]._frame_data.add_start(collector_index,
|
_threads[thread_index]._frame_data.add_start(collector_index,
|
||||||
_clock.get_real_time());
|
get_clock().get_real_time());
|
||||||
}
|
}
|
||||||
_collectors[collector_index]._per_thread[thread_index]._nested_count++;
|
_collectors[collector_index]._per_thread[thread_index]._nested_count++;
|
||||||
}
|
}
|
||||||
@ -636,7 +470,8 @@ start(int collector_index, int thread_index, float as_of) {
|
|||||||
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_collectors[collector_index]._def->_is_active &&
|
if (client_is_connected() &&
|
||||||
|
_collectors[collector_index]._def->_is_active &&
|
||||||
_threads[thread_index]._is_active) {
|
_threads[thread_index]._is_active) {
|
||||||
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
||||||
// This collector wasn't already started in this thread; record
|
// This collector wasn't already started in this thread; record
|
||||||
@ -661,7 +496,8 @@ stop(int collector_index, int thread_index) {
|
|||||||
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_collectors[collector_index]._def->_is_active &&
|
if (client_is_connected() &&
|
||||||
|
_collectors[collector_index]._def->_is_active &&
|
||||||
_threads[thread_index]._is_active) {
|
_threads[thread_index]._is_active) {
|
||||||
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
||||||
pstats_cat.warning()
|
pstats_cat.warning()
|
||||||
@ -677,7 +513,7 @@ stop(int collector_index, int thread_index) {
|
|||||||
// This collector has now been completely stopped; record a new
|
// This collector has now been completely stopped; record a new
|
||||||
// data point.
|
// data point.
|
||||||
_threads[thread_index]._frame_data.add_stop(collector_index,
|
_threads[thread_index]._frame_data.add_stop(collector_index,
|
||||||
_clock.get_real_time());
|
get_clock().get_real_time());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,7 +532,8 @@ stop(int collector_index, int thread_index, float as_of) {
|
|||||||
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (_collectors[collector_index]._def->_is_active &&
|
if (client_is_connected() &&
|
||||||
|
_collectors[collector_index]._def->_is_active &&
|
||||||
_threads[thread_index]._is_active) {
|
_threads[thread_index]._is_active) {
|
||||||
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
|
||||||
pstats_cat.warning()
|
pstats_cat.warning()
|
||||||
@ -745,7 +582,7 @@ clear_level(int collector_index, int thread_index) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PStatClient::
|
void PStatClient::
|
||||||
set_level(int collector_index, int thread_index, float level) {
|
set_level(int collector_index, int thread_index, float level) {
|
||||||
if (_collectors[collector_index]._def->_is_active) {
|
if (client_is_connected() && _collectors[collector_index]._def->_is_active) {
|
||||||
level *= _collectors[collector_index]._def->_factor;
|
level *= _collectors[collector_index]._def->_factor;
|
||||||
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
|
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
|
||||||
_collectors[collector_index]._per_thread[thread_index]._level = level;
|
_collectors[collector_index]._per_thread[thread_index]._level = level;
|
||||||
@ -765,7 +602,7 @@ set_level(int collector_index, int thread_index, float level) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void PStatClient::
|
void PStatClient::
|
||||||
add_level(int collector_index, int thread_index, float increment) {
|
add_level(int collector_index, int thread_index, float increment) {
|
||||||
if (_collectors[collector_index]._def->_is_active) {
|
if (client_is_connected() && _collectors[collector_index]._def->_is_active) {
|
||||||
increment *= _collectors[collector_index]._def->_factor;
|
increment *= _collectors[collector_index]._def->_factor;
|
||||||
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
|
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
|
||||||
_collectors[collector_index]._per_thread[thread_index]._level += increment;
|
_collectors[collector_index]._per_thread[thread_index]._level += increment;
|
||||||
@ -786,291 +623,4 @@ get_level(int collector_index, int thread_index) const {
|
|||||||
_collectors[collector_index]._def->_factor;
|
_collectors[collector_index]._def->_factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::new_frame
|
|
||||||
// Access: Private
|
|
||||||
// Description: Called by the PStatThread interface at the beginning
|
|
||||||
// of every frame, for each thread. This resets the
|
|
||||||
// clocks for the new frame and transmits the data for
|
|
||||||
// the previous frame.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
new_frame(int thread_index) {
|
|
||||||
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
|
||||||
|
|
||||||
Thread &thread = _threads[thread_index];
|
|
||||||
|
|
||||||
// If we're the main thread, we should exchange control packets with
|
|
||||||
// the server.
|
|
||||||
if (thread_index == 0) {
|
|
||||||
transmit_control_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we've got the UDP port by the time the frame starts, it's
|
|
||||||
// time to become active and start actually tracking data.
|
|
||||||
if (_got_udp_port) {
|
|
||||||
thread._is_active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!thread._is_active) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float frame_start = _clock.get_real_time();
|
|
||||||
|
|
||||||
if (!thread._frame_data.is_empty()) {
|
|
||||||
// Collector 0 is the whole frame.
|
|
||||||
stop(0, thread_index, frame_start);
|
|
||||||
|
|
||||||
// Fill up the level data for all the collectors who have level
|
|
||||||
// data for this thread.
|
|
||||||
int num_collectors = _collectors.size();
|
|
||||||
for (int i = 0; i < num_collectors; i++) {
|
|
||||||
const PerThreadData &ptd = _collectors[i]._per_thread[thread_index];
|
|
||||||
if (ptd._has_level) {
|
|
||||||
thread._frame_data.add_level(i, ptd._level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
transmit_frame_data(thread_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
thread._frame_data.clear();
|
|
||||||
thread._frame_number++;
|
|
||||||
start(0, thread_index, frame_start);
|
|
||||||
|
|
||||||
// Also record the time for the PStats operation itself.
|
|
||||||
start(_pstats_pcollector.get_index(), thread_index, frame_start);
|
|
||||||
stop(_pstats_pcollector.get_index(), thread_index, _clock.get_real_time());
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::transmit_frame_data
|
|
||||||
// Access: Private
|
|
||||||
// Description: Should be called once per frame per thread to
|
|
||||||
// transmit the latest data to the PStatServer.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
transmit_frame_data(int thread_index) {
|
|
||||||
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
|
|
||||||
if (_is_connected && _threads[thread_index]._is_active) {
|
|
||||||
|
|
||||||
// We don't want to send too many packets in a hurry and flood the
|
|
||||||
// server. Check that enough time has elapsed for us to send a
|
|
||||||
// new packet. If not, we'll drop this packet on the floor and
|
|
||||||
// send a new one next time around.
|
|
||||||
float now = _clock.get_real_time();
|
|
||||||
if (now >= _threads[thread_index]._next_packet) {
|
|
||||||
// We don't want to send more than _max_rate UDP-size packets
|
|
||||||
// per second, per thread.
|
|
||||||
float packet_delay = 1.0 / _max_rate;
|
|
||||||
|
|
||||||
// Send new data.
|
|
||||||
NetDatagram datagram;
|
|
||||||
// We always start with a zero byte, to differentiate it from a
|
|
||||||
// control message.
|
|
||||||
datagram.add_uint8(0);
|
|
||||||
|
|
||||||
datagram.add_uint16(thread_index);
|
|
||||||
datagram.add_uint32(_threads[thread_index]._frame_number);
|
|
||||||
_threads[thread_index]._frame_data.write_datagram(datagram);
|
|
||||||
|
|
||||||
if (_writer.is_valid_for_udp(datagram)) {
|
|
||||||
if (_udp_count * _udp_count_factor < _tcp_count * _tcp_count_factor) {
|
|
||||||
// Send this one as a UDP packet.
|
|
||||||
nassertv(_got_udp_port);
|
|
||||||
_writer.send(datagram, _udp_connection, _server);
|
|
||||||
_udp_count++;
|
|
||||||
|
|
||||||
if (_udp_count == 0) {
|
|
||||||
// Wraparound!
|
|
||||||
_udp_count = 1;
|
|
||||||
_tcp_count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Send this one as a TCP packet.
|
|
||||||
_writer.send(datagram, _tcp_connection);
|
|
||||||
_tcp_count++;
|
|
||||||
|
|
||||||
if (_tcp_count == 0) {
|
|
||||||
// Wraparound!
|
|
||||||
_udp_count = 1;
|
|
||||||
_tcp_count = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_writer.send(datagram, _tcp_connection);
|
|
||||||
// If our packets are so large that we must ship them via TCP,
|
|
||||||
// then artificially slow down the packet rate even further.
|
|
||||||
int packet_ratio =
|
|
||||||
(datagram.get_length() + maximum_udp_datagram - 1) /
|
|
||||||
maximum_udp_datagram;
|
|
||||||
packet_delay *= (float)packet_ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
_threads[thread_index]._next_packet = now + packet_delay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::transmit_control_data
|
|
||||||
// Access: Private
|
|
||||||
// Description: Should be called once a frame to exchange control
|
|
||||||
// information with the server.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
transmit_control_data() {
|
|
||||||
// Check for new messages from the server.
|
|
||||||
while (_is_connected && _reader.data_available()) {
|
|
||||||
NetDatagram datagram;
|
|
||||||
|
|
||||||
if (_reader.get_data(datagram)) {
|
|
||||||
PStatServerControlMessage message;
|
|
||||||
if (message.decode(datagram)) {
|
|
||||||
handle_server_control_message(message);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
pstats_cat.error()
|
|
||||||
<< "Got unexpected message from server.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_is_connected) {
|
|
||||||
report_new_collectors();
|
|
||||||
report_new_threads();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::get_hostname
|
|
||||||
// Access: Private
|
|
||||||
// Description: Returns the current machine's hostname.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
string PStatClient::
|
|
||||||
get_hostname() {
|
|
||||||
if (_hostname.empty()) {
|
|
||||||
char temp_buff[1024];
|
|
||||||
if (gethostname(temp_buff, 1024) == 0) {
|
|
||||||
_hostname = temp_buff;
|
|
||||||
} else {
|
|
||||||
_hostname = "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::send_hello
|
|
||||||
// Access: Private
|
|
||||||
// Description: Sends the initial greeting message to the server.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
send_hello() {
|
|
||||||
nassertv(_is_connected);
|
|
||||||
|
|
||||||
PStatClientControlMessage message;
|
|
||||||
message._type = PStatClientControlMessage::T_hello;
|
|
||||||
message._client_hostname = get_hostname();
|
|
||||||
message._client_progname = _client_name;
|
|
||||||
message._major_version = get_current_pstat_major_version();
|
|
||||||
message._minor_version = get_current_pstat_minor_version();
|
|
||||||
|
|
||||||
Datagram datagram;
|
|
||||||
message.encode(datagram);
|
|
||||||
_writer.send(datagram, _tcp_connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::report_new_collectors
|
|
||||||
// Access: Private
|
|
||||||
// Description: Sends over any information about new Collectors that
|
|
||||||
// the user code might have recently created.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
report_new_collectors() {
|
|
||||||
nassertv(_is_connected);
|
|
||||||
|
|
||||||
if (_collectors_reported < (int)_collectors.size()) {
|
|
||||||
PStatClientControlMessage message;
|
|
||||||
message._type = PStatClientControlMessage::T_define_collectors;
|
|
||||||
while (_collectors_reported < (int)_collectors.size()) {
|
|
||||||
message._collectors.push_back(_collectors[_collectors_reported]._def);
|
|
||||||
_collectors_reported++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Datagram datagram;
|
|
||||||
message.encode(datagram);
|
|
||||||
_writer.send(datagram, _tcp_connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::report_new_threads
|
|
||||||
// Access: Private
|
|
||||||
// Description: Sends over any information about new Threads that
|
|
||||||
// the user code might have recently created.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
report_new_threads() {
|
|
||||||
nassertv(_is_connected);
|
|
||||||
|
|
||||||
if (_threads_reported < (int)_threads.size()) {
|
|
||||||
PStatClientControlMessage message;
|
|
||||||
message._type = PStatClientControlMessage::T_define_threads;
|
|
||||||
message._first_thread_index = _threads_reported;
|
|
||||||
while (_threads_reported < (int)_threads.size()) {
|
|
||||||
message._names.push_back(_threads[_threads_reported]._name);
|
|
||||||
_threads_reported++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Datagram datagram;
|
|
||||||
message.encode(datagram);
|
|
||||||
_writer.send(datagram, _tcp_connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::handle_server_control_message
|
|
||||||
// Access: Private
|
|
||||||
// Description: Called when a control message has been received by
|
|
||||||
// the server over the TCP connection.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
handle_server_control_message(const PStatServerControlMessage &message) {
|
|
||||||
switch (message._type) {
|
|
||||||
case PStatServerControlMessage::T_hello:
|
|
||||||
pstats_cat.info()
|
|
||||||
<< "Connected to " << message._server_progname << " on "
|
|
||||||
<< message._server_hostname << "\n";
|
|
||||||
|
|
||||||
_server.set_port(message._udp_port);
|
|
||||||
_got_udp_port = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
pstats_cat.error()
|
|
||||||
<< "Invalid control message received from server.\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: PStatClient::connection_reset
|
|
||||||
// Access: Private, Virtual
|
|
||||||
// Description: Called by the internal net code when the connection
|
|
||||||
// has been lost.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void PStatClient::
|
|
||||||
connection_reset(const PT(Connection) &connection, PRErrorCode) {
|
|
||||||
if (connection == _tcp_connection) {
|
|
||||||
disconnect();
|
|
||||||
} else {
|
|
||||||
pstats_cat.warning()
|
|
||||||
<< "Ignoring spurious connection_reset() message\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DO_PSTATS
|
#endif // DO_PSTATS
|
||||||
|
@ -22,19 +22,10 @@
|
|||||||
#include "pandabase.h"
|
#include "pandabase.h"
|
||||||
|
|
||||||
#include "pStatFrameData.h"
|
#include "pStatFrameData.h"
|
||||||
|
#include "pStatClientImpl.h"
|
||||||
#include "clockObject.h"
|
|
||||||
#include "luse.h"
|
#include "luse.h"
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
|
|
||||||
#ifdef HAVE_NET
|
|
||||||
#include "connectionManager.h"
|
|
||||||
#include "queuedConnectionReader.h"
|
|
||||||
#include "connectionWriter.h"
|
|
||||||
#include "netAddress.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class PStatServerControlMessage;
|
|
||||||
class PStatCollector;
|
class PStatCollector;
|
||||||
class PStatCollectorDef;
|
class PStatCollectorDef;
|
||||||
class PStatThread;
|
class PStatThread;
|
||||||
@ -62,25 +53,26 @@ public:
|
|||||||
PStatClient();
|
PStatClient();
|
||||||
~PStatClient();
|
~PStatClient();
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
INLINE void set_client_name(const string &name);
|
INLINE void set_client_name(const string &name);
|
||||||
INLINE string get_client_name() const;
|
INLINE string get_client_name() const;
|
||||||
INLINE void set_max_rate(float rate);
|
INLINE void set_max_rate(float rate);
|
||||||
INLINE float get_max_rate() const;
|
INLINE float get_max_rate() const;
|
||||||
|
|
||||||
int get_num_collectors() const;
|
INLINE int get_num_collectors() const;
|
||||||
PStatCollector get_collector(int index) const;
|
PStatCollector get_collector(int index) const;
|
||||||
const PStatCollectorDef &get_collector_def(int index) const;
|
const PStatCollectorDef &get_collector_def(int index) const;
|
||||||
string get_collector_name(int index) const;
|
string get_collector_name(int index) const;
|
||||||
string get_collector_fullname(int index) const;
|
string get_collector_fullname(int index) const;
|
||||||
|
|
||||||
int get_num_threads() const;
|
INLINE int get_num_threads() const;
|
||||||
PStatThread get_thread(int index) const;
|
PStatThread get_thread(int index) const;
|
||||||
string get_thread_name(int index) const;
|
INLINE string get_thread_name(int index) const;
|
||||||
|
|
||||||
const ClockObject &get_clock() const;
|
|
||||||
PStatThread get_main_thread() const;
|
PStatThread get_main_thread() const;
|
||||||
|
|
||||||
PUBLISHED:
|
INLINE const ClockObject &get_clock() const;
|
||||||
|
|
||||||
INLINE static bool connect(const string &hostname = string(), int port = -1);
|
INLINE static bool connect(const string &hostname = string(), int port = -1);
|
||||||
INLINE static void disconnect();
|
INLINE static void disconnect();
|
||||||
INLINE static bool is_connected();
|
INLINE static bool is_connected();
|
||||||
@ -89,17 +81,20 @@ PUBLISHED:
|
|||||||
|
|
||||||
static void main_tick();
|
static void main_tick();
|
||||||
|
|
||||||
public:
|
void client_main_tick();
|
||||||
|
INLINE bool client_connect(string hostname, int port);
|
||||||
|
void client_disconnect();
|
||||||
|
INLINE bool client_is_connected() const;
|
||||||
|
|
||||||
|
INLINE void client_resume_after_pause();
|
||||||
|
|
||||||
static PStatClient *get_global_pstats();
|
static PStatClient *get_global_pstats();
|
||||||
|
|
||||||
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:
|
private:
|
||||||
|
INLINE bool has_impl() const;
|
||||||
|
INLINE PStatClientImpl *get_impl();
|
||||||
|
INLINE const PStatClientImpl *get_impl() const;
|
||||||
|
|
||||||
PStatCollector make_collector_with_relname(int parent_index, string relname);
|
PStatCollector make_collector_with_relname(int parent_index, string relname);
|
||||||
PStatCollector make_collector_with_name(int parent_index, const string &name);
|
PStatCollector make_collector_with_name(int parent_index, const string &name);
|
||||||
PStatThread make_thread(const string &name);
|
PStatThread make_thread(const string &name);
|
||||||
@ -117,14 +112,6 @@ private:
|
|||||||
void add_level(int collector_index, int thread_index, float increment);
|
void add_level(int collector_index, int thread_index, float increment);
|
||||||
float get_level(int collector_index, int thread_index) const;
|
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;
|
|
||||||
|
|
||||||
// Not a phash_map, so the threads remain sorted by name.
|
// Not a phash_map, so the threads remain sorted by name.
|
||||||
typedef pmap<string, int> ThingsByName;
|
typedef pmap<string, int> ThingsByName;
|
||||||
ThingsByName _threads_by_name;
|
ThingsByName _threads_by_name;
|
||||||
@ -167,43 +154,18 @@ private:
|
|||||||
typedef pvector<Thread> Threads;
|
typedef pvector<Thread> Threads;
|
||||||
Threads _threads;
|
Threads _threads;
|
||||||
|
|
||||||
|
PStatClientImpl *_impl;
|
||||||
|
|
||||||
private:
|
static PStatCollector _total_size_pcollector;
|
||||||
// Networking stuff
|
static PStatCollector _cpp_size_pcollector;
|
||||||
string get_hostname();
|
static PStatCollector _interpreter_size_pcollector;
|
||||||
void send_hello();
|
static PStatCollector _pstats_pcollector;
|
||||||
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;
|
|
||||||
|
|
||||||
float _tcp_count_factor;
|
|
||||||
float _udp_count_factor;
|
|
||||||
unsigned int _tcp_count;
|
|
||||||
unsigned int _udp_count;
|
|
||||||
|
|
||||||
static PStatClient *_global_pstats;
|
static PStatClient *_global_pstats;
|
||||||
|
|
||||||
friend class PStatCollector;
|
friend class PStatCollector;
|
||||||
friend class PStatThread;
|
friend class PStatThread;
|
||||||
|
friend class PStatClientImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "pStatClient.I"
|
#include "pStatClient.I"
|
||||||
|
121
panda/src/pstatclient/pStatClientImpl.I
Normal file
121
panda/src/pstatclient/pStatClientImpl.I
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
// Filename: pStatClientImpl.I
|
||||||
|
// Created by: drose (23Dec04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::set_client_name
|
||||||
|
// Access: Public
|
||||||
|
// Description: Sets the name of the client. This is reported to the
|
||||||
|
// PStatsServer, and will presumably be written in the
|
||||||
|
// title bar or something.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void PStatClientImpl::
|
||||||
|
set_client_name(const string &name) {
|
||||||
|
_client_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::get_client_name
|
||||||
|
// Access: Public
|
||||||
|
// Description: Retrieves the name of the client as set.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE string PStatClientImpl::
|
||||||
|
get_client_name() const {
|
||||||
|
return _client_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::set_max_rate
|
||||||
|
// Access: Public
|
||||||
|
// Description: Controls the number of packets that will be sent to
|
||||||
|
// the server. Normally, one packet is sent per frame,
|
||||||
|
// but this can flood the server with more packets than
|
||||||
|
// it can handle if the frame rate is especially good
|
||||||
|
// (e.g. if nothing is onscreen at the moment). Set
|
||||||
|
// this parameter to a reasonable number to prevent this
|
||||||
|
// from happening.
|
||||||
|
//
|
||||||
|
// This number specifies the maximum number of packets
|
||||||
|
// that will be sent to the server per second, per
|
||||||
|
// thread.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void PStatClientImpl::
|
||||||
|
set_max_rate(float rate) {
|
||||||
|
_max_rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::get_max_rate
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns the maximum number of packets that will be
|
||||||
|
// sent to the server per second, per thread. See
|
||||||
|
// set_max_rate().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE float PStatClientImpl::
|
||||||
|
get_max_rate() const {
|
||||||
|
return _max_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::get_clock
|
||||||
|
// Access: Public
|
||||||
|
// Description: Returns a reference to the PStatClientImpl's clock
|
||||||
|
// object. It keeps its own clock, instead of using the
|
||||||
|
// global clock object, so the stats won't get mucked up
|
||||||
|
// if you put the global clock in non-real-time mode or
|
||||||
|
// something.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE const ClockObject &PStatClientImpl::
|
||||||
|
get_clock() const {
|
||||||
|
return _clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::client_main_tick
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called only by PStatClient::client_main_tick().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void PStatClientImpl::
|
||||||
|
client_main_tick() {
|
||||||
|
_clock.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::client_is_connected
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called only by PStatClient::client_is_connected().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool PStatClientImpl::
|
||||||
|
client_is_connected() const {
|
||||||
|
return _is_connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::client_resume_after_pause
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called only by PStatClient::client_resume_after_pause().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void PStatClientImpl::
|
||||||
|
client_resume_after_pause() {
|
||||||
|
// Simply reset the clock to the beginning of the last frame. This
|
||||||
|
// may lose a frame, but on the other hand we won't skip a whole
|
||||||
|
// slew of frames either.
|
||||||
|
|
||||||
|
double frame_time = _clock.get_frame_time();
|
||||||
|
_clock.set_real_time(frame_time);
|
||||||
|
}
|
448
panda/src/pstatclient/pStatClientImpl.cxx
Normal file
448
panda/src/pstatclient/pStatClientImpl.cxx
Normal file
@ -0,0 +1,448 @@
|
|||||||
|
// Filename: pStatClientImpl.cxx
|
||||||
|
// Created by: drose (23Dec04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "pStatClientImpl.h"
|
||||||
|
|
||||||
|
// This file only defines anything if DO_PSTATS is defined.
|
||||||
|
#ifdef DO_PSTATS
|
||||||
|
|
||||||
|
#include "pStatClient.h"
|
||||||
|
#include "pStatClientControlMessage.h"
|
||||||
|
#include "pStatServerControlMessage.h"
|
||||||
|
#include "pStatCollector.h"
|
||||||
|
#include "pStatThread.h"
|
||||||
|
#include "config_pstats.h"
|
||||||
|
#include "pStatProperties.h"
|
||||||
|
#include "cmath.h"
|
||||||
|
#include "mathNumbers.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef WIN32_VC
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PStatClientImpl::
|
||||||
|
PStatClientImpl(PStatClient *client) :
|
||||||
|
_client(client),
|
||||||
|
_reader(this, 0),
|
||||||
|
_writer(this, get_pstats_threaded_write() ? 1 : 0)
|
||||||
|
{
|
||||||
|
_is_connected = false;
|
||||||
|
_got_udp_port = false;
|
||||||
|
_collectors_reported = 0;
|
||||||
|
_threads_reported = 0;
|
||||||
|
|
||||||
|
// Make sure our clock is in "normal" mode.
|
||||||
|
_clock.set_mode(ClockObject::M_normal);
|
||||||
|
|
||||||
|
_client_name = get_pstats_name();
|
||||||
|
_max_rate = get_pstats_max_rate();
|
||||||
|
|
||||||
|
_tcp_count = 1;
|
||||||
|
_udp_count = 1;
|
||||||
|
|
||||||
|
double pstats_tcp_ratio = get_pstats_tcp_ratio();
|
||||||
|
|
||||||
|
if (pstats_tcp_ratio >= 1.0f) {
|
||||||
|
_tcp_count_factor = 0.0f;
|
||||||
|
_udp_count_factor = 1.0f;
|
||||||
|
|
||||||
|
} else if (pstats_tcp_ratio <= 0.0f) {
|
||||||
|
_tcp_count_factor = 1.0f;
|
||||||
|
_udp_count_factor = 0.0f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
csincos(pstats_tcp_ratio * MathNumbers::pi_f / 2.0f,
|
||||||
|
&_udp_count_factor,
|
||||||
|
&_tcp_count_factor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
PStatClientImpl::
|
||||||
|
~PStatClientImpl() {
|
||||||
|
nassertv(!_is_connected);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::client_connect
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called only by PStatClient::client_connect().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PStatClientImpl::
|
||||||
|
client_connect(string hostname, int port) {
|
||||||
|
nassertr(!_is_connected, true);
|
||||||
|
|
||||||
|
if (hostname.empty()) {
|
||||||
|
hostname = pstats_host;
|
||||||
|
}
|
||||||
|
if (port < 0) {
|
||||||
|
port = pstats_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_server.set_host(hostname, port)) {
|
||||||
|
pstats_cat.error()
|
||||||
|
<< "Unknown host: " << hostname << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tcp_connection = open_TCP_client_connection(_server, 5000);
|
||||||
|
|
||||||
|
if (_tcp_connection.is_null()) {
|
||||||
|
pstats_cat.error()
|
||||||
|
<< "Couldn't connect to PStatServer at " << hostname << ":"
|
||||||
|
<< port << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Make sure we're not queuing up multiple TCP sockets--we expect
|
||||||
|
// immediate writes of our TCP datagrams.
|
||||||
|
_tcp_connection->set_collect_tcp(false);
|
||||||
|
|
||||||
|
_reader.add_connection(_tcp_connection);
|
||||||
|
_is_connected = true;
|
||||||
|
|
||||||
|
_udp_connection = open_UDP_connection();
|
||||||
|
|
||||||
|
send_hello();
|
||||||
|
|
||||||
|
return _is_connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::client_disconnect
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called only by PStatClient::client_disconnect().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
client_disconnect() {
|
||||||
|
if (_is_connected) {
|
||||||
|
_reader.remove_connection(_tcp_connection);
|
||||||
|
close_connection(_tcp_connection);
|
||||||
|
close_connection(_udp_connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
_tcp_connection.clear();
|
||||||
|
_udp_connection.clear();
|
||||||
|
|
||||||
|
_is_connected = false;
|
||||||
|
_got_udp_port = false;
|
||||||
|
|
||||||
|
_collectors_reported = 0;
|
||||||
|
_threads_reported = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::new_frame
|
||||||
|
// Access: Public
|
||||||
|
// Description: Called by the PStatThread interface at the beginning
|
||||||
|
// of every frame, for each thread. This resets the
|
||||||
|
// clocks for the new frame and transmits the data for
|
||||||
|
// the previous frame.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
new_frame(int thread_index) {
|
||||||
|
nassertv(thread_index >= 0 && thread_index < (int)_client->_threads.size());
|
||||||
|
|
||||||
|
PStatClient::Thread &thread = _client->_threads[thread_index];
|
||||||
|
|
||||||
|
// If we're the main thread, we should exchange control packets with
|
||||||
|
// the server.
|
||||||
|
if (thread_index == 0) {
|
||||||
|
transmit_control_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've got the UDP port by the time the frame starts, it's
|
||||||
|
// time to become active and start actually tracking data.
|
||||||
|
if (_got_udp_port) {
|
||||||
|
thread._is_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!thread._is_active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float frame_start = _clock.get_real_time();
|
||||||
|
|
||||||
|
if (!thread._frame_data.is_empty()) {
|
||||||
|
// Collector 0 is the whole frame.
|
||||||
|
_client->stop(0, thread_index, frame_start);
|
||||||
|
|
||||||
|
// Fill up the level data for all the collectors who have level
|
||||||
|
// data for this thread.
|
||||||
|
int num_collectors = _client->_collectors.size();
|
||||||
|
for (int i = 0; i < num_collectors; i++) {
|
||||||
|
const PStatClient::PerThreadData &ptd =
|
||||||
|
_client->_collectors[i]._per_thread[thread_index];
|
||||||
|
if (ptd._has_level) {
|
||||||
|
thread._frame_data.add_level(i, ptd._level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
transmit_frame_data(thread_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
thread._frame_data.clear();
|
||||||
|
thread._frame_number++;
|
||||||
|
_client->start(0, thread_index, frame_start);
|
||||||
|
|
||||||
|
// Also record the time for the PStats operation itself.
|
||||||
|
int pstats_index = PStatClient::_pstats_pcollector.get_index();
|
||||||
|
_client->start(pstats_index, thread_index, frame_start);
|
||||||
|
_client->stop(pstats_index, thread_index, _clock.get_real_time());
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::transmit_frame_data
|
||||||
|
// Access: Private
|
||||||
|
// Description: Should be called once per frame per thread to
|
||||||
|
// transmit the latest data to the PStatServer.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
transmit_frame_data(int thread_index) {
|
||||||
|
nassertv(thread_index >= 0 && thread_index < (int)_client->_threads.size());
|
||||||
|
if (_is_connected && _client->_threads[thread_index]._is_active) {
|
||||||
|
|
||||||
|
// We don't want to send too many packets in a hurry and flood the
|
||||||
|
// server. Check that enough time has elapsed for us to send a
|
||||||
|
// new packet. If not, we'll drop this packet on the floor and
|
||||||
|
// send a new one next time around.
|
||||||
|
float now = _clock.get_real_time();
|
||||||
|
if (now >= _client->_threads[thread_index]._next_packet) {
|
||||||
|
// We don't want to send more than _max_rate UDP-size packets
|
||||||
|
// per second, per thread.
|
||||||
|
float packet_delay = 1.0 / _max_rate;
|
||||||
|
|
||||||
|
// Send new data.
|
||||||
|
NetDatagram datagram;
|
||||||
|
// We always start with a zero byte, to differentiate it from a
|
||||||
|
// control message.
|
||||||
|
datagram.add_uint8(0);
|
||||||
|
|
||||||
|
datagram.add_uint16(thread_index);
|
||||||
|
datagram.add_uint32(_client->_threads[thread_index]._frame_number);
|
||||||
|
_client->_threads[thread_index]._frame_data.write_datagram(datagram);
|
||||||
|
|
||||||
|
if (_writer.is_valid_for_udp(datagram)) {
|
||||||
|
if (_udp_count * _udp_count_factor < _tcp_count * _tcp_count_factor) {
|
||||||
|
// Send this one as a UDP packet.
|
||||||
|
nassertv(_got_udp_port);
|
||||||
|
_writer.send(datagram, _udp_connection, _server);
|
||||||
|
_udp_count++;
|
||||||
|
|
||||||
|
if (_udp_count == 0) {
|
||||||
|
// Wraparound!
|
||||||
|
_udp_count = 1;
|
||||||
|
_tcp_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Send this one as a TCP packet.
|
||||||
|
_writer.send(datagram, _tcp_connection);
|
||||||
|
_tcp_count++;
|
||||||
|
|
||||||
|
if (_tcp_count == 0) {
|
||||||
|
// Wraparound!
|
||||||
|
_udp_count = 1;
|
||||||
|
_tcp_count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_writer.send(datagram, _tcp_connection);
|
||||||
|
// If our packets are so large that we must ship them via TCP,
|
||||||
|
// then artificially slow down the packet rate even further.
|
||||||
|
int packet_ratio =
|
||||||
|
(datagram.get_length() + maximum_udp_datagram - 1) /
|
||||||
|
maximum_udp_datagram;
|
||||||
|
packet_delay *= (float)packet_ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
_client->_threads[thread_index]._next_packet = now + packet_delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::transmit_control_data
|
||||||
|
// Access: Private
|
||||||
|
// Description: Should be called once a frame to exchange control
|
||||||
|
// information with the server.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
transmit_control_data() {
|
||||||
|
// Check for new messages from the server.
|
||||||
|
while (_is_connected && _reader.data_available()) {
|
||||||
|
NetDatagram datagram;
|
||||||
|
|
||||||
|
if (_reader.get_data(datagram)) {
|
||||||
|
PStatServerControlMessage message;
|
||||||
|
if (message.decode(datagram)) {
|
||||||
|
handle_server_control_message(message);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
pstats_cat.error()
|
||||||
|
<< "Got unexpected message from server.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_is_connected) {
|
||||||
|
report_new_collectors();
|
||||||
|
report_new_threads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::get_hostname
|
||||||
|
// Access: Private
|
||||||
|
// Description: Returns the current machine's hostname.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
string PStatClientImpl::
|
||||||
|
get_hostname() {
|
||||||
|
if (_hostname.empty()) {
|
||||||
|
char temp_buff[1024];
|
||||||
|
if (gethostname(temp_buff, 1024) == 0) {
|
||||||
|
_hostname = temp_buff;
|
||||||
|
} else {
|
||||||
|
_hostname = "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::send_hello
|
||||||
|
// Access: Private
|
||||||
|
// Description: Sends the initial greeting message to the server.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
send_hello() {
|
||||||
|
nassertv(_is_connected);
|
||||||
|
|
||||||
|
PStatClientControlMessage message;
|
||||||
|
message._type = PStatClientControlMessage::T_hello;
|
||||||
|
message._client_hostname = get_hostname();
|
||||||
|
message._client_progname = _client_name;
|
||||||
|
message._major_version = get_current_pstat_major_version();
|
||||||
|
message._minor_version = get_current_pstat_minor_version();
|
||||||
|
|
||||||
|
Datagram datagram;
|
||||||
|
message.encode(datagram);
|
||||||
|
_writer.send(datagram, _tcp_connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::report_new_collectors
|
||||||
|
// Access: Private
|
||||||
|
// Description: Sends over any information about new Collectors that
|
||||||
|
// the user code might have recently created.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
report_new_collectors() {
|
||||||
|
nassertv(_is_connected);
|
||||||
|
|
||||||
|
if (_collectors_reported < (int)_client->_collectors.size()) {
|
||||||
|
PStatClientControlMessage message;
|
||||||
|
message._type = PStatClientControlMessage::T_define_collectors;
|
||||||
|
while (_collectors_reported < (int)_client->_collectors.size()) {
|
||||||
|
message._collectors.push_back(_client->_collectors[_collectors_reported]._def);
|
||||||
|
_collectors_reported++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Datagram datagram;
|
||||||
|
message.encode(datagram);
|
||||||
|
_writer.send(datagram, _tcp_connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::report_new_threads
|
||||||
|
// Access: Private
|
||||||
|
// Description: Sends over any information about new Threads that
|
||||||
|
// the user code might have recently created.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
report_new_threads() {
|
||||||
|
nassertv(_is_connected);
|
||||||
|
|
||||||
|
if (_threads_reported < (int)_client->_threads.size()) {
|
||||||
|
PStatClientControlMessage message;
|
||||||
|
message._type = PStatClientControlMessage::T_define_threads;
|
||||||
|
message._first_thread_index = _threads_reported;
|
||||||
|
while (_threads_reported < (int)_client->_threads.size()) {
|
||||||
|
message._names.push_back(_client->_threads[_threads_reported]._name);
|
||||||
|
_threads_reported++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Datagram datagram;
|
||||||
|
message.encode(datagram);
|
||||||
|
_writer.send(datagram, _tcp_connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::handle_server_control_message
|
||||||
|
// Access: Private
|
||||||
|
// Description: Called when a control message has been received by
|
||||||
|
// the server over the TCP connection.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
handle_server_control_message(const PStatServerControlMessage &message) {
|
||||||
|
switch (message._type) {
|
||||||
|
case PStatServerControlMessage::T_hello:
|
||||||
|
pstats_cat.info()
|
||||||
|
<< "Connected to " << message._server_progname << " on "
|
||||||
|
<< message._server_hostname << "\n";
|
||||||
|
|
||||||
|
_server.set_port(message._udp_port);
|
||||||
|
_got_udp_port = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pstats_cat.error()
|
||||||
|
<< "Invalid control message received from server.\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PStatClientImpl::connection_reset
|
||||||
|
// Access: Private, Virtual
|
||||||
|
// Description: Called by the internal net code when the connection
|
||||||
|
// has been lost.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void PStatClientImpl::
|
||||||
|
connection_reset(const PT(Connection) &connection, PRErrorCode) {
|
||||||
|
if (connection == _tcp_connection) {
|
||||||
|
_client->client_disconnect();
|
||||||
|
} else {
|
||||||
|
pstats_cat.warning()
|
||||||
|
<< "Ignoring spurious connection_reset() message\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // DO_PSTATS
|
129
panda/src/pstatclient/pStatClientImpl.h
Normal file
129
panda/src/pstatclient/pStatClientImpl.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// Filename: pStatClientImpl.h
|
||||||
|
// Created by: drose (23Dec04)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001 - 2004, 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://etc.cmu.edu/panda3d/docs/license/ .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d-general@lists.sourceforge.net .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef PSTATCLIENTIMPL_H
|
||||||
|
#define PSTATCLIENTIMPL_H
|
||||||
|
|
||||||
|
#include "pandabase.h"
|
||||||
|
|
||||||
|
// This class doesn't exist at all unless DO_PSTATS is defined.
|
||||||
|
#ifdef DO_PSTATS
|
||||||
|
|
||||||
|
#include "pStatFrameData.h"
|
||||||
|
#include "connectionManager.h"
|
||||||
|
#include "queuedConnectionReader.h"
|
||||||
|
#include "connectionWriter.h"
|
||||||
|
#include "netAddress.h"
|
||||||
|
|
||||||
|
#include "clockObject.h"
|
||||||
|
#include "luse.h"
|
||||||
|
#include "pmap.h"
|
||||||
|
|
||||||
|
class PStatClient;
|
||||||
|
class PStatServerControlMessage;
|
||||||
|
class PStatCollector;
|
||||||
|
class PStatCollectorDef;
|
||||||
|
class PStatThread;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : PStatClientImpl
|
||||||
|
// Description : This class is the implementation of the actual
|
||||||
|
// PStatClient class (which is just for interface). All
|
||||||
|
// of the stuff to manage sending stats up to the server
|
||||||
|
// is handled by this class.
|
||||||
|
//
|
||||||
|
// This separation between PStatClient and
|
||||||
|
// PStatClientImpl allows the global PStatClient to be
|
||||||
|
// constructed at static init time, without having to
|
||||||
|
// consult any config variables at that time. We don't
|
||||||
|
// actually do any real work until someone explicitly
|
||||||
|
// calls PStatClient::connect().
|
||||||
|
//
|
||||||
|
// This class doesn't exist at all unless DO_PSTATS is
|
||||||
|
// defined.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDA PStatClientImpl : public ConnectionManager {
|
||||||
|
public:
|
||||||
|
PStatClientImpl(PStatClient *client);
|
||||||
|
~PStatClientImpl();
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
INLINE const ClockObject &get_clock() const;
|
||||||
|
|
||||||
|
INLINE void client_main_tick();
|
||||||
|
bool client_connect(string hostname, int port);
|
||||||
|
void client_disconnect();
|
||||||
|
INLINE bool client_is_connected() const;
|
||||||
|
|
||||||
|
INLINE void client_resume_after_pause();
|
||||||
|
|
||||||
|
void new_frame(int thread_index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void transmit_frame_data(int thread_index);
|
||||||
|
|
||||||
|
void transmit_control_data();
|
||||||
|
|
||||||
|
// Stats collecting stuff
|
||||||
|
ClockObject _clock;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
PStatClient *_client;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
float _tcp_count_factor;
|
||||||
|
float _udp_count_factor;
|
||||||
|
unsigned int _tcp_count;
|
||||||
|
unsigned int _udp_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "pStatClientImpl.I"
|
||||||
|
|
||||||
|
#endif // DO_PSTATS
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -99,6 +99,6 @@ operator = (const PStatThread ©) {
|
|||||||
INLINE void PStatThread::
|
INLINE void PStatThread::
|
||||||
new_frame() {
|
new_frame() {
|
||||||
#ifdef DO_PSTATS
|
#ifdef DO_PSTATS
|
||||||
_client->new_frame(_index);
|
_client->get_impl()->new_frame(_index);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#include "config_pstats.cxx"
|
#include "config_pstats.cxx"
|
||||||
#include "pStatClient.cxx"
|
#include "pStatClient.cxx"
|
||||||
|
#include "pStatClientImpl.cxx"
|
||||||
#include "pStatClientVersion.cxx"
|
#include "pStatClientVersion.cxx"
|
||||||
#include "pStatClientControlMessage.cxx"
|
#include "pStatClientControlMessage.cxx"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user