Add pstats timing of wrt calls

This commit is contained in:
David Rose 2001-05-21 23:49:53 +00:00
parent 86869cf402
commit 866507bb17
24 changed files with 379 additions and 92 deletions

View File

@ -4,7 +4,7 @@
#begin lib_target
#define TARGET graph
#define LOCAL_LIBS \
putil mathutil
pstatclient putil mathutil
#define SOURCES \
allAttributesWrapper.I allAttributesWrapper.T \

View File

@ -392,7 +392,6 @@ cached_wrt_base(const Node *from,
InputIterator2 to_arcs_begin, InputIterator2 to_arcs_end,
TransitionWrapper &result,
TypeHandle graph_type) {
UpdateSeq now = last_graph_update(graph_type);
TransitionWrapper net_from_trans = TransitionWrapper::init_from(result);
@ -506,6 +505,8 @@ wrt_base(const Node *from,
InputIterator2 to_arcs_begin, InputIterator2 to_arcs_end,
TransitionWrapper &result,
TypeHandle graph_type) {
PStatTimer timer(_wrt_pcollector);
#ifndef NDEBUG
if (!cache_wrt) {
uncached_wrt_base(from, from_arcs_begin, from_arcs_end,
@ -874,6 +875,8 @@ template<class TransitionWrapper>
INLINE_GRAPH Node *
wrt_subtree(NodeRelation *arc, Node *to, UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &result, TypeHandle graph_type) {
PStatTimer timer(_wrt_subtree_pcollector);
#ifndef NDEBUG
if (!cache_wrt) {
// If we aren't caching wrt, compute it explicitly.

View File

@ -5,6 +5,7 @@
#include "wrt.h"
// There's no real need to have this file, but it's sometimes a little
// cleaner to guarantee that every .h file gets scanned when this
// directory is built.
#ifndef CPPPARSER
PStatCollector _wrt_pcollector("WRT");
PStatCollector _wrt_subtree_pcollector("WRT:subtree");
#endif

View File

@ -13,6 +13,8 @@
#include "config_graph.h"
#include <typedObject.h>
#include <pStatCollector.h>
#include <pStatTimer.h>
class Node;
@ -127,6 +129,9 @@ INLINE_GRAPH Node *
wrt_subtree(NodeRelation *arc, Node *to, UpdateSeq as_of, UpdateSeq now,
TransitionWrapper &result, TypeHandle graph_type);
// This is used to count the amount of time spend in calls to wrt().
extern EXPCL_PANDA PStatCollector _wrt_pcollector;
extern EXPCL_PANDA PStatCollector _wrt_subtree_pcollector;
#ifndef DONT_INLINE_GRAPH
#include "wrt.I"

View File

@ -304,7 +304,7 @@ set_planes() {
// transforming it with a -1 matrix. We do this by ensuring that
// the centroid is in front of all of the planes (actually, we only
// need to test the first plane).
if (_planes[0].dist_to_plane(_centroid) >= 0) {
if (_planes[0].dist_to_plane(_centroid) > 0) {
// Oops! We're flipped! Rebuild the planes in the opposite
// direction.
_planes[0] = Planef(_points[0], _points[2], _points[3]);

View File

@ -111,6 +111,7 @@ send(const Datagram &datagram, const PT(Connection) &connection) {
}
}
////////////////////////////////////////////////////////////////////
// Function: ConnectionWriter::send
// Access: Public
@ -158,6 +159,17 @@ send(const Datagram &datagram, const PT(Connection) &connection,
}
}
////////////////////////////////////////////////////////////////////
// Function: ConnectionWriter::is_valid_for_udp
// Access: Public
// Description: Returns true if the datagram is small enough to be
// sent over a UDP packet, false otherwise.
////////////////////////////////////////////////////////////////////
bool ConnectionWriter::
is_valid_for_udp(const Datagram &datagram) const {
return (int)datagram.get_length() <= maximum_udp_datagram;
}
////////////////////////////////////////////////////////////////////
// Function: ConnectionWriter::get_manager
// Access: Public

View File

@ -41,6 +41,8 @@ PUBLISHED:
const PT(Connection) &connection,
const NetAddress &address);
bool is_valid_for_udp(const Datagram &datagram) const;
ConnectionManager *get_manager() const;
bool is_immediate() const;
int get_num_threads() const;

View File

@ -9,7 +9,9 @@
#define SOURCES \
config_pstats.cxx config_pstats.h pStatClient.I pStatClient.cxx \
pStatClient.h pStatClientControlMessage.cxx \
pStatClient.h \
pStatClientVersion.I pStatClientVersion.cxx pStatClientVersion.h \
pStatClientControlMessage.cxx \
pStatClientControlMessage.h \
pStatCollector.I pStatCollector.h \
pStatCollectorDef.cxx \
@ -22,6 +24,7 @@
#define INSTALL_HEADERS \
config_pstats.h pStatClient.I pStatClient.h \
pStatClientVersion.I pStatClientVersion.h \
pStatClientControlMessage.h pStatCollector.I pStatCollector.h \
pStatCollectorDef.h pStatFrameData.I pStatFrameData.h \
pStatProperties.h \

View File

@ -7,7 +7,7 @@
#include <dconfig.h>
Configure(config_pstats);
ConfigureDef(config_pstats);
NotifyCategoryDef(pstats, "");
ConfigureFn(config_pstats) {

View File

@ -9,9 +9,11 @@
#include <pandabase.h>
#include <notifyCategoryProxy.h>
#include <dconfig.h>
// Configure variables for pstats package.
ConfigureDecl(config_pstats, EXPCL_PANDA, EXPTP_PANDA);
NotifyCategoryDecl(pstats, EXPCL_PANDA, EXPTP_PANDA);
extern EXPCL_PANDA string get_pstats_name();

View File

@ -325,7 +325,7 @@ make_thread(const string &name) {
Thread thread;
thread._name = name;
thread._is_active = false;
thread._last_packet = 0.0;
thread._next_packet = 0.0;
thread._frame_number = 0;
_threads.push_back(thread);
@ -435,7 +435,7 @@ ns_disconnect() {
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
(*ti)._frame_number = 0;
(*ti)._is_active = false;
(*ti)._last_packet = 0.0;
(*ti)._next_packet = 0.0;
(*ti)._frame_data.clear();
}
@ -472,7 +472,8 @@ start(int collector_index, int thread_index, float as_of) {
nassertv(collector_index >= 0 && collector_index < (int)_collectors.size());
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
if (_threads[thread_index]._is_active) {
if (_collectors[collector_index]._def->_is_active &&
_threads[thread_index]._is_active) {
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
// This collector wasn't already started in this thread; record
// a new data point.
@ -494,7 +495,8 @@ stop(int collector_index, int thread_index, float as_of) {
nassertv(collector_index >= 0 && collector_index < (int)_collectors.size());
nassertv(thread_index >= 0 && thread_index < (int)_threads.size());
if (_threads[thread_index]._is_active) {
if (_collectors[collector_index]._def->_is_active &&
_threads[thread_index]._is_active) {
if (_collectors[collector_index]._per_thread[thread_index]._nested_count == 0) {
pstats_cat.warning()
<< "Collector " << get_collector_fullname(collector_index)
@ -525,8 +527,11 @@ stop(int collector_index, int thread_index, float as_of) {
////////////////////////////////////////////////////////////////////
void PStatClient::
clear_level(int collector_index, int thread_index) {
_collectors[collector_index]._per_thread[thread_index]._has_level = false;
_collectors[collector_index]._per_thread[thread_index]._level = 0.0;
if (_collectors[collector_index]._def->_is_active &&
_threads[thread_index]._is_active) {
_collectors[collector_index]._per_thread[thread_index]._has_level = false;
_collectors[collector_index]._per_thread[thread_index]._level = 0.0;
}
}
////////////////////////////////////////////////////////////////////
@ -540,9 +545,12 @@ clear_level(int collector_index, int thread_index) {
////////////////////////////////////////////////////////////////////
void PStatClient::
set_level(int collector_index, int thread_index, float level) {
level *= _collectors[collector_index]._def->_factor;
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
_collectors[collector_index]._per_thread[thread_index]._level = level;
if (_collectors[collector_index]._def->_is_active &&
_threads[thread_index]._is_active) {
level *= _collectors[collector_index]._def->_factor;
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
_collectors[collector_index]._per_thread[thread_index]._level = level;
}
}
////////////////////////////////////////////////////////////////////
@ -558,9 +566,12 @@ set_level(int collector_index, int thread_index, float level) {
////////////////////////////////////////////////////////////////////
void PStatClient::
add_level(int collector_index, int thread_index, float increment) {
increment *= _collectors[collector_index]._def->_factor;
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
_collectors[collector_index]._per_thread[thread_index]._level += increment;
if (_collectors[collector_index]._def->_is_active &&
_threads[thread_index]._is_active) {
increment *= _collectors[collector_index]._def->_factor;
_collectors[collector_index]._per_thread[thread_index]._has_level = true;
_collectors[collector_index]._per_thread[thread_index]._level += increment;
}
}
////////////////////////////////////////////////////////////////////
@ -626,23 +637,42 @@ 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. In fact, we don't want to send more than
// _max_rate packets per second, per thread.
float min_packet_delay = 1.0 / _max_rate;
float now = _clock.get_real_time();
if (now - _threads[thread_index]._last_packet > min_packet_delay) {
nassertv(_got_udp_port);
// 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 into the void 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);
_writer.send(datagram, _udp_connection, _server);
_threads[thread_index]._last_packet = now;
if (_writer.is_valid_for_udp(datagram)) {
nassertv(_got_udp_port);
_writer.send(datagram, _udp_connection, _server);
} 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;
}
}
}

View File

@ -127,7 +127,7 @@ private:
PStatFrameData _frame_data;
bool _is_active;
int _frame_number;
float _last_packet;
float _next_packet;
};
typedef vector<Thread> Threads;
Threads _threads;

View File

@ -5,6 +5,7 @@
#include "config_pstats.h"
#include "pStatClientControlMessage.h"
#include "pStatClientVersion.h"
#include <datagram.h>
#include <datagramIterator.h>
@ -68,7 +69,7 @@ encode(Datagram &datagram) const {
// Returns true on success, false on error.
////////////////////////////////////////////////////////////////////
bool PStatClientControlMessage::
decode(const Datagram &datagram) {
decode(const Datagram &datagram, PStatClientVersion *version) {
DatagramIterator source(datagram);
_type = (Type)source.get_uint8();
@ -91,7 +92,7 @@ decode(const Datagram &datagram) {
_collectors.clear();
for (int i = 0; i < num; i++) {
PStatCollectorDef *def = new PStatCollectorDef;
def->read_datagram(source);
def->read_datagram(source, version);
_collectors.push_back(def);
}
}
@ -108,6 +109,10 @@ decode(const Datagram &datagram) {
}
break;
case T_datagram:
// Not, strictly speaking, a control message.
return false;
default:
pstats_cat.error()
<< "Read invalid PStatClientControlMessage type: " << (int)_type << "\n";

View File

@ -13,6 +13,7 @@
#include <vector>
class Datagram;
class PStatClientVersion;
////////////////////////////////////////////////////////////////////
// Class : PStatClientControlMessage
@ -25,13 +26,14 @@ public:
PStatClientControlMessage();
void encode(Datagram &datagram) const;
bool decode(const Datagram &datagram);
bool decode(const Datagram &datagram, PStatClientVersion *version);
enum Type {
T_invalid,
T_datagram = 0,
T_hello,
T_define_collectors,
T_define_threads,
T_invalid
};
Type _type;

View File

@ -0,0 +1,49 @@
// Filename: pStatClientVersion.I
// Created by: drose (21May01)
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: PStatClientVersion::get_major_version
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int PStatClientVersion::
get_major_version() const {
return _major_version;
}
////////////////////////////////////////////////////////////////////
// Function: PStatClientVersion::get_minor_version
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int PStatClientVersion::
get_minor_version() const {
return _minor_version;
}
////////////////////////////////////////////////////////////////////
// Function: PStatClientVersion::set_version
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void PStatClientVersion::
set_version(int major, int minor) {
_major_version = major;
_minor_version = minor;
}
////////////////////////////////////////////////////////////////////
// Function: PStatClientVersion::is_at_least
// Access: Public
// Description: Returns true if the client version is at least the
// indicated major/minor version number, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool PStatClientVersion::
is_at_least(int major, int minor) const {
return (_major_version > major ||
(_major_version == major && _minor_version >= minor));
}

View File

@ -0,0 +1,19 @@
// Filename: pStatClientVersion.cxx
// Created by: drose (21May01)
//
////////////////////////////////////////////////////////////////////
#include "pStatClientVersion.h"
#include "pStatProperties.h"
////////////////////////////////////////////////////////////////////
// Function: PStatClientVersion::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PStatClientVersion::
PStatClientVersion() {
_major_version = get_current_pstat_major_version();
_minor_version = get_current_pstat_minor_version();
}

View File

@ -0,0 +1,39 @@
// Filename: pStatClientVersion.h
// Created by: drose (21May01)
//
////////////////////////////////////////////////////////////////////
#ifndef PSTATCLIENTVERSION_H
#define PSTATCLIENTVERSION_H
#include <pandabase.h>
#include <referenceCount.h>
#include <pointerTo.h>
////////////////////////////////////////////////////////////////////
// Class : PStatClientVersion
// Description : Records the version number of a particular client.
// Normally this will be the same as
// get_current_pstat_major/minor_version().
////////////////////////////////////////////////////////////////////
class PStatClientVersion : public ReferenceCount {
public:
PStatClientVersion();
INLINE int get_major_version() const;
INLINE int get_minor_version() const;
INLINE void set_version(int major, int minor);
INLINE bool is_at_least(int major, int minor) const;
private:
int _major_version;
int _minor_version;
};
#include "pStatClientVersion.I"
#endif

View File

@ -22,6 +22,7 @@ PStatCollectorDef() {
_sort = -1;
_suggested_scale = 0.0;
_factor = 1.0;
_is_active = true;
}
////////////////////////////////////////////////////////////////////
@ -39,6 +40,7 @@ PStatCollectorDef(int index, const string &name) :
_sort = -1;
_suggested_scale = 0.0;
_factor = 1.0;
_is_active = true;
}
////////////////////////////////////////////////////////////////////
@ -55,6 +57,7 @@ set_parent(const PStatCollectorDef &parent) {
_level_units = parent._level_units;
_suggested_scale = parent._suggested_scale;
_factor = parent._factor;
_is_active = parent._is_active;
}
////////////////////////////////////////////////////////////////////
@ -81,7 +84,7 @@ write_datagram(Datagram &destination) const {
// Description: Extracts the collectorDef definition from the datagram.
////////////////////////////////////////////////////////////////////
void PStatCollectorDef::
read_datagram(DatagramIterator &source) {
read_datagram(DatagramIterator &source, PStatClientVersion *) {
_index = source.get_int16();
_name = source.get_string();
_parent_index = source.get_int16();

View File

@ -13,6 +13,7 @@
class Datagram;
class DatagramIterator;
class PStatClient;
class PStatClientVersion;
////////////////////////////////////////////////////////////////////
// Class : PStatCollectorDef
@ -26,7 +27,7 @@ public:
void set_parent(const PStatCollectorDef &parent);
void write_datagram(Datagram &destination) const;
void read_datagram(DatagramIterator &source);
void read_datagram(DatagramIterator &source, PStatClientVersion *version);
int _index;
string _name;
@ -36,6 +37,7 @@ public:
string _level_units;
float _suggested_scale;
float _factor;
bool _is_active;
};
#endif

View File

@ -4,6 +4,7 @@
////////////////////////////////////////////////////////////////////
#include "pStatFrameData.h"
#include "pStatClientVersion.h"
#include <datagram.h>
#include <datagramIterator.h>
@ -35,7 +36,7 @@ write_datagram(Datagram &destination) const {
// Description: Extracts the FrameData definition from the datagram.
////////////////////////////////////////////////////////////////////
void PStatFrameData::
read_datagram(DatagramIterator &source) {
read_datagram(DatagramIterator &source, PStatClientVersion *) {
clear();
int i;

View File

@ -14,6 +14,7 @@
class Datagram;
class DatagramIterator;
class PStatClientVersion;
////////////////////////////////////////////////////////////////////
// Class : PStatFrameData
@ -47,7 +48,7 @@ public:
INLINE float get_level(int n) const;
void write_datagram(Datagram &destination) const;
void read_datagram(DatagramIterator &source);
void read_datagram(DatagramIterator &source, PStatClientVersion *version);
private:
class DataPoint {

View File

@ -6,6 +6,14 @@
#include "pStatProperties.h"
#include "pStatCollectorDef.h"
#include "pStatClient.h"
#include "config_pstats.h"
#include <ctype.h>
static const int current_pstat_major_version = 2;
static const int current_pstat_minor_version = 1;
// Initialized at 2.0 on 5/18/01, when version numbers were first added.
// Incremented to 2.1 on 5/21/01 to add support for TCP frame data.
////////////////////////////////////////////////////////////////////
// Function: get_current_pstat_major_version
@ -19,7 +27,7 @@
////////////////////////////////////////////////////////////////////
int
get_current_pstat_major_version() {
return 2;
return current_pstat_major_version;
}
////////////////////////////////////////////////////////////////////
@ -34,7 +42,7 @@ get_current_pstat_major_version() {
////////////////////////////////////////////////////////////////////
int
get_current_pstat_minor_version() {
return 0;
return current_pstat_minor_version;
}
@ -67,12 +75,14 @@ struct ColorDef {
};
struct TimeCollectorProperties {
bool is_active;
const char *name;
ColorDef color;
float suggested_scale;
};
struct LevelCollectorProperties {
bool is_active;
const char *name;
ColorDef color;
const char *units;
@ -81,57 +91,50 @@ struct LevelCollectorProperties {
};
static TimeCollectorProperties time_properties[] = {
{ "App", { 0.0, 1.0, 1.0 }, 1.0 / 30.0 },
{ "App:Animation", { 1.0, 0.0, 1.0 } },
{ "App:Collisions", { 1.0, 0.5, 0.0 } },
{ "App:Data graph", { 0.5, 0.8, 0.4 } },
{ "App:Show code", { 0.8, 0.2, 1.0 } },
{ "Cull", { 0.0, 1.0, 0.0 }, 1.0 / 30.0 },
{ "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 },
{ "Draw:Swap buffers", { 0.5, 1.0, 0.8 } },
{ "Draw:Clear", { 0.5, 0.7, 0.7 } },
{ "Draw:Show fps", { 0.5, 0.8, 1.0 } },
{ "Draw:Make current", { 1.0, 0.6, 0.3 } },
{ NULL }
{ 1, "App", { 0.0, 1.0, 1.0 }, 1.0 / 30.0 },
{ 1, "App:Animation", { 1.0, 0.0, 1.0 } },
{ 1, "App:Collisions", { 1.0, 0.5, 0.0 } },
{ 1, "App:Data graph", { 0.5, 0.8, 0.4 } },
{ 1, "App:Show code", { 0.8, 0.2, 1.0 } },
{ 1, "Cull", { 0.0, 1.0, 0.0 }, 1.0 / 30.0 },
{ 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 },
{ 1, "Draw:Swap buffers", { 0.5, 1.0, 0.8 } },
{ 1, "Draw:Clear", { 0.5, 0.7, 0.7 } },
{ 1, "Draw:Show fps", { 0.5, 0.8, 1.0 } },
{ 1, "Draw:Make current", { 1.0, 0.6, 0.3 } },
{ 0, "WRT", { 0.0, 0.0, 1.0 } },
{ 0, "WRT:Subtree", { 0.3, 1.0, 0.3 } },
{ 0, NULL }
};
static LevelCollectorProperties level_properties[] = {
{ "Texture usage", { 1.0, 0.0, 0.0 }, "MB", 12, 1048576 },
{ "Texture usage:Active", { 1.0, 1.0, 0.0 } },
{ "Texture memory", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
{ "Texture memory:In use", { 0.0, 1.0, 1.0 } },
{ "Vertices", { 0.5, 0.2, 0.0 }, "K", 10, 1000 },
{ "Vertices:Other", { 0.2, 0.2, 0.2 } },
{ "Vertices:Triangles", { 0.8, 0.8, 0.8 } },
{ "Vertices:Triangle fans", { 0.8, 0.5, 0.2 } },
{ "Vertices:Triangle strips", { 0.2, 0.5, 0.8 } },
{ "Nodes", { 0.4, 0.2, 0.8 }, "", 500.0 },
{ "Nodes:GeomNodes", { 0.8, 0.2, 0.0 } },
{ "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 },
{ "State changes:Transforms", { 0.2, 0.2, 0.8 }, },
{ "State changes:Textures", { 0.8, 0.2, 0.2 }, },
{ NULL }
{ 1, "Texture usage", { 1.0, 0.0, 0.0 }, "MB", 12, 1048576 },
{ 1, "Texture usage:Active", { 1.0, 1.0, 0.0 } },
{ 1, "Texture memory", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
{ 1, "Texture memory:In use", { 0.0, 1.0, 1.0 } },
{ 1, "Vertices", { 0.5, 0.2, 0.0 }, "K", 10, 1000 },
{ 1, "Vertices:Other", { 0.2, 0.2, 0.2 } },
{ 1, "Vertices:Triangles", { 0.8, 0.8, 0.8 } },
{ 1, "Vertices:Triangle fans", { 0.8, 0.5, 0.2 } },
{ 1, "Vertices:Triangle strips", { 0.2, 0.5, 0.8 } },
{ 1, "Nodes", { 0.4, 0.2, 0.8 }, "", 500.0 },
{ 1, "Nodes:GeomNodes", { 0.8, 0.2, 0.0 } },
{ 1, "State changes", { 1.0, 0.5, 0.2 }, "", 500.0 },
{ 1, "State changes:Transforms", { 0.2, 0.2, 0.8 }, },
{ 1, "State changes:Textures", { 0.8, 0.2, 0.2 }, },
{ 0, NULL }
};
////////////////////////////////////////////////////////////////////
// Function: initialize_collector_def
// Description: This is the only accessor function into this table.
// The PStatCollectorDef constructor calls it when a new
// PStatCollectorDef is created. It should look up in
// the table and find a matching definition for this def
// by name; if one is found, the properties are applied.
// Function: initialize_collector_def_from_table
// Description: Looks up the collector in the compiled-in table
// defined above, and sets its properties appropriately
// if it is found.
////////////////////////////////////////////////////////////////////
void
initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
static void
initialize_collector_def_from_table(const string &fullname, PStatCollectorDef *def) {
int i;
string fullname;
if (def->_index == 0) {
fullname = def->_name;
} else {
fullname = client->get_collector_fullname(def->_index);
}
for (i = 0;
time_properties[i].name != (const char *)NULL;
@ -139,6 +142,7 @@ initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
const TimeCollectorProperties &tp = time_properties[i];
if (fullname == tp.name) {
def->_sort = i;
def->_is_active = tp.is_active;
def->_suggested_color.set(tp.color.r, tp.color.g, tp.color.b);
if (tp.suggested_scale != 0.0) {
def->_suggested_scale = tp.suggested_scale;
@ -153,6 +157,7 @@ initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
const LevelCollectorProperties &lp = level_properties[i];
if (fullname == lp.name) {
def->_sort = i;
def->_is_active = lp.is_active;
def->_suggested_color.set(lp.color.r, lp.color.g, lp.color.b);
if (lp.suggested_scale != 0.0) {
def->_suggested_scale = lp.suggested_scale;
@ -168,4 +173,87 @@ initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
}
}
////////////////////////////////////////////////////////////////////
// Function: initialize_collector_def
// Description: This is the only accessor function into this table.
// The PStatCollectorDef constructor calls it when a new
// PStatCollectorDef is created. It should look up in
// the table and find a matching definition for this def
// by name; if one is found, the properties are applied.
////////////////////////////////////////////////////////////////////
void
initialize_collector_def(PStatClient *client, PStatCollectorDef *def) {
string fullname;
if (def->_index == 0) {
fullname = def->_name;
} else {
fullname = client->get_collector_fullname(def->_index);
}
// First, check the compiled-in defaults.
initialize_collector_def_from_table(fullname, def);
// Then, look to Config for more advice. To do this, we first
// change the name to something more like a Config variable name.
// We replace colons and spaces with hyphens, eliminate other
// punctuation, and make all letters lowercase.
string config_name;
string::const_iterator ni;
for (ni = fullname.begin(); ni != fullname.end(); ++ni) {
switch (*ni) {
case ':':
case ' ':
case '\n':
case '\r':
case '\t':
config_name += '-';
break;
default:
if (isalnum(*ni)) {
config_name += tolower(*ni);
}
}
}
def->_is_active =
config_pstats.GetBool("pstats-active-" + config_name, def->_is_active);
def->_sort =
config_pstats.GetInt("pstats-sort-" + config_name, def->_sort);
def->_suggested_scale =
config_pstats.GetFloat("pstats-scale-" + config_name, def->_suggested_scale);
def->_level_units =
config_pstats.GetString("pstats-units-" + config_name, def->_level_units);
def->_level_units =
config_pstats.GetString("pstats-units-" + config_name, def->_level_units);
if (!config_pstats.GetString("pstats-factor-" + config_name, "").empty()) {
def->_factor =
1.0/config_pstats.GetFloat("pstats-factor-" + config_name, 1.0);
}
// Get and decode the color string. We allow any three
// floating-point numbers, with any kind of non-digit characters
// between them.
string color_str =
config_pstats.GetString("pstats-color-" + config_name, "");
if (!color_str.empty()) {
const char *cstr = color_str.c_str();
const char *p = cstr;
int i = 0;
while (i < 3 && *p != '\0') {
while (*p != '\0' && !(isdigit(*p) || *p == '.')) {
p++;
}
char *q;
def->_suggested_color[i] = strtod(p, &q);
p = q;
i++;
}
}
}
#endif // DO_PSTATS

View File

@ -10,6 +10,7 @@
#include "pStatThreadData.h"
#include <pStatClientVersion.h>
#include <referenceCount.h>
#include <pointerTo.h>
@ -23,7 +24,7 @@ class PStatReader;
// with any one particular frame or thread: the list of
// collectors and threads, for instance.
////////////////////////////////////////////////////////////////////
class PStatClientData : public ReferenceCount {
class PStatClientData : public PStatClientVersion {
public:
PStatClientData(PStatReader *reader);
~PStatClientData();

View File

@ -158,8 +158,12 @@ receive_datagram(const NetDatagram &datagram) {
if (connection == _tcp_connection) {
PStatClientControlMessage message;
if (message.decode(datagram)) {
if (message.decode(datagram, _client_data)) {
handle_client_control_message(message);
} else if (message._type == PStatClientControlMessage::T_datagram) {
handle_client_udp_data(datagram);
} else {
nout << "Got unexpected message from client.\n";
}
@ -183,15 +187,16 @@ handle_client_control_message(const PStatClientControlMessage &message) {
switch (message._type) {
case PStatClientControlMessage::T_hello:
{
int current_major_version = get_current_pstat_major_version();
int current_minor_version = get_current_pstat_minor_version();
_client_data->set_version(message._major_version, message._minor_version);
int server_major_version = get_current_pstat_major_version();
int server_minor_version = get_current_pstat_minor_version();
if (message._major_version != current_major_version ||
(message._major_version == current_major_version &&
message._minor_version > current_minor_version)) {
if (message._major_version != server_major_version ||
(message._major_version == server_major_version &&
message._minor_version > server_minor_version)) {
_monitor->bad_version(message._client_hostname, message._client_progname,
message._major_version, message._minor_version,
current_major_version, current_minor_version);
server_major_version, server_minor_version);
_monitor->close();
} else {
_monitor->hello_from(message._client_hostname, message._client_progname);
@ -233,12 +238,26 @@ handle_client_control_message(const PStatClientControlMessage &message) {
////////////////////////////////////////////////////////////////////
void PStatReader::
handle_client_udp_data(const Datagram &datagram) {
if (!_monitor->is_client_known()) {
// If we haven't heard a "hello" from the client yet, we don't
// know what version data it will be sending us, so we can't
// decode the data. Chances are good we can't display it sensibly
// yet anyway. Ignore frame data until we get that hello.
return;
}
DatagramIterator source(datagram);
if (_client_data->is_at_least(2, 1)) {
// Throw away the zero byte at the beginning.
int initial_byte = source.get_uint8();
nassertv(initial_byte == 0);
}
int thread_index = source.get_uint16();
int frame_number = source.get_uint32();
PStatFrameData *frame_data = new PStatFrameData;
frame_data->read_datagram(source);
frame_data->read_datagram(source, _client_data);
// Check to see if any new collectors have level data.
int num_levels = frame_data->get_num_levels();