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

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: #if condition for EXPECT_DEATH tests Created 4 years, 3 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;
nisse-webrtc 2016/08/23 08:27:28 Do you really need to return a pointer to a pointe
hbos 2016/08/23 16:21:17 Done. (You're right, const char[] works but not co
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);
nisse-webrtc 2016/08/23 08:27:28 I would expect that you don't do cast and then mod
hbos 2016/08/23 16:21:18 With a const return value on the other |cast_to| m
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);
nisse-webrtc 2016/08/23 08:27:28 And this one really ought to have a const return v
hbos 2016/08/23 16:21:17 Done.
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*>
96 MembersOfThisObjectAndAncestors(
97 size_t additional_capacity) const;
98
99 std::string const id_;
100 double timestamp_;
101 };
102
103 // All |RTCStats| classes should use this macro in a public section of the class
104 // definition.
105 //
106 // This macro declares the static |kType| and overrides methods as required by
107 // subclasses of |RTCStats|: |copy|, |type|, |type_name| and
108 // |MembersOfThisObjectAndAncestors|. The |...| argument is a list of addresses
109 // to each member defined in the implementing class (list cannot be empty, must
110 // have at least one new member).
111 //
112 // (Since class names need to be known to implement these methods this cannot be
113 // part of the base |RTCStats|. While these methods could be implemented using
114 // templates, that would only work for immediate subclasses. Subclasses of
115 // subclasses also have to override these methods, resulting in boilerplate
116 // code. Using a macro avoids this and works for any |RTCStats| class, including
117 // grandchildren.)
118 //
119 // Sample usage:
120 //
121 // rtcfoostats.h:
122 // class RTCFooStats : public RTCStats {
123 // public:
124 // RTCFooStats(const std::string& id, double timestamp)
125 // : RTCStats(id, timestamp),
126 // foo("foo"),
127 // bar("bar") {
128 // }
129 //
130 // WEBRTC_RTCSTATS_IMPL(RTCStats, RTCFooStats,
131 // &foo,
132 // &bar);
133 //
134 // RTCStatsMember<int32_t> foo;
135 // RTCStatsMember<int32_t> bar;
136 // };
137 //
138 // rtcfoostats.cc:
139 // const char* const RTCFooStats::kType = "foo-stats";
140 //
141 #define WEBRTC_RTCSTATS_IMPL(parent_class, this_class, ...) \
nisse-webrtc 2016/08/23 08:27:28 You have checked that variadic macros, with ..., a
hbos 2016/08/23 16:21:18 Yes, it is used by other code (e.g. webrtc/base/lo
142 public: \
143 static const char* const kType; \
nisse-webrtc 2016/08/23 08:27:28 As above, I'd suggest making this static const
hbos 2016/08/23 16:21:18 Unfortunately, the variable can only be declared i
144 std::unique_ptr<webrtc::RTCStats> copy() const override { \
145 return std::unique_ptr<webrtc::RTCStats>(new this_class(*this)); \
146 } \
147 const char* const* type() const override { return &this_class::kType; } \
148 const char* type_name() const override { return this_class::kType; } \
149 protected: \
150 std::vector<const webrtc::RTCStatsMemberInterface*> \
151 MembersOfThisObjectAndAncestors( \
152 size_t additional_capacity) const override { \
153 const webrtc::RTCStatsMemberInterface* members[] = { \
nisse-webrtc 2016/08/23 08:27:28 In general when doing large macros, you have to ta
hbos 2016/08/23 16:21:18 Done. Nice catch. I couldn't find anything in the
154 __VA_ARGS__ \
155 }; \
156 size_t members_count = sizeof(members) / sizeof(members[0]); \
157 std::vector<const webrtc::RTCStatsMemberInterface*> members_vec = \
158 parent_class::MembersOfThisObjectAndAncestors( \
159 additional_capacity + members_count); \
nisse-webrtc 2016/08/23 08:27:28 How do you test this allocation logic? Is there so
hbos 2016/08/23 16:21:18 I added a DCHECK that ensures the capacity is enou
160 members_vec.insert(members_vec.end(), \
161 &members[0], &members[members_count]); \
nisse-webrtc 2016/08/23 08:27:28 There's an extra copy, first into the members arra
hbos 2016/08/23 16:21:18 Variadic functions come to mind, but I don't think
162 return members_vec; \
163 } \
164 public:
165
166 // Interface for |RTCStats| members, which have a name and a value of a type
167 // defined in a subclass. Only the types listed in |Type| are supported, these
168 // are implemented by |RTCStatsMember<T>|. The value of a member may be
169 // undefined, the value can only be read if |is_defined|.
170 class RTCStatsMemberInterface {
171 public:
172 // Member value types.
173 enum Type {
nisse-webrtc 2016/08/23 08:27:28 Hmm, this was a bit confusing at first. Here types
hbos 2016/08/23 16:21:18 That is correct. The RTCStats type is for RTCStat
174 kInt32, // int32_t
175 kUint32, // uint32_t
176 kInt64, // int64_t
177 kUint64, // uint64_t
178 kDouble, // double
179 kStaticString, // const char*
180 kString, // std::string
181
182 kSequenceInt32, // std::vector<int32_t>
183 kSequenceUint32, // std::vector<uint32_t>
184 kSequenceInt64, // std::vector<int64_t>
185 kSequenceUint64, // std::vector<uint64_t>
186 kSequenceDouble, // std::vector<double>
187 kSequenceStaticString, // std::vector<const char*>
188 kSequenceString, // std::vector<std::string>
189 };
190
191 virtual ~RTCStatsMemberInterface() {}
192
193 const char* name() const { return name_; }
194 virtual Type type() const = 0;
195 virtual bool is_sequence() const = 0;
196 virtual bool is_string() const = 0; // true for sequences of strings too.
nisse-webrtc 2016/08/23 08:27:28 That's kind of surprising. Why? Only use I've see
hbos 2016/08/23 16:21:17 Hmm, yeah, strange decision, I'll make it false in
197 bool is_defined() const { return is_defined_; }
198 virtual std::string ValueToString() const = 0;
199
200 template<typename T>
201 T& cast_to() const {
nisse-webrtc 2016/08/23 08:27:28 I think the return type should be const T&.
hbos 2016/08/23 16:21:18 Done.
202 RTC_DCHECK_EQ(type(), T::kType);
203 return static_cast<T&>(*this);
204 }
205
206 protected:
207 RTCStatsMemberInterface(const char* name, bool is_defined)
208 : name_(name), is_defined_(is_defined) {}
209
210 const char* const name_;
211 bool is_defined_;
212 };
213
214 // Template implementation of |RTCStatsMemberInterface|. Every possible |T| is
215 // specialized in rtcstats.cc, using a different |T| results in a linker error
216 // (undefined reference to |kType|). The supported types are the ones described
217 // by |RTCStatsMemberInterface::Type|.
218 template<typename T>
219 class RTCStatsMember : public RTCStatsMemberInterface {
220 public:
221 static const Type kType;
222
223 explicit RTCStatsMember(const char* name)
224 : RTCStatsMemberInterface(name, false),
225 value_() {}
226 RTCStatsMember(const char* name, const T& value)
227 : RTCStatsMemberInterface(name, true),
228 value_(value) {}
229 RTCStatsMember(const char* name, T&& value)
230 : RTCStatsMemberInterface(name, true),
231 value_(std::move(value)) {}
232 explicit RTCStatsMember(const RTCStatsMember<T>& other)
233 : RTCStatsMemberInterface(other.name_, other.is_defined_),
234 value_(other.value_) {}
235 explicit RTCStatsMember(RTCStatsMember<T>&& other)
236 : RTCStatsMemberInterface(other.name_, other.is_defined_),
237 value_(std::move(other.value_)) {}
238
239 Type type() const override { return kType; }
240 bool is_sequence() const override;
241 bool is_string() const override;
242 std::string ValueToString() const override;
243
244 // Assignment operators.
245 T& operator=(const T& value) {
246 value_ = value;
247 is_defined_ = true;
248 return value_;
249 }
250 T& operator=(const T&& value) {
251 value_ = std::move(value);
252 is_defined_ = true;
253 return value_;
254 }
255 T& operator=(const RTCStatsMember<T>& other) {
256 RTC_DCHECK(other.is_defined_);
257 value_ = other.is_defined_;
258 is_defined_ = true;
259 return value_;
260 }
261
262 // Value getters.
263 T& operator*() {
264 RTC_DCHECK(is_defined_);
265 return value_;
266 }
267 const T& operator*() const {
268 RTC_DCHECK(is_defined_);
269 return value_;
270 }
271
272 // Value getters, arrow operator.
273 T* operator->() {
274 RTC_DCHECK(is_defined_);
275 return &value_;
276 }
277 const T* operator->() const {
278 RTC_DCHECK(is_defined_);
279 return &value_;
280 }
281
282 private:
283 T value_;
284 };
285
286 } // namespace webrtc
287
288 #endif // WEBRTC_API_RTCSTATS_H_
OLDNEW
« no previous file with comments | « webrtc/api/api.gyp ('k') | webrtc/api/rtcstatsreport.h » ('j') | webrtc/stats/rtcstats.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698