open_toontown_panda3d/pandatool/src/pstatserver/pStatMonitor.cxx

355 lines
14 KiB
C++

// Filename: pStatMonitor.cxx
// Created by: drose (09Jul00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "pStatMonitor.h"
#include "pStatCollectorDef.h"
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
PStatMonitor::
PStatMonitor(PStatServer *server) : _server(server) {
_client_known = false;
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
PStatMonitor::
~PStatMonitor() {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::hello_from
// Access: Public
// Description: Called shortly after startup time with the greeting
// from the client. This indicates the client's
// reported hostname and program name.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
hello_from(const string &hostname, const string &progname) {
_client_known = true;
_client_hostname = hostname;
_client_progname = progname;
got_hello();
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::bad_version
// Access: Public
// Description: Called shortly after startup time with the greeting
// from the client. In this case, the client seems to
// have an incompatible version and will be
// automatically disconnected; the server should issue a
// message to that effect.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
bad_version(const string &hostname, const string &progname,
int client_major, int client_minor,
int server_major, int server_minor) {
_client_known = true;
_client_hostname = hostname;
_client_progname = progname;
got_bad_version(client_major, client_minor,
server_major, server_minor);
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::set_client_data
// Access: Public
// Description: Called by the PStatServer at setup time to set the
// new data pointer for the first time.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
set_client_data(PStatClientData *client_data) {
_client_data = client_data;
initialized();
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::is_alive
// Access: Public
// Description: Returns true if the client is alive and connected,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool PStatMonitor::
is_alive() const {
if (_client_data.is_null()) {
// Not yet, but in a second probably.
return false;
}
return _client_data->is_alive();
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::close
// Access: Public
// Description: Closes the client connection if it is active.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
close() {
if (!_client_data.is_null()) {
_client_data->close();
}
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::get_collector_color
// Access: Public
// Description: Returns the color associated with the indicated
// collector. If the collector has no associated color,
// or is unknown, a new color will be made up on the
// spot and associated with this collector for the rest
// of the session.
////////////////////////////////////////////////////////////////////
const RGBColorf &PStatMonitor::
get_collector_color(int collector_index) {
Colors::iterator ci;
ci = _colors.find(collector_index);
if (ci != _colors.end()) {
return (*ci).second;
}
// Ask the client data about the color.
if (!_client_data.is_null() &&
_client_data->has_collector(collector_index)) {
const PStatCollectorDef &def =
_client_data->get_collector_def(collector_index);
RGBColorf sc(def._suggested_color.r,
def._suggested_color.g,
def._suggested_color.b);
if (sc != RGBColorf::zero()) {
ci = _colors.insert(Colors::value_type(collector_index, sc)).first;
return (*ci).second;
}
// Use the fullname of the collector as a hash to seed the random
// number generator (consulted below), so we get the same color
// for a given name across sessions.
string fullname = _client_data->get_collector_fullname(collector_index);
unsigned int hash = 0;
for (string::const_iterator ci = fullname.begin(); ci != fullname.end(); ++ci) {
hash = hash * 37 + (unsigned int)(*ci);
}
srand(hash);
}
// We didn't have a color for the collector; make one up.
RGBColorf random_color;
random_color[0] = (float)rand() / (float)RAND_MAX;
random_color[1] = (float)rand() / (float)RAND_MAX;
random_color[2] = (float)rand() / (float)RAND_MAX;
ci = _colors.insert(Colors::value_type(collector_index, random_color)).first;
return (*ci).second;
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::get_view
// Access: Public
// Description: Returns a view on the given thread index. If there
// is no such view already for the indicated thread,
// this will create one. This view can be used to
// examine the accumulated data for the given thread.
////////////////////////////////////////////////////////////////////
PStatView &PStatMonitor::
get_view(int thread_index) {
Views::iterator vi;
vi = _views.find(thread_index);
if (vi == _views.end()) {
vi = _views.insert(Views::value_type(thread_index, PStatView())).first;
(*vi).second.set_thread_data(_client_data->get_thread_data(thread_index));
}
return (*vi).second;
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::get_level_view
// Access: Public
// Description: Returns a view on the level value (as opposed to
// elapsed time) for the given collector over the given
// thread. If there is no such view already for the
// indicated thread, this will create one.
////////////////////////////////////////////////////////////////////
PStatView &PStatMonitor::
get_level_view(int collector_index, int thread_index) {
LevelViews::iterator lvi;
lvi = _level_views.find(collector_index);
if (lvi == _level_views.end()) {
lvi = _level_views.insert(LevelViews::value_type(collector_index, Views())).first;
}
Views &views = (*lvi).second;
Views::iterator vi;
vi = views.find(thread_index);
if (vi == views.end()) {
vi = views.insert(Views::value_type(thread_index, PStatView())).first;
(*vi).second.set_thread_data(_client_data->get_thread_data(thread_index));
(*vi).second.constrain(collector_index, true);
}
return (*vi).second;
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::initialized
// Access: Public, Virtual
// Description: Called after the monitor has been fully set up. At
// this time, it will have a valid _client_data pointer,
// and things like is_alive() and close() will be
// meaningful. However, we may not yet know who we're
// connected to (is_client_known() may return false),
// and we may not know anything about the threads or
// collectors we're about to get data on.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
initialized() {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::got_hello
// Access: Public, Virtual
// Description: Called when the "hello" message has been received
// from the client. At this time, the client's hostname
// and program name will be known.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
got_hello() {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::got_bad_version
// Access: Public, Virtual
// Description: Like got_hello(), this is called when the "hello"
// message has been received from the client. At this
// time, the client's hostname and program name will be
// known. However, the client appears to be an
// incompatible version and the connection will be
// terminated; the monitor should issue a message to
// that effect.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
got_bad_version(int, int, int, int) {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::new_collector
// Access: Public, Virtual
// Description: Called whenever a new Collector definition is
// received from the client. Generally, the client will
// send all of its collectors over shortly after
// connecting, but there's no guarantee that they will
// all be received before the first frames are received.
// The monitor should be prepared to accept new Collector
// definitions midstream.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
new_collector(int) {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::new_thread
// Access: Public, Virtual
// Description: Called whenever a new Thread definition is
// received from the client. Generally, the client will
// send all of its threads over shortly after
// connecting, but there's no guarantee that they will
// all be received before the first frames are received.
// The monitor should be prepared to accept new Thread
// definitions midstream.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
new_thread(int) {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::new_data
// Access: Public, Virtual
// Description: Called as each frame's data is made available. There
// is no guarantee the frames will arrive in order, or
// that all of them will arrive at all. The monitor
// should be prepared to accept frames received
// out-of-order or missing. The use of the
// PStatFrameData / PStatView objects to report the data
// will facilitate this.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
new_data(int, int) {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::lost_connection
// Access: Public, Virtual
// Description: Called whenever the connection to the client has been
// lost. This is a permanent state change. The monitor
// should update its display to represent this, and may
// choose to close down automatically.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
lost_connection() {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::idle
// Access: Public, Virtual
// Description: If has_idle() returns true, this will be called
// periodically to allow the monitor to update its
// display or whatever it needs to do.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
idle() {
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::has_idle
// Access: Public, Virtual
// Description: Should be redefined to return true if you want to
// redefine idle() and expect it to be called.
////////////////////////////////////////////////////////////////////
bool PStatMonitor::
has_idle() {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::is_thread_safe
// Access: Public, Virtual
// Description: Should be redefined to return true if this monitor
// class can handle running in a sub-thread.
//
// This is not related to the question of whether it can
// handle multiple different PStatThreadDatas; this is
// strictly a question of whether or not the monitor
// itself wants to run in a sub-thread.
////////////////////////////////////////////////////////////////////
bool PStatMonitor::
is_thread_safe() {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PStatMonitor::user_guide_bars_changed
// Access: Public, Virtual
// Description: Called when the user guide bars have been changed.
////////////////////////////////////////////////////////////////////
void PStatMonitor::
user_guide_bars_changed() {
}