1 #pragma once
2 
3 #include <type_traits>
4 
5 #include "tracing/categories.h"
6 
7 namespace tracing {
8 
9 class MonitorBase {
10  protected:
11 	const char* _name;
12 	Category _tracing_cat;
13 
14 	void valueChanged(float newVal);
15 
16  public:
17 	MonitorBase(const char* name);
18 
19 	// Disallow any copy or movement
20 	MonitorBase(const MonitorBase&) = delete;
21 	MonitorBase& operator=(const MonitorBase&) = delete;
22 
23 	MonitorBase(MonitorBase&&) = delete;
24 	MonitorBase& operator=(MonitorBase&&) = delete;
25 };
26 
27 template<typename T>
28 class Monitor: public MonitorBase {
29 	T _value;
30 
31 	static_assert(std::is_convertible<T, float>::value, "Monitor values must be convertible to float!");
32  public:
Monitor(const char * name,const T & defaultVal)33 	Monitor(const char* name, const T& defaultVal) : MonitorBase(name), _value(defaultVal) {
34 	}
35 
changeValue(const T & val)36 	void changeValue(const T& val) {
37 		_value = val;
38 		valueChanged(_value);
39 	}
40 
41 	Monitor<T>& operator=(const T& val) {
42 		changeValue(val);
43 		return *this;
44 	}
45 
46 	Monitor<T>& operator+=(const T& val) {
47 		_value += val;
48 		valueChanged((float)_value);
49 
50 		return *this;
51 	}
52 
53 	Monitor<T>& operator-=(const T& val) {
54 		_value -= val;
55 		valueChanged((float)_value);
56 
57 		return *this;
58 	}
59 };
60 
61 /**
62  * @brief Class that keeps track of how many operations are currently running
63  */
64 class RunningCounter {
65 	Monitor<int>& _monitor;
66 
67   public:
68 	explicit RunningCounter(Monitor<int>& monitor);
69 	~RunningCounter();
70 
71 	RunningCounter(const RunningCounter&);
72 	RunningCounter& operator=(const RunningCounter&);
73 
74 	RunningCounter(RunningCounter&&) noexcept;
75 	RunningCounter& operator=(RunningCounter&&) noexcept;
76 };
77 
78 } // namespace tracing
79 
80 // Creates a monitor variable
81 #define MONITOR(function_name)				static ::tracing::Monitor<int> mon_##function_name(#function_name, 0);
82 
83 // Increments a monitor variable
84 #define MONITOR_INC(function_name, inc)		do { mon_##function_name += (inc); } while(false)
85 
86 
87