mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-20 00:57:49 +01:00

Bug: webrtc:342905193 No-Try: True Change-Id: Icc968be43b8830038ea9a1f5f604307220457807 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361021 Auto-Submit: Florent Castelli <orphis@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Florent Castelli <orphis@webrtc.org> Cr-Commit-Position: refs/heads/main@{#42911}
194 lines
7.9 KiB
C++
194 lines
7.9 KiB
C++
/*
|
|
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef API_STATS_RTC_STATS_H_
|
|
#define API_STATS_RTC_STATS_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <map>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "api/stats/attribute.h"
|
|
#include "api/units/timestamp.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/system/rtc_export.h"
|
|
#include "rtc_base/system/rtc_export_template.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// Abstract base class for RTCStats-derived dictionaries, see
|
|
// https://w3c.github.io/webrtc-stats/.
|
|
//
|
|
// All derived classes must have the following static variable defined:
|
|
// static const char kType[];
|
|
// It is used as a unique class identifier and a string representation of the
|
|
// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
|
|
// Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
|
|
// for details.
|
|
//
|
|
// Derived classes list their dictionary attributes, std::optional<T>, as
|
|
// public fields, allowing the following:
|
|
//
|
|
// RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
|
|
// foo.bar = 42;
|
|
// foo.baz = std::vector<std::string>();
|
|
// foo.baz->push_back("hello world");
|
|
// uint32_t x = *foo.bar;
|
|
//
|
|
// Pointers to all the attributes are available with `Attributes()`, allowing
|
|
// iteration:
|
|
//
|
|
// for (const auto& attribute : foo.Attributes()) {
|
|
// printf("%s = %s\n", attribute.name(), attribute.ToString().c_str());
|
|
// }
|
|
class RTC_EXPORT RTCStats {
|
|
public:
|
|
RTCStats(const std::string& id, Timestamp timestamp)
|
|
: id_(id), timestamp_(timestamp) {}
|
|
RTCStats(const RTCStats& other);
|
|
virtual ~RTCStats();
|
|
|
|
virtual std::unique_ptr<RTCStats> copy() const = 0;
|
|
|
|
const std::string& id() const { return id_; }
|
|
// Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
|
|
Timestamp timestamp() const { return timestamp_; }
|
|
|
|
// Returns the static member variable `kType` of the implementing class.
|
|
virtual const char* type() const = 0;
|
|
// Returns all attributes of this stats object, i.e. a list of its individual
|
|
// metrics as viewed via the Attribute wrapper.
|
|
std::vector<Attribute> Attributes() const;
|
|
template <typename T>
|
|
Attribute GetAttribute(const std::optional<T>& stat) const {
|
|
for (const auto& attribute : Attributes()) {
|
|
if (!attribute.holds_alternative<T>()) {
|
|
continue;
|
|
}
|
|
if (absl::get<const std::optional<T>*>(attribute.as_variant()) == &stat) {
|
|
return attribute;
|
|
}
|
|
}
|
|
RTC_CHECK_NOTREACHED();
|
|
}
|
|
// Checks if the two stats objects are of the same type and have the same
|
|
// attribute values. Timestamps are not compared. These operators are exposed
|
|
// for testing.
|
|
bool operator==(const RTCStats& other) const;
|
|
bool operator!=(const RTCStats& other) const;
|
|
|
|
// Creates a JSON readable string representation of the stats
|
|
// object, listing all of its attributes (names and values).
|
|
std::string ToJson() const;
|
|
|
|
// Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
|
|
// object is of type `T`.
|
|
template <typename T>
|
|
const T& cast_to() const {
|
|
RTC_DCHECK_EQ(type(), T::kType);
|
|
return static_cast<const T&>(*this);
|
|
}
|
|
|
|
protected:
|
|
virtual std::vector<Attribute> AttributesImpl(
|
|
size_t additional_capacity) const;
|
|
|
|
std::string const id_;
|
|
Timestamp timestamp_;
|
|
};
|
|
|
|
// All `RTCStats` classes should use these macros.
|
|
// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
|
|
// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
|
|
//
|
|
// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
|
|
// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
|
|
// `AttributesImpl`. The |...| argument is a list of addresses to each attribute
|
|
// defined in the implementing class. The list must have at least one attribute.
|
|
//
|
|
// (Since class names need to be known to implement these methods this cannot be
|
|
// part of the base `RTCStats`. While these methods could be implemented using
|
|
// templates, that would only work for immediate subclasses. Subclasses of
|
|
// subclasses also have to override these methods, resulting in boilerplate
|
|
// code. Using a macro avoids this and works for any `RTCStats` class, including
|
|
// grandchildren.)
|
|
//
|
|
// Sample usage:
|
|
//
|
|
// rtcfoostats.h:
|
|
// class RTCFooStats : public RTCStats {
|
|
// public:
|
|
// WEBRTC_RTCSTATS_DECL();
|
|
//
|
|
// RTCFooStats(const std::string& id, Timestamp timestamp);
|
|
//
|
|
// std::optional<int32_t> foo;
|
|
// std::optional<int32_t> bar;
|
|
// };
|
|
//
|
|
// rtcfoostats.cc:
|
|
// WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
|
|
// &foo,
|
|
// &bar);
|
|
//
|
|
// RTCFooStats::RTCFooStats(const std::string& id, Timestamp timestamp)
|
|
// : RTCStats(id, timestamp),
|
|
// foo("foo"),
|
|
// bar("bar") {
|
|
// }
|
|
//
|
|
#define WEBRTC_RTCSTATS_DECL() \
|
|
protected: \
|
|
std::vector<webrtc::Attribute> AttributesImpl(size_t additional_capacity) \
|
|
const override; \
|
|
\
|
|
public: \
|
|
static const char kType[]; \
|
|
\
|
|
std::unique_ptr<webrtc::RTCStats> copy() const override; \
|
|
const char* type() const override
|
|
|
|
#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...) \
|
|
const char this_class::kType[] = type_str; \
|
|
\
|
|
std::unique_ptr<webrtc::RTCStats> this_class::copy() const { \
|
|
return std::make_unique<this_class>(*this); \
|
|
} \
|
|
\
|
|
const char* this_class::type() const { \
|
|
return this_class::kType; \
|
|
} \
|
|
\
|
|
std::vector<webrtc::Attribute> this_class::AttributesImpl( \
|
|
size_t additional_capacity) const { \
|
|
webrtc::AttributeInit attribute_inits[] = {__VA_ARGS__}; \
|
|
size_t attribute_inits_size = \
|
|
sizeof(attribute_inits) / sizeof(attribute_inits[0]); \
|
|
std::vector<webrtc::Attribute> attributes = parent_class::AttributesImpl( \
|
|
attribute_inits_size + additional_capacity); \
|
|
for (size_t i = 0; i < attribute_inits_size; ++i) { \
|
|
attributes.push_back(absl::visit( \
|
|
[&](const auto* field) { \
|
|
return Attribute(attribute_inits[i].name, field); \
|
|
}, \
|
|
attribute_inits[i].variant)); \
|
|
} \
|
|
return attributes; \
|
|
}
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // API_STATS_RTC_STATS_H_
|