Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: webrtc/api/rtcstats.h

Issue 2241093002: RTCStats and RTCStatsReport added (webrtc/stats) (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Updated comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifndef WEBRTC_API_RTCSTATS_H_
12 #define WEBRTC_API_RTCSTATS_H_
13
14 #include <map>
15 #include <memory>
16 #include <string>
17 #include <utility>
18 #include <vector>
19
20 #include "webrtc/base/checks.h"
21
22 namespace webrtc {
23
24 class RTCStatsMemberInterface;
25
26 // Abstract base class for RTCStats-derived dictionaries, see
27 // https://w3c.github.io/webrtc-stats/.
28 //
29 // All derived classes must have the following static variable defined:
30 // static const char* const kType;
31 // The address of |kType| is used as a unique class identifier and the value as
32 // a string representation of the class type, see
33 // https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
34 // Use the |WEBRTC_RTCSTATS_IMPL| macro when implementing subclasses, see macro
35 // for details.
36 //
37 // Derived classes list their dictionary members, RTCStatsMember<T>, as public
38 // fields, allowing the following:
39 //
40 // RTCFooStats foo("fooId", GetCurrentTime());
41 // foo.bar = 42;
42 // foo.baz = std::vector<std::string>();
43 // foo.baz->push_back("hello world");
44 // uint32_t x = *foo.bar;
45 //
46 // Pointers to all the members are available with |Members|, allowing iteration:
47 //
48 // for (const RTCStatsMemberInterface* member : foo.Members()) {
49 // printf("%s = %s\n", member->name(), member->ValueToString().c_str());
50 // }
51 class RTCStats {
52 public:
53 RTCStats(const std::string& id, double timestamp)
54 : id_(id), timestamp_(timestamp) {}
55 RTCStats(std::string&& id, double timestamp)
56 : id_(std::move(id)), timestamp_(timestamp) {}
57 virtual ~RTCStats() {}
58
59 virtual std::unique_ptr<RTCStats> copy() const = 0;
60
61 const std::string& id() const { return id_; }
62 // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in seconds.
63 double timestamp() const { return timestamp_; }
64 // Returns the address of the static |kType| variable of the implementing
65 // class. Comparing it to |&T::kType| tests if a stats object is of type |T|.
66 virtual const char* const* type() const = 0;
67 // Returns the value of the static |kType| variable of the implementing class.
68 virtual const char* type_name() const = 0;
69 // Returns a vector of pointers to all the RTCStatsMemberInterface members of
70 // this class. This allows for iteration of members.
71 std::vector<const RTCStatsMemberInterface*> Members() const;
72
73 // Creates a human readable string representation of the report, listing all
74 // of its members (names and values).
75 std::string ToString() const;
76
77 // Downcasts the stats object to an |RTCStats| subclass |T|. DCHECKs that the
78 // object is of type |T|.
79 template<typename T>
80 T& cast_to() {
81 RTC_DCHECK_EQ(type(), &T::kType);
82 return static_cast<T&>(*this);
83 }
84 template<typename T>
85 T& cast_to() const {
86 RTC_DCHECK_EQ(type(), &T::kType);
87 return static_cast<T&>(*this);
88 }
89
90 protected:
91 // Gets a vector of all members of this |RTCStats| object, including members
92 // derived from parent classes. |additional_capacity| is how many more members
93 // shall be reserved in the vector (so that subclasses can allocate a vector
94 // with room for both parent and child members without it having to resize).
95 virtual std::vector<const RTCStatsMemberInterface*> ThisMembers(
96 size_t additional_capacity) const;
97
98 std::string const id_;
99 double timestamp_;
100 };
101
102 // All |RTCStats| classes should use this macro in a public section of the class
103 // definition.
hta-webrtc 2016/08/22 07:01:53 The macro starts with "public", so it doesn't have
hbos 2016/08/22 15:17:36 But the macro changes the protection level (? -> p
104 //
105 // This macro declares the static |kType| and overrides methods as required by
106 // subclasses of |RTCStats|: |copy|, |type|, |type_name| and |ThisMembers|.
107 // The |...| argument is a list of addresses to each member defined in the
108 // implementing class (list cannot be empty, must have at least one new member).
109 //
110 // (Since class names need to be known to implement these methods this cannot be
111 // part of the base |RTCStats|. While these methods could be implemented using
112 // templates, that would only work for immediate subclasses. Subclasses of
113 // subclasses also have to override these methods, resulting in boilerplate
114 // code. Using a macro avoids this and works for any |RTCStats| class, including
115 // grandchildren.)
116 //
117 // Sample usage:
118 //
119 // rtcfoostats.h:
120 // class RTCFooStats : public RTCStats {
121 // public:
122 // RTCFooStats(const std::string& id, double timestamp)
123 // : RTCStats(id, timestamp),
124 // foo("foo"),
125 // bar("bar") {
126 // }
127 //
128 // WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats,
129 // &foo,
130 // &bar);
131 //
132 // RTCStatsMember<int32_t> foo;
133 // RTCStatsMember<int32_t> bar;
134 // };
135 //
136 // rtcfoostats.cc:
137 // const char* const RTCFooStats::kType = "foo-stats";
138 //
139 #define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, ...) \
hta-webrtc 2016/08/22 07:01:53 Argh. This is a macro, and it's a macro in an .h f
hbos 2016/08/22 15:17:36 I'll ask nisse to take a look.
140 public: \
141 static const char* const kType; \
142 std::unique_ptr<webrtc::RTCStats> copy() const override { \
143 return std::unique_ptr<webrtc::RTCStats>(new this_class(*this)); \
144 } \
145 const char* const* type() const override { return &this_class::kType; } \
hta-webrtc 2016/08/22 07:01:53 Is it possible to use "typeof(this)" or some such
hbos 2016/08/22 15:17:36 Hmm.. I don't think that is possible, and we don't
146 const char* type_name() const override { return this_class::kType; } \
147 protected: \
148 std::vector<const webrtc::RTCStatsMemberInterface*> ThisMembers( \
hta-webrtc 2016/08/22 07:01:53 ThisMembers is such an ugly name. What about Membe
hbos 2016/08/22 15:17:36 Done.
149 size_t additional_capacity) const override { \
150 const webrtc::RTCStatsMemberInterface* members[] = { \
151 __VA_ARGS__ \
152 }; \
153 size_t members_count = sizeof(members) / sizeof(members[0]); \
154 std::vector<const webrtc::RTCStatsMemberInterface*> members_vec = \
155 parent_class::ThisMembers(additional_capacity + members_count); \
156 members_vec.insert(members_vec.end(), \
157 &members[0], &members[members_count]); \
158 return members_vec; \
159 } \
160 public:
161
162 // Interface for |RTCStats| members, which have a name and an optional value.
hta-webrtc 2016/08/22 07:01:53 Value type, not value? I don't think "optional" is
hbos 2016/08/22 15:17:36 Updated comment. (By optional I meant that the val
163 // The value type is implementation-specific. Only the types listed in |Type|
164 // are supported, these are implemented by |RTCStatsMember<T>|.
165 class RTCStatsMemberInterface {
166 public:
167 // Member value types.
168 enum Type {
169 kInt32, // int32_t
170 kUint32, // uint32_t
171 kInt64, // int64_t
172 kUint64, // uint64_t
173 kDouble, // double
174 kStaticString, // const char*
175 kString, // std::string
176
177 kSequenceInt32, // std::vector<int32_t>
178 kSequenceUint32, // std::vector<uint32_t>
179 kSequenceInt64, // std::vector<int64_t>
180 kSequenceUint64, // std::vector<uint64_t>
181 kSequenceDouble, // std::vector<double>
182 kSequenceStaticString, // std::vector<const char*>
183 kSequenceString, // std::vector<std::string>
184 };
185
186 virtual ~RTCStatsMemberInterface() {}
187
188 const char* name() const { return name_; }
189 virtual Type type() const = 0;
190 virtual bool is_sequence() const = 0;
191 virtual bool is_string() const = 0; // true for sequences of strings too.
192 bool is_defined() const { return is_defined_; }
193 virtual std::string ValueToString() const = 0;
194
195 template<typename T>
196 T& cast_to() const {
197 RTC_DCHECK_EQ(type(), T::kType);
198 return static_cast<T&>(*this);
199 }
200
201 protected:
202 RTCStatsMemberInterface(const char* name, bool is_defined)
203 : name_(name), is_defined_(is_defined) {}
204
205 const char* const name_;
206 bool is_defined_;
207 };
208
209 // Template implementation of |RTCStatsMemberInterface|. Every possible |T| is
210 // specialized in rtcstats.cc, using a different |T| results in a linker error
211 // (undefined reference to |kType|). The supported types are the ones described
212 // by |RTCStatsMemberInterface::Type|.
213 template<typename T>
214 class RTCStatsMember : public RTCStatsMemberInterface {
215 public:
216 static const Type kType;
217
218 explicit RTCStatsMember(const char* name)
219 : RTCStatsMemberInterface(name, false),
220 value_() {}
221 RTCStatsMember(const char* name, const T& value)
222 : RTCStatsMemberInterface(name, true),
223 value_(value) {}
224 RTCStatsMember(const char* name, T&& value)
225 : RTCStatsMemberInterface(name, true),
226 value_(std::move(value)) {}
227 explicit RTCStatsMember(const RTCStatsMember<T>& other)
228 : RTCStatsMemberInterface(other.name_, other.is_defined_),
229 value_(other.value_) {}
230 explicit RTCStatsMember(RTCStatsMember<T>&& other)
231 : RTCStatsMemberInterface(other.name_, other.is_defined_),
232 value_(std::move(other.value_)) {}
233
234 Type type() const override { return kType; }
235 bool is_sequence() const override;
236 bool is_string() const override;
237 std::string ValueToString() const override;
238
239 // Assignment operators.
240 T& operator=(const T& value) {
241 value_ = value;
242 is_defined_ = true;
243 return value_;
244 }
245 T& operator=(const T&& value) {
246 value_ = std::move(value);
247 is_defined_ = true;
248 return value_;
249 }
250 T& operator=(const RTCStatsMember<T>& other) {
251 RTC_DCHECK(other.is_defined_);
252 value_ = other.is_defined_;
253 is_defined_ = true;
254 return value_;
255 }
256
257 // Value getters.
258 T& operator*() {
259 RTC_DCHECK(is_defined_);
260 return value_;
261 }
262 const T& operator*() const {
263 RTC_DCHECK(is_defined_);
264 return value_;
265 }
266
267 // Value getters, arrow operator.
268 T* operator->() {
269 RTC_DCHECK(is_defined_);
270 return &value_;
271 }
272 const T* operator->() const {
273 RTC_DCHECK(is_defined_);
274 return &value_;
275 }
276
277 private:
278 T value_;
279 };
280
281 } // namespace webrtc
282
283 #endif // WEBRTC_API_RTCSTATS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698