OpenClonk
C4Network2Stats.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2005-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2013-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // network statistics and information dialogs
17 
18 #ifndef INC_C4Network2Stats
19 #define INC_C4Network2Stats
20 
21 #include "game/C4Application.h"
22 
23 // (int) value by time function
24 class C4Graph
25 {
26 public:
27  typedef float ValueType;
28  typedef int TimeType;
29 
30 private:
31  StdStrBuf szTitle;
32  DWORD dwColor{0x7fff0000};
33 
34 public:
35  C4Graph();
36  virtual ~C4Graph() = default;
37 
38  void SetTitle(const char *szNewTitle) { szTitle.Copy(szNewTitle); }
39  void SetColorDw(DWORD dwClr) { dwColor = dwClr; }
40 
41  // retrieve timeframe covered by backlog
42  virtual TimeType GetStartTime() const = 0; // inclusively
43  virtual TimeType GetEndTime() const = 0; // exclusively
44 
45  // retrieve values within backlog timeframe - guarantueed to be working inside [GetStartTime(), GetEndTime()[
46  virtual ValueType GetValue(TimeType iAtTime) const = 0;
47  virtual ValueType GetMedianValue(TimeType iStartTime, TimeType iEndTime) const = 0; // median within [iStartTime, iEndTime[
48  virtual ValueType GetMinValue() const = 0;
49  virtual ValueType GetMaxValue() const = 0;
50 
51  // base graph has always just one series (self)
52  virtual int GetSeriesCount() const = 0;
53  virtual const C4Graph *GetSeries(int iIndex) const = 0;
54 
55  DWORD GetColorDw() const { return dwColor; }
56  const char *GetTitle() const { return szTitle.getData(); }
57 
58  // called before drawing procedure: Make sure graph values are up-to-date
59  virtual void Update() const {}
60 
61  virtual void SetAverageTime(int iToTime) = 0;
62  virtual void SetMultiplier(ValueType fToVal) = 0;
63 };
64 
65 // Standard graph: Assume constant time and one call each time frame
66 class C4TableGraph : public C4Graph
67 {
68 private:
69  // recorded backlog
70  int iBackLogLength;
71  ValueType *pValues{nullptr};
72  ValueType fMultiplier{1}; // multiplicative factor used for all value returns
73  mutable ValueType *pAveragedValues{nullptr}; // equals pValues if no average is being calculated
74 
75  // currently valid backlog timeframe
76  int iBackLogPos{0}; // position of next entry to be written
77  bool fWrapped{false}; // if true, the buffer has been cycled already
78 
79  TimeType iInitialStartTime; // initial table start time; used to calc offset in buffer
80  TimeType iTime; // next timeframe to be recorded
81  mutable TimeType iAveragedTime; // last timeframe for which average has been calculated
82  StdStrBuf szDumpFile; // if set, the buffer is dumped to file regularly
83  TimeType iAvgRange{1}; // range used for averaging
84 
85 public:
86  enum { DefaultBlockLength = 256 }; // default backlog
87 
88  C4TableGraph(int iBackLogLength=DefaultBlockLength, TimeType iStartTime = 0);
89  ~C4TableGraph() override;
90 
91  // flush dump; reset time, etc
92  void Reset(TimeType iToTime);
93 
94  void SetDumpFile(StdStrBuf &szFile) { szDumpFile = szFile; }
95 
96  // retrieve timeframe covered by backlog
97  TimeType GetStartTime() const override; // inclusively
98  TimeType GetEndTime() const override; // exclusively
99 
100  // retrieve values within backlog timeframe - guarantueed to be working inside [GetStartTime(), GetEndTime()[
101  ValueType GetValue(TimeType iAtTime) const override; // retrieve averaged value!
102  ValueType GetAtValue(TimeType iAtTime) const; // retrieve not-averaged value
103  void SetAvgValue(TimeType iAtTime, ValueType iValue) const; // overwrite avg value at time - considered const because it modifies mutable only
104  ValueType GetMedianValue(TimeType iStartTime, TimeType iEndTime) const override; // median within [iStartTime, iEndTime[
105  ValueType GetMinValue() const override;
106  ValueType GetMaxValue() const override;
107 
108  // record a value for this frame; increases time by one
109  void RecordValue(ValueType iValue);
110 
111  // write table to file
112  virtual bool DumpToFile(const StdStrBuf &rszFilename, bool fAppend) const;
113 
114  // base graph has always just one series (self)
115  int GetSeriesCount() const override { return 1; }
116  const C4Graph *GetSeries(int iIndex) const override { return iIndex ? nullptr : this; }
117 
118  void SetAverageTime(int iToTime) override;
119  void Update() const override; // make sure average times are correctly calculated
120 
121  void SetMultiplier(ValueType fToVal) override { fMultiplier = fToVal; }
122 };
123 
124 // A graph collection; grouping similar graphs
125 // Does not delete graph pointers
126 class C4GraphCollection : public C4Graph, private std::vector<C4Graph *>
127 {
128 private:
129  // if 0, keep individual for each graph
130  int iCommonAvgTime{0};
131  ValueType fMultiplier{0};
132 public:
133  C4GraphCollection() = default;
134 
135  // retrieve max timeframe covered by all graphs
136  C4Graph::TimeType GetStartTime() const override;
137  C4Graph::TimeType GetEndTime() const override;
138 
139  // must be called on base series only!
140  C4Graph::ValueType GetValue(C4Graph::TimeType iAtTime) const override { assert(0); return 0; }
141  C4Graph::ValueType GetMedianValue(C4Graph::TimeType iStartTime, C4Graph::TimeType iEndTime) const override { assert(0); return 0; }
142 
143  // get overall min/max for all series
144  C4Graph::ValueType GetMinValue() const override;
145  C4Graph::ValueType GetMaxValue() const override;
146 
147  // retrieve child (or grandchild) graphs
148  int GetSeriesCount() const override;
149  const C4Graph *GetSeries(int iIndex) const override;
150 
151  void AddGraph(C4Graph *pAdd) { push_back(pAdd); if (iCommonAvgTime) pAdd->SetAverageTime(iCommonAvgTime); if (fMultiplier) pAdd->SetMultiplier(fMultiplier); }
152  void RemoveGraph(const C4Graph *pRemove) { iterator i=std::find(begin(), end(), pRemove); if (i!=end()) erase(i); }
153 
154  // update all children
155  void Update() const override;
156 
157  // force values for all children
158  void SetAverageTime(int iToTime) override;
159  void SetMultiplier(ValueType fToVal) override;
160 };
161 
162 // network stat collection wrapper
164 {
165 private:
166 
167  // per-frame stats
168  C4TableGraph statObjCount;
169 
170  // per-second stats
171  C4TableGraph statFPS;
172 
173  // overall network i/o
174  C4TableGraph statNetI, statNetO;
175  C4GraphCollection graphNetIO;
176 
177 protected:
178  C4GraphCollection statPings; // for all clients
179 
180  // per-controlframe stats
183 
184  int SecondCounter; // seconds passed in measured time by network stats module
185  int ControlCounter; // control frames passed in measured time by network stats module
186 
187  friend class C4Player;
188  friend class C4Network2Client;
189 
190 public:
191  C4Network2Stats();
192  ~C4Network2Stats() override;
193 
194  // periodic callbacks
195  void ExecuteFrame();
196  void ExecuteSecond();
197  void ExecuteControlFrame();
198 
199  void OnSec1Timer() override { ExecuteSecond(); }
200 
201  C4Graph *GetGraphByName(const StdStrBuf &rszName, bool &rfIsTemp);
202 };
203 
204 #endif // INC_C4Network2Stats
uint32_t DWORD
void Update() const override
C4Graph::TimeType GetStartTime() const override
void SetAverageTime(int iToTime) override
C4Graph::ValueType GetMedianValue(C4Graph::TimeType iStartTime, C4Graph::TimeType iEndTime) const override
int GetSeriesCount() const override
C4Graph::ValueType GetMaxValue() const override
C4Graph::TimeType GetEndTime() const override
void AddGraph(C4Graph *pAdd)
C4Graph::ValueType GetMinValue() const override
void RemoveGraph(const C4Graph *pRemove)
const C4Graph * GetSeries(int iIndex) const override
void SetMultiplier(ValueType fToVal) override
C4Graph::ValueType GetValue(C4Graph::TimeType iAtTime) const override
C4GraphCollection()=default
virtual ValueType GetMinValue() const =0
const char * GetTitle() const
virtual void SetMultiplier(ValueType fToVal)=0
virtual TimeType GetStartTime() const =0
virtual void Update() const
virtual ~C4Graph()=default
virtual TimeType GetEndTime() const =0
void SetTitle(const char *szNewTitle)
void SetColorDw(DWORD dwClr)
virtual ValueType GetValue(TimeType iAtTime) const =0
virtual ValueType GetMedianValue(TimeType iStartTime, TimeType iEndTime) const =0
virtual void SetAverageTime(int iToTime)=0
virtual const C4Graph * GetSeries(int iIndex) const =0
DWORD GetColorDw() const
virtual ValueType GetMaxValue() const =0
float ValueType
virtual int GetSeriesCount() const =0
~C4Network2Stats() override
C4GraphCollection statPings
void OnSec1Timer() override
C4GraphCollection statControls
C4GraphCollection statActions
C4Graph * GetGraphByName(const StdStrBuf &rszName, bool &rfIsTemp)
void SetAvgValue(TimeType iAtTime, ValueType iValue) const
int GetSeriesCount() const override
ValueType GetAtValue(TimeType iAtTime) const
void Reset(TimeType iToTime)
void RecordValue(ValueType iValue)
ValueType GetMedianValue(TimeType iStartTime, TimeType iEndTime) const override
C4TableGraph(int iBackLogLength=DefaultBlockLength, TimeType iStartTime=0)
void SetDumpFile(StdStrBuf &szFile)
virtual bool DumpToFile(const StdStrBuf &rszFilename, bool fAppend) const
ValueType GetMaxValue() const override
TimeType GetStartTime() const override
TimeType GetEndTime() const override
ValueType GetValue(TimeType iAtTime) const override
const C4Graph * GetSeries(int iIndex) const override
~C4TableGraph() override
void SetMultiplier(ValueType fToVal) override
void SetAverageTime(int iToTime) override
void Update() const override
ValueType GetMinValue() const override
const char * getData() const
Definition: StdBuf.h:442
void Copy()
Definition: StdBuf.h:467