beginnings of win-stats
This commit is contained in:
parent
e1be4d99df
commit
0e366091e5
|
|
@ -260,6 +260,7 @@ end_draw() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void PStatPianoRoll::
|
||||
idle() {
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ PStatStripChart(PStatMonitor *monitor, PStatView &view,
|
|||
_start_time = 0.0;
|
||||
|
||||
_level_index = 0;
|
||||
_title_unknown = true;
|
||||
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data->has_collector(_collector_index)) {
|
||||
|
|
@ -236,6 +237,59 @@ get_collector_under_pixel(int xpoint, int ypoint) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatStripChart::get_title_text
|
||||
// Access: Private
|
||||
// Description: Returns the text suitable for the title label on the
|
||||
// top line.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string PStatStripChart::
|
||||
get_title_text() {
|
||||
string text;
|
||||
|
||||
_title_unknown = false;
|
||||
bool _show_level = false;
|
||||
int _thread_index = 0;
|
||||
|
||||
const PStatClientData *client_data = _monitor->get_client_data();
|
||||
if (client_data->has_collector(_collector_index)) {
|
||||
const PStatCollectorDef &def = client_data->get_collector_def(_collector_index);
|
||||
if (_show_level) {
|
||||
if (def._level_units.empty()) {
|
||||
text = def._name;
|
||||
} else {
|
||||
text = def._name + " (" + def._level_units + ")";
|
||||
}
|
||||
} else {
|
||||
text = def._name + " time";
|
||||
}
|
||||
} else {
|
||||
_title_unknown = true;
|
||||
}
|
||||
|
||||
if (_thread_index != 0) {
|
||||
if (client_data->has_thread(_thread_index)) {
|
||||
text += "(" + client_data->get_thread_name(_thread_index) + " thread)";
|
||||
} else {
|
||||
_title_unknown = true;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatStripChart::is_title_unknown
|
||||
// Access: Public
|
||||
// Description: Returns true if get_title_text() has never yet
|
||||
// returned an answer, false if it has.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PStatStripChart::
|
||||
is_title_unknown() const {
|
||||
return _title_unknown;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PStatStripChart::get_frame_data
|
||||
// Access: Protected
|
||||
|
|
|
|||
|
|
@ -72,6 +72,9 @@ public:
|
|||
INLINE int height_to_pixel(float value) const;
|
||||
INLINE float pixel_to_height(int y) const;
|
||||
|
||||
string get_title_text();
|
||||
bool is_title_unknown() const;
|
||||
|
||||
protected:
|
||||
class ColorData {
|
||||
public:
|
||||
|
|
@ -117,6 +120,7 @@ private:
|
|||
float _time_width;
|
||||
float _start_time;
|
||||
float _value_height;
|
||||
bool _title_unknown;
|
||||
};
|
||||
|
||||
#include "pStatStripChart.I"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#define BUILD_DIRECTORY $[and $[WINDOWS_PLATFORM],$[HAVE_NET]]
|
||||
#define USE_PACKAGES net
|
||||
|
||||
#begin bin_target
|
||||
#define TARGET pstats
|
||||
#define LOCAL_LIBS \
|
||||
progbase pstatserver
|
||||
#define OTHER_LIBS \
|
||||
pstatclient:c linmath:c putil:c net:c express:c pandaexpress:m panda:m \
|
||||
dtoolutil:c dtoolbase:c dconfig:c dtoolconfig:m dtool:m \
|
||||
pystub
|
||||
|
||||
#define SOURCES \
|
||||
winStats.cxx \
|
||||
winStatsGraph.cxx winStatsGraph.h \
|
||||
winStatsServer.cxx winStatsServer.h \
|
||||
winStatsMonitor.cxx winStatsMonitor.h \
|
||||
winStatsStripChart.cxx winStatsStripChart.h
|
||||
|
||||
#define WIN_SYS_LIBS Imm32.lib winmm.lib kernel32.lib oldnames.lib user32.lib gdi32.lib
|
||||
|
||||
#end bin_target
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
// Filename: winStats.cxx
|
||||
// Created by: drose (02Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "winStatsServer.h"
|
||||
#include "config_pstats.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static const char *toplevel_class_name = "pstats";
|
||||
static WinStatsServer *server = NULL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: toplevel_window_proc
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static LONG WINAPI
|
||||
toplevel_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_TIMER:
|
||||
server->poll();
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: create_toplevel_window
|
||||
// Description: Creates the initial, toplevel window for the
|
||||
// application.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
static HWND
|
||||
create_toplevel_window(HINSTANCE application) {
|
||||
WNDCLASS wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof(WNDCLASS));
|
||||
wc.lpfnWndProc = (WNDPROC)toplevel_window_proc;
|
||||
wc.hInstance = application;
|
||||
wc.lpszClassName = toplevel_class_name;
|
||||
|
||||
if (!RegisterClass(&wc)) {
|
||||
nout << "Could not register window class!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
DWORD window_style = WS_POPUP | WS_SYSMENU | WS_ICONIC;
|
||||
|
||||
HWND toplevel_window =
|
||||
CreateWindow(toplevel_class_name, "PStats", window_style,
|
||||
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
|
||||
NULL, NULL, application, 0);
|
||||
if (!toplevel_window) {
|
||||
nout << "Could not create toplevel window!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return toplevel_window;
|
||||
}
|
||||
|
||||
|
||||
// WinMain() is the correct way to start a Windows-only application,
|
||||
// but it is sometimes more convenient during development to use
|
||||
// main() instead, which doesn't squelch the stderr output.
|
||||
|
||||
#ifdef USE_WINMAIN
|
||||
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
|
||||
#else
|
||||
int main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
HINSTANCE application = GetModuleHandle(NULL);
|
||||
HWND toplevel_window = create_toplevel_window(application);
|
||||
|
||||
ShowWindow(toplevel_window, SW_SHOWMINIMIZED);
|
||||
|
||||
// Create the server object.
|
||||
server = new WinStatsServer;
|
||||
if (!server->listen()) {
|
||||
nout << "Unable to open port.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Set up a timer to poll the pstats every so often.
|
||||
SetTimer(toplevel_window, 1, 200, NULL);
|
||||
|
||||
// Now get lost in the Windows message loop.
|
||||
MSG msg;
|
||||
int retval;
|
||||
retval = GetMessage(&msg, NULL, 0, 0);
|
||||
while (retval != 0) {
|
||||
if (retval == -1) {
|
||||
nout << "Error processing message queue.\n";
|
||||
exit(1);
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
retval = GetMessage(&msg, NULL, 0, 0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
// Filename: winStats.h
|
||||
// Created by: drose (02Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WINSTATS_H
|
||||
#define WINSTATS_H
|
||||
|
||||
#include "pStatServer.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
// Filename: winStatsGraph.cxx
|
||||
// Created by: drose (03Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "winStatsGraph.h"
|
||||
#include "winStatsMonitor.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinStatsGraph::
|
||||
WinStatsGraph(WinStatsMonitor *monitor) :
|
||||
_monitor(monitor)
|
||||
{
|
||||
_window = 0;
|
||||
_bitmap = 0;
|
||||
_bitmap_dc = 0;
|
||||
_bitmap_xsize = 0;
|
||||
_bitmap_ysize = 0;
|
||||
_left_margin = 64;
|
||||
_right_margin = 32;
|
||||
_top_margin = 16;
|
||||
_bottom_margin = 8;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinStatsGraph::
|
||||
~WinStatsGraph() {
|
||||
_monitor = (WinStatsMonitor *)NULL;
|
||||
release_bitmap();
|
||||
|
||||
Brushes::iterator bi;
|
||||
for (bi = _brushes.begin(); bi != _brushes.end(); ++bi) {
|
||||
HBRUSH brush = (*bi).second;
|
||||
DeleteObject(brush);
|
||||
}
|
||||
|
||||
if (_window) {
|
||||
DestroyWindow(_window);
|
||||
_window = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::new_collector
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever a new Collector definition is
|
||||
// received from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsGraph::
|
||||
new_collector(int new_collector) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::new_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever new data arrives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsGraph::
|
||||
new_data(int thread_index, int frame_number) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::close
|
||||
// Access: Protected
|
||||
// Description: Should be called when the user closes the associated
|
||||
// window. This tells the monitor to remove the graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsGraph::
|
||||
close() {
|
||||
WinStatsMonitor *monitor = _monitor;
|
||||
_monitor = (WinStatsMonitor *)NULL;
|
||||
if (monitor != (WinStatsMonitor *)NULL) {
|
||||
monitor->remove_graph(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::setup_bitmap
|
||||
// Access: Protected
|
||||
// Description: Sets up a backing-store bitmap of the indicated size.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsGraph::
|
||||
setup_bitmap(int xsize, int ysize) {
|
||||
release_bitmap();
|
||||
_bitmap_xsize = max(xsize, 0);
|
||||
_bitmap_ysize = max(ysize, 0);
|
||||
|
||||
_frame_rect.left = _left_margin;
|
||||
_frame_rect.top = _top_margin;
|
||||
_frame_rect.right = _left_margin + _bitmap_xsize;
|
||||
_frame_rect.bottom = _bottom_margin + _bitmap_ysize;
|
||||
|
||||
HDC hdc = GetDC(_window);
|
||||
_bitmap_dc = CreateCompatibleDC(hdc);
|
||||
_bitmap = CreateCompatibleBitmap(hdc, _bitmap_xsize, _bitmap_ysize);
|
||||
SelectObject(_bitmap_dc, _bitmap);
|
||||
ReleaseDC(_window, hdc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::release_bitmap
|
||||
// Access: Protected
|
||||
// Description: Frees the backing-store bitmap created by
|
||||
// setup_bitmap().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsGraph::
|
||||
release_bitmap() {
|
||||
if (_bitmap) {
|
||||
DeleteObject(_bitmap);
|
||||
_bitmap = 0;
|
||||
}
|
||||
if (_bitmap_dc) {
|
||||
DeleteDC(_bitmap_dc);
|
||||
_bitmap_dc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::get_collector_brush
|
||||
// Access: Protected
|
||||
// Description: Returns a brush suitable for drawing in the indicated
|
||||
// collector's color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HBRUSH WinStatsGraph::
|
||||
get_collector_brush(int collector_index) {
|
||||
Brushes::iterator bi;
|
||||
bi = _brushes.find(collector_index);
|
||||
if (bi != _brushes.end()) {
|
||||
return (*bi).second;
|
||||
}
|
||||
|
||||
// Ask the monitor what color this guy should be.
|
||||
RGBColorf rgb = _monitor->get_collector_color(collector_index);
|
||||
int r = (int)(rgb[0] * 255.0f);
|
||||
int g = (int)(rgb[1] * 255.0f);
|
||||
int b = (int)(rgb[2] * 255.0f);
|
||||
HBRUSH brush = CreateSolidBrush(RGB(r, g, b));
|
||||
|
||||
_brushes[collector_index] = brush;
|
||||
return brush;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsGraph::draw_graph
|
||||
// Access: Protected
|
||||
// Description: Draws the graph into the window by blitting the
|
||||
// backing-store bitmap in, along with a suitable frame.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsGraph::
|
||||
draw_graph(HDC hdc) {
|
||||
if (_bitmap_xsize == 0 || _bitmap_ysize == 0) {
|
||||
// Never mind: nothing to draw.
|
||||
return;
|
||||
}
|
||||
|
||||
// First, draw a frame around the graph.
|
||||
|
||||
// Windows doesn't seem to have an API to ask how big the outer
|
||||
// frame will be before we draw it, only a way to draw the outer
|
||||
// frame and return the size of the inner frame afterwards.
|
||||
|
||||
// So we have to make our best guess about the correct size of the
|
||||
// outer frame before we draw it, then examine the size of the
|
||||
// resulting inner frame. If it didn't come out to the correct size
|
||||
// (that is, exactly large enough to frame our graph), we expand the
|
||||
// outer frame by the difference, and redraw it.
|
||||
|
||||
RECT rect = _frame_rect;
|
||||
DrawEdge(hdc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
||||
|
||||
if (rect.left != _left_margin ||
|
||||
rect.top != _top_margin ||
|
||||
rect.right != _left_margin + _bitmap_xsize ||
|
||||
rect.bottom != _top_margin + _bitmap_ysize) {
|
||||
_frame_rect.left = _left_margin - (rect.left - _frame_rect.left);
|
||||
_frame_rect.top = _top_margin - (rect.top - _frame_rect.top);
|
||||
_frame_rect.right = _left_margin + _bitmap_xsize + (_frame_rect.right - rect.right);
|
||||
_frame_rect.bottom = _top_margin + _bitmap_ysize + (_frame_rect.bottom - rect.bottom);
|
||||
|
||||
DrawEdge(hdc, &_frame_rect, EDGE_SUNKEN, BF_RECT);
|
||||
}
|
||||
|
||||
// Now fill in the graph.
|
||||
BitBlt(hdc, _left_margin, _top_margin,
|
||||
_bitmap_xsize, _bitmap_ysize,
|
||||
_bitmap_dc, 0, 0,
|
||||
SRCCOPY);
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Filename: winStatsGraph.h
|
||||
// Created by: drose (03Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WINSTATSGRAPH_H
|
||||
#define WINSTATSGRAPH_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "pmap.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class WinStatsMonitor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WinStatsGraph
|
||||
// Description : This is just an abstract base class to provide a
|
||||
// common pointer type for the various kinds of graphs
|
||||
// that may be created for a WinStatsMonitor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WinStatsGraph {
|
||||
public:
|
||||
WinStatsGraph(WinStatsMonitor *monitor);
|
||||
virtual ~WinStatsGraph();
|
||||
|
||||
virtual void new_collector(int collector_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
|
||||
protected:
|
||||
void close();
|
||||
|
||||
void setup_bitmap(int xsize, int ysize);
|
||||
void release_bitmap();
|
||||
|
||||
HBRUSH get_collector_brush(int collector_index);
|
||||
void draw_graph(HDC hdc);
|
||||
|
||||
protected:
|
||||
// Table of brushes for our various collectors.
|
||||
typedef pmap<int, HBRUSH> Brushes;
|
||||
Brushes _brushes;
|
||||
|
||||
WinStatsMonitor *_monitor;
|
||||
HWND _window;
|
||||
|
||||
HBITMAP _bitmap;
|
||||
HDC _bitmap_dc;
|
||||
|
||||
int _bitmap_xsize, _bitmap_ysize;
|
||||
int _left_margin, _right_margin;
|
||||
int _top_margin, _bottom_margin;
|
||||
|
||||
RECT _frame_rect;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
// Filename: winStatsMonitor.cxx
|
||||
// Created by: drose (02Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "winStatsMonitor.h"
|
||||
#include "winStatsStripChart.h"
|
||||
|
||||
#include "pStatCollectorDef.h"
|
||||
|
||||
bool WinStatsMonitor::_window_class_registered = false;
|
||||
const char * const WinStatsMonitor::_window_class_name = "monitor";
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinStatsMonitor::
|
||||
WinStatsMonitor() {
|
||||
_window = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinStatsMonitor::
|
||||
~WinStatsMonitor() {
|
||||
cerr << "WinStatsMonitor destructor\n";
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
delete (*gi);
|
||||
}
|
||||
_graphs.clear();
|
||||
|
||||
if (_window) {
|
||||
DestroyWindow(_window);
|
||||
_window = 0;
|
||||
}
|
||||
|
||||
// For now, exit when the first monitor closes.
|
||||
exit(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::get_monitor_name
|
||||
// Access: Public, Virtual
|
||||
// Description: Should be redefined to return a descriptive name for
|
||||
// the type of PStatsMonitor this is.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string WinStatsMonitor::
|
||||
get_monitor_name() {
|
||||
return "WinStats";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
initialized() {
|
||||
cerr << "Monitor initialized (refcount = " << get_ref_count() << ")\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
got_hello() {
|
||||
create_window();
|
||||
|
||||
add_graph(new WinStatsStripChart(this, get_view(0), 0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
got_bad_version(int client_major, int client_minor,
|
||||
int server_major, int server_minor) {
|
||||
cerr << "Got bad version " << client_major << "." << client_minor
|
||||
<< " from " << get_client_progname() << " on "
|
||||
<< get_client_hostname() << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
new_collector(int collector_index) {
|
||||
cerr << "Got new collector " << get_collector_name(collector_index)
|
||||
<< "\n";
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
WinStatsGraph *graph = (*gi);
|
||||
graph->new_collector(collector_index);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::new_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Called as each frame's data is made available. There
|
||||
// is no gurantee 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsMonitor::
|
||||
new_data(int thread_index, int frame_number) {
|
||||
Graphs::iterator gi;
|
||||
for (gi = _graphs.begin(); gi != _graphs.end(); ++gi) {
|
||||
WinStatsGraph *graph = (*gi);
|
||||
graph->new_data(thread_index, frame_number);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
lost_connection() {
|
||||
cerr << "Lost connection to " << get_client_hostname()
|
||||
<< " (refcount = " << get_ref_count() << ")\n";
|
||||
|
||||
if (_window) {
|
||||
DestroyWindow(_window);
|
||||
_window = 0;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
idle() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::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 WinStatsMonitor::
|
||||
has_idle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::get_window
|
||||
// Access: Public
|
||||
// Description: Returns the window handle to the monitor's window.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
HWND WinStatsMonitor::
|
||||
get_window() const {
|
||||
return _window;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::add_graph
|
||||
// Access: Private
|
||||
// Description: Adds the newly-created graph to the list of managed
|
||||
// graphs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsMonitor::
|
||||
add_graph(WinStatsGraph *graph) {
|
||||
_graphs.insert(graph);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::remove_graph
|
||||
// Access: Private
|
||||
// Description: Deletes the indicated graph.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsMonitor::
|
||||
remove_graph(WinStatsGraph *graph) {
|
||||
Graphs::iterator gi = _graphs.find(graph);
|
||||
if (gi != _graphs.end()) {
|
||||
_graphs.erase(gi);
|
||||
delete graph;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::create_window
|
||||
// Access: Private
|
||||
// Description: Creates the window for this monitor.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsMonitor::
|
||||
create_window() {
|
||||
if (_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
HINSTANCE application = GetModuleHandle(NULL);
|
||||
register_window_class(application);
|
||||
|
||||
_window_title = get_client_progname() + " on " + get_client_hostname();
|
||||
DWORD window_style = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
|
||||
|
||||
_window =
|
||||
CreateWindow(_window_class_name, _window_title.c_str(), window_style,
|
||||
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
|
||||
NULL, NULL, application, 0);
|
||||
if (!_window) {
|
||||
nout << "Could not create monitor window!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SetWindowLongPtr(_window, 0, (LONG_PTR)this);
|
||||
ShowWindow(_window, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::register_window_class
|
||||
// Access: Private, Static
|
||||
// Description: Registers the window class for the monitor window, if
|
||||
// it has not already been registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsMonitor::
|
||||
register_window_class(HINSTANCE application) {
|
||||
if (_window_class_registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
WNDCLASS wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof(WNDCLASS));
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = (WNDPROC)static_window_proc;
|
||||
wc.hInstance = application;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = _window_class_name;
|
||||
|
||||
// Reserve space to associate the this pointer with the window.
|
||||
wc.cbWndExtra = sizeof(WinStatsMonitor *);
|
||||
|
||||
if (!RegisterClass(&wc)) {
|
||||
nout << "Could not register monitor window class!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_window_class_registered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::static_window_proc
|
||||
// Access: Private, Static
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI WinStatsMonitor::
|
||||
static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
WinStatsMonitor *self = (WinStatsMonitor *)GetWindowLongPtr(hwnd, 0);
|
||||
if (self != (WinStatsMonitor *)NULL && self->_window == hwnd) {
|
||||
return self->window_proc(hwnd, msg, wparam, lparam);
|
||||
} else {
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsMonitor::window_proc
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG WinStatsMonitor::
|
||||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_DESTROY:
|
||||
close();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// Filename: winStatsMonitor.h
|
||||
// Created by: drose (02Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WINSTATSMONITOR_H
|
||||
#define WINSTATSMONITOR_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "winStatsGraph.h"
|
||||
#include "pStatMonitor.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pset.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WinStatsMonitor
|
||||
// Description : This class represents a connection to a PStatsClient
|
||||
// and manages the data exchange with the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WinStatsMonitor : public PStatMonitor {
|
||||
public:
|
||||
WinStatsMonitor();
|
||||
virtual ~WinStatsMonitor();
|
||||
|
||||
virtual string get_monitor_name();
|
||||
|
||||
virtual void initialized();
|
||||
virtual void got_hello();
|
||||
virtual void got_bad_version(int client_major, int client_minor,
|
||||
int server_major, int server_minor);
|
||||
virtual void new_collector(int collector_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
virtual void lost_connection();
|
||||
virtual void idle();
|
||||
virtual bool has_idle();
|
||||
|
||||
HWND get_window() const;
|
||||
|
||||
private:
|
||||
void add_graph(WinStatsGraph *graph);
|
||||
void remove_graph(WinStatsGraph *graph);
|
||||
|
||||
void create_window();
|
||||
static void register_window_class(HINSTANCE application);
|
||||
|
||||
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
typedef pset<WinStatsGraph *> Graphs;
|
||||
Graphs _graphs;
|
||||
|
||||
HWND _window;
|
||||
string _window_title;
|
||||
|
||||
static bool _window_class_registered;
|
||||
static const char * const _window_class_name;
|
||||
|
||||
friend class WinStatsGraph;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Filename: winStatsServer.cxx
|
||||
// Created by: drose (02Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "winStatsServer.h"
|
||||
#include "winStatsMonitor.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsServer::make_monitor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PStatMonitor *WinStatsServer::
|
||||
make_monitor() {
|
||||
return new WinStatsMonitor;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
// Filename: winStatsServer.h
|
||||
// Created by: drose (02Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WINSTATSSERVER_H
|
||||
#define WINSTATSSERVER_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
#include "pStatServer.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WinStatsServer
|
||||
// Description : The class that owns the main loop, waiting for client
|
||||
// connections.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WinStatsServer : public PStatServer {
|
||||
public:
|
||||
virtual PStatMonitor *make_monitor();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,336 @@
|
|||
// Filename: winStatsStripChart.cxx
|
||||
// Created by: drose (03Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "winStatsStripChart.h"
|
||||
#include "winStatsMonitor.h"
|
||||
|
||||
static const int default_strip_chart_width = 400;
|
||||
static const int default_strip_chart_height = 100;
|
||||
|
||||
bool WinStatsStripChart::_window_class_registered = false;
|
||||
const char * const WinStatsStripChart::_window_class_name = "strip";
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinStatsStripChart::
|
||||
WinStatsStripChart(WinStatsMonitor *monitor, PStatView &view,
|
||||
int collector_index) :
|
||||
PStatStripChart(monitor, view, collector_index,
|
||||
default_strip_chart_width,
|
||||
default_strip_chart_height),
|
||||
WinStatsGraph(monitor)
|
||||
{
|
||||
cerr << "Constructing strip chart " << (void *)this << "\n";
|
||||
_brush_origin = 0;
|
||||
|
||||
setup_bitmap(get_xsize(), get_ysize());
|
||||
clear_region();
|
||||
create_window();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
WinStatsStripChart::
|
||||
~WinStatsStripChart() {
|
||||
cerr << "Destructing strip chart " << (void *)this << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::new_collector
|
||||
// Access: Public, Virtual
|
||||
// Description: Called whenever a new Collector definition is
|
||||
// received from the client.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
new_collector(int collector_index) {
|
||||
if (is_title_unknown()) {
|
||||
string window_title = get_title_text();
|
||||
if (!is_title_unknown()) {
|
||||
SetWindowText(_window, window_title.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
WinStatsGraph::new_collector(collector_index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::idle
|
||||
// Access: Public, Virtual
|
||||
// Description: Called as each frame's data is made available. There
|
||||
// is no gurantee 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.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
new_data(int thread_index, int frame_number) {
|
||||
update();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::clear_region
|
||||
// Access: Protected, Virtual
|
||||
// Description: Erases the chart area.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
clear_region() {
|
||||
RECT rect = { 0, 0, get_xsize(), get_ysize() };
|
||||
FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::copy_region
|
||||
// Access: Protected, Virtual
|
||||
// Description: Should be overridden by the user class to copy a
|
||||
// region of the chart from one part of the chart to
|
||||
// another. This is used to implement scrolling.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
copy_region(int start_x, int end_x, int dest_x) {
|
||||
BitBlt(_bitmap_dc, dest_x, 0,
|
||||
end_x - start_x, get_ysize(),
|
||||
_bitmap_dc, start_x, 0,
|
||||
SRCCOPY);
|
||||
|
||||
// Also shift the brush origin over, so we still get proper
|
||||
// dithering.
|
||||
_brush_origin += (dest_x - start_x);
|
||||
SetBrushOrgEx(_bitmap_dc, _brush_origin, 0, NULL);
|
||||
|
||||
RECT rect = {
|
||||
_left_margin + dest_x, _top_margin,
|
||||
_left_margin + end_x - start_x, _top_margin + get_ysize()
|
||||
};
|
||||
InvalidateRect(_window, &rect, FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::draw_slice
|
||||
// Access: Protected, Virtual
|
||||
// Description: Draws a single vertical slice of the strip chart, at
|
||||
// the given pixel position, and corresponding to the
|
||||
// indicated level data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
draw_slice(int x, int frame_number) {
|
||||
const FrameData &frame = get_frame_data(frame_number);
|
||||
|
||||
// Start by clearing the band first.
|
||||
RECT rect = { x, 0, x + 1, get_ysize() };
|
||||
FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
|
||||
float overall_time = 0.0;
|
||||
int y = get_ysize();
|
||||
|
||||
FrameData::const_iterator fi;
|
||||
for (fi = frame.begin(); fi != frame.end(); ++fi) {
|
||||
const ColorData &cd = (*fi);
|
||||
overall_time += cd._net_value;
|
||||
HBRUSH brush = get_collector_brush(cd._collector_index);
|
||||
|
||||
if (overall_time > get_vertical_scale()) {
|
||||
// Off the top. Go ahead and clamp it by hand, in case it's so
|
||||
// far off the top we'd overflow the 16-bit pixel value.
|
||||
rect.top = 0;
|
||||
rect.bottom = y;
|
||||
FillRect(_bitmap_dc, &rect, brush);
|
||||
// And we can consider ourselves done now.
|
||||
return;
|
||||
}
|
||||
|
||||
int top_y = height_to_pixel(overall_time);
|
||||
rect.top = top_y;
|
||||
rect.bottom = y;
|
||||
FillRect(_bitmap_dc, &rect, brush);
|
||||
y = top_y;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::draw_empty
|
||||
// Access: Protected, Virtual
|
||||
// Description: Draws a single vertical slice of background color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
draw_empty(int x) {
|
||||
RECT rect = { x, 0, x + 1, get_ysize() };
|
||||
FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::draw_cursor
|
||||
// Access: Protected, Virtual
|
||||
// Description: Draws a single vertical slice of foreground color.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
draw_cursor(int x) {
|
||||
RECT rect = { x, 0, x + 1, get_ysize() };
|
||||
FillRect(_bitmap_dc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::end_draw
|
||||
// Access: Protected, Virtual
|
||||
// Description: Should be overridden by the user class. This hook
|
||||
// will be called after drawing a series of color bars
|
||||
// in the strip chart; it gives the pixel range that
|
||||
// was just redrawn.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
end_draw(int from_x, int to_x) {
|
||||
RECT rect = { from_x, 0, to_x + 1, get_ysize() };
|
||||
InvalidateRect(_window, &rect, FALSE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::create_window
|
||||
// Access: Private
|
||||
// Description: Creates the window for this strip chart.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
create_window() {
|
||||
if (_window) {
|
||||
return;
|
||||
}
|
||||
|
||||
HINSTANCE application = GetModuleHandle(NULL);
|
||||
register_window_class(application);
|
||||
|
||||
string window_title = get_title_text();
|
||||
DWORD window_style = WS_CHILD | WS_OVERLAPPEDWINDOW;
|
||||
|
||||
RECT win_rect = {
|
||||
0, 0,
|
||||
_left_margin + get_xsize() + _right_margin,
|
||||
_top_margin + get_ysize() + _bottom_margin
|
||||
};
|
||||
|
||||
// compute window size based on desired client area size
|
||||
AdjustWindowRect(&win_rect, window_style, FALSE);
|
||||
|
||||
_window =
|
||||
CreateWindow(_window_class_name, window_title.c_str(), window_style,
|
||||
CW_USEDEFAULT, 0,
|
||||
win_rect.right - win_rect.left,
|
||||
win_rect.bottom - win_rect.top,
|
||||
WinStatsGraph::_monitor->get_window(), NULL, application, 0);
|
||||
if (!_window) {
|
||||
nout << "Could not create StripChart window!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
SetWindowLongPtr(_window, 0, (LONG_PTR)this);
|
||||
ShowWindow(_window, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::register_window_class
|
||||
// Access: Private, Static
|
||||
// Description: Registers the window class for the stripChart window, if
|
||||
// it has not already been registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void WinStatsStripChart::
|
||||
register_window_class(HINSTANCE application) {
|
||||
if (_window_class_registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
WNDCLASS wc;
|
||||
|
||||
ZeroMemory(&wc, sizeof(WNDCLASS));
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = (WNDPROC)static_window_proc;
|
||||
wc.hInstance = application;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = (HBRUSH)COLOR_BACKGROUND;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = _window_class_name;
|
||||
|
||||
// Reserve space to associate the this pointer with the window.
|
||||
wc.cbWndExtra = sizeof(WinStatsStripChart *);
|
||||
|
||||
if (!RegisterClass(&wc)) {
|
||||
nout << "Could not register StripChart window class!\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
_window_class_registered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::static_window_proc
|
||||
// Access: Private, Static
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG WINAPI WinStatsStripChart::
|
||||
static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
WinStatsStripChart *self = (WinStatsStripChart *)GetWindowLongPtr(hwnd, 0);
|
||||
if (self != (WinStatsStripChart *)NULL && self->_window == hwnd) {
|
||||
return self->window_proc(hwnd, msg, wparam, lparam);
|
||||
} else {
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: WinStatsStripChart::window_proc
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LONG WinStatsStripChart::
|
||||
window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
switch (msg) {
|
||||
case WM_DESTROY:
|
||||
close();
|
||||
break;
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
setup_bitmap(get_xsize(), get_ysize());
|
||||
force_redraw();
|
||||
break;
|
||||
|
||||
case WM_SIZE:
|
||||
changed_size(LOWORD(lparam) - (_left_margin + _right_margin),
|
||||
HIWORD(lparam) - (_top_margin + _bottom_margin));
|
||||
setup_bitmap(get_xsize(), get_ysize());
|
||||
force_redraw();
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
{
|
||||
// Repaint the graph by copying the backing pixmap in.
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(hwnd, &ps);
|
||||
draw_graph(hdc);
|
||||
EndPaint(hwnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// Filename: winStatsStripChart.h
|
||||
// Created by: drose (03Dec03)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WINSTATSSTRIPCHART_H
|
||||
#define WINSTATSSTRIPCHART_H
|
||||
|
||||
#include "pandatoolbase.h"
|
||||
|
||||
#include "winStatsGraph.h"
|
||||
#include "pStatStripChart.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class WinStatsMonitor;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : WinStatsStripChart
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class WinStatsStripChart : public PStatStripChart, public WinStatsGraph {
|
||||
public:
|
||||
WinStatsStripChart(WinStatsMonitor *monitor,
|
||||
PStatView &view, int collector_index);
|
||||
virtual ~WinStatsStripChart();
|
||||
|
||||
virtual void new_collector(int collector_index);
|
||||
virtual void new_data(int thread_index, int frame_number);
|
||||
|
||||
protected:
|
||||
virtual void clear_region();
|
||||
virtual void copy_region(int start_x, int end_x, int dest_x);
|
||||
virtual void draw_slice(int x, int frame_number);
|
||||
virtual void draw_empty(int x);
|
||||
virtual void draw_cursor(int x);
|
||||
virtual void end_draw(int from_x, int to_x);
|
||||
|
||||
private:
|
||||
void create_window();
|
||||
static void register_window_class(HINSTANCE application);
|
||||
|
||||
static LONG WINAPI static_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
LONG WINAPI window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
int _brush_origin;
|
||||
|
||||
static bool _window_class_registered;
|
||||
static const char * const _window_class_name;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue