Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pstatclient/test_client.cxx

Go to the documentation of this file.
00001 // Filename: test_client.cxx
00002 // Created by:  drose (09Jul00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "config_pstats.h"
00020 #include "pStatClient.h"
00021 #include "pStatCollector.h"
00022 
00023 #include <luse.h>
00024 #include <queuedConnectionManager.h>
00025 #include <queuedConnectionReader.h>
00026 #include <connectionWriter.h>
00027 #include <netAddress.h>
00028 #include <connection.h>
00029 #include <netDatagram.h>
00030 
00031 #include <signal.h>
00032 #include <algorithm>
00033 
00034 static bool user_interrupted = false;
00035 
00036 // Define a signal handler so we can clean up on control-C.
00037 void signal_handler(int) {
00038   user_interrupted = true;
00039 }
00040 
00041 struct SampleData {
00042   const char *category;
00043   float min_ms;
00044   float max_ms;
00045   bool is_level;
00046 };
00047 
00048 SampleData dataset_zero[] = {
00049   { "Draw", 10, 10, false },
00050   { "Cull", 5, 6, false },
00051   { "App", 0, 5, false },
00052   { "Texture memory", 1, 0.01, true },
00053   { NULL },
00054 };
00055 
00056 SampleData dataset_one[] = {
00057   { "Draw", 10, 12, false },
00058   { "Squeak", 25, 30, false },
00059   { NULL },
00060 };
00061 
00062 SampleData dataset_two[] = {
00063   { "Squeak", 40, 45, false },
00064   { "Cull", 20, 22, false },
00065   { "Draw", 10, 20, false },
00066   { "Animation", 0, 0, false },
00067   { "Animation:mickey", 5, 6, false },
00068   { "Animation:donald", 5, 6, false },
00069   { "Animation:goofy", 5, 6, false },
00070   { "Animation:pluto", 5, 6, false },
00071   { NULL },
00072 };
00073 
00074 #define NUM_DATASETS 3
00075 SampleData *datasets[NUM_DATASETS] = {
00076   dataset_zero, dataset_one, dataset_two
00077 };
00078 
00079 
00080 class WaitRequest {
00081 public:
00082   float _time;
00083   int _index;
00084   bool _start;
00085 
00086   bool operator < (const WaitRequest &other) const {
00087     return _time < other._time;
00088   }
00089 };
00090 
00091 int
00092 main(int argc, char *argv[]) {
00093   string hostname = "localhost";
00094   int port = pstats_port;
00095 
00096   if (argc > 1) {
00097     hostname = argv[1];
00098   }
00099   if (argc > 2) {
00100     port = atoi(argv[2]);
00101     if (port == 0) {
00102       nout << "Invalid port number: " << argv[2] << "\n";
00103       exit(1);
00104     }
00105   }
00106   if (argc > 4) {
00107     nout << "test_client host port [dataset]\n";
00108     exit(1);
00109   }
00110 
00111   signal(SIGINT, &signal_handler);
00112 
00113   PStatClient *client = PStatClient::get_global_pstats();
00114   client->set_client_name("Bogus Stats");
00115 
00116   if (!client->connect(hostname, port)) {
00117     nout << "Couldn't connect.\n";
00118     exit(1);
00119   }
00120 
00121   srand(time(NULL));
00122 
00123   int ds_index;
00124   if (argc > 3) {
00125     ds_index = atoi(argv[3]);
00126   } else {
00127     // Pick a random Dataset.
00128     ds_index = (int)((float)NUM_DATASETS * rand() / (RAND_MAX + 1.0));
00129   }
00130   if (ds_index < 0 || ds_index >= NUM_DATASETS) {
00131     nout << "Invalid dataset; choose a number in the range 0 to "
00132          << NUM_DATASETS - 1 << "\n";
00133     exit(1);
00134   }
00135 
00136   SampleData *ds = datasets[ds_index];
00137 
00138   pvector<PStatCollector> _collectors;
00139   int i = 0;
00140   while (ds[i].category != (const char *)NULL) {
00141     _collectors.push_back(PStatCollector(ds[i].category));
00142     if (ds[i].is_level) {
00143       _collectors[i].set_level(ds[i].min_ms);
00144     }
00145     i++;
00146   }
00147 
00148   while (!user_interrupted && client->is_connected()) {
00149     client->get_main_thread().new_frame();
00150 
00151     float total_ms = 0.0;
00152     float now = client->get_clock().get_real_time();
00153 
00154     typedef pvector<WaitRequest> Wait;
00155     Wait wait;
00156 
00157     // Make up some random intervals to "wait".
00158     for (i = 0; i < (int)_collectors.size(); i++) {
00159       if (ds[i].is_level) {
00160         // Make up an amount to add/delete to the level this frame.
00161         float increment = ds[i].max_ms * (rand() / (RAND_MAX + 1.0) - 0.5);
00162         _collectors[i].add_level(increment);
00163 
00164       } else {
00165         // A bit of random jitter so the collectors might overlap some.
00166         float jitter_ms = (5.0 * rand() / (RAND_MAX + 1.0));
00167 
00168         WaitRequest wr;
00169         wr._time = now + jitter_ms / 1000.0;
00170         wr._index = i;
00171         wr._start = true;
00172         wait.push_back(wr);
00173 
00174         float ms_range = ds[i].max_ms - ds[i].min_ms;
00175         float ms = (float)ds[i].min_ms +
00176           (ms_range * rand() / (RAND_MAX + 1.0));
00177         now += ms / 1000.0;
00178         total_ms += ms;
00179 
00180         wr._time = now + jitter_ms / 1000.0;
00181         wr._start = false;
00182         wait.push_back(wr);
00183       }
00184     }
00185 
00186     // Put the wait requests in order, to allow for the jitter, and
00187     // invoke them.
00188     sort(wait.begin(), wait.end());
00189     Wait::const_iterator wi;
00190     for (wi = wait.begin(); wi != wait.end(); ++wi) {
00191       const WaitRequest &wr = (*wi);
00192       if (wr._start) {
00193         _collectors[wr._index].start(client->get_main_thread(), wr._time);
00194       } else {
00195         _collectors[wr._index].stop(client->get_main_thread(), wr._time);
00196       }
00197     }
00198 
00199     // Now actually wait some approximation of the time we said we
00200     // did.
00201     PRIntervalTime sleep_timeout =
00202       PR_MillisecondsToInterval((int)total_ms + 5);
00203     PR_Sleep(sleep_timeout);
00204   }
00205 
00206   return (0);
00207 }

Generated on Fri May 2 00:43:28 2003 for Panda by doxygen1.3