blob: e33d3efe07dc83f2c85518e0713be81510e86163 [file] [log] [blame]
andresp@webrtc.org6b68c282013-05-13 08:06:36 +00001/*
2 * Copyright (c) 2013 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
andrew@webrtc.org61e596f2013-07-25 18:28:29 +000011#ifndef WEBRTC_COMMON_H_
12#define WEBRTC_COMMON_H_
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000013
14#include <map>
15
Andrew MacDonald469c2c02015-05-22 17:50:26 -070016#include "webrtc/base/basictypes.h"
17
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000018namespace webrtc {
19
aluebs688e3082016-01-14 04:32:46 -080020// Only add new values to the end of the enumeration and never remove (only
21// deprecate) to maintain binary compatibility.
22enum class ConfigOptionID {
23 kMyExperimentForTest,
24 kAlgo1CostFunctionForTest,
25 kTemporalLayersFactory,
26 kNetEqCapacityConfig,
27 kNetEqFastAccelerate,
28 kVoicePacing,
29 kExtendedFilter,
30 kDelayAgnostic,
31 kExperimentalAgc,
32 kExperimentalNs,
33 kBeamforming,
peaha332e2d2016-02-17 01:11:16 -080034 kIntelligibility,
35 kNextGenerationAec
aluebs688e3082016-01-14 04:32:46 -080036};
37
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000038// Class Config is designed to ease passing a set of options across webrtc code.
39// Options are identified by typename in order to avoid incorrect casts.
40//
41// Usage:
42// * declaring an option:
43// struct Algo1_CostFunction {
44// virtual float cost(int x) const { return x; }
45// virtual ~Algo1_CostFunction() {}
46// };
47//
48// * accessing an option:
49// config.Get<Algo1_CostFunction>().cost(value);
50//
51// * setting an option:
52// struct SqrCost : Algo1_CostFunction {
53// virtual float cost(int x) const { return x*x; }
54// };
55// config.Set<Algo1_CostFunction>(new SqrCost());
56//
57// Note: This class is thread-compatible (like STL containers).
58class Config {
59 public:
60 // Returns the option if set or a default constructed one.
andrew@webrtc.org61e596f2013-07-25 18:28:29 +000061 // Callers that access options too often are encouraged to cache the result.
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000062 // Returned references are owned by this.
63 //
64 // Requires std::is_default_constructible<T>
65 template<typename T> const T& Get() const;
66
67 // Set the option, deleting any previous instance of the same.
andrew@webrtc.org61e596f2013-07-25 18:28:29 +000068 // This instance gets ownership of the newly set value.
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000069 template<typename T> void Set(T* value);
70
71 Config() {}
72 ~Config() {
73 // Note: this method is inline so webrtc public API depends only
74 // on the headers.
75 for (OptionMap::iterator it = options_.begin();
76 it != options_.end(); ++it) {
77 delete it->second;
78 }
79 }
80
81 private:
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000082 struct BaseOption {
83 virtual ~BaseOption() {}
84 };
85
86 template<typename T>
87 struct Option : BaseOption {
88 explicit Option(T* v): value(v) {}
89 ~Option() {
90 delete value;
91 }
92 T* value;
93 };
94
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000095 template<typename T>
aluebs688e3082016-01-14 04:32:46 -080096 static ConfigOptionID identifier() {
97 return T::identifier;
andresp@webrtc.org6b68c282013-05-13 08:06:36 +000098 }
99
100 // Used to instantiate a default constructed object that doesn't needs to be
101 // owned. This allows Get<T> to be implemented without requiring explicitly
102 // locks.
103 template<typename T>
104 static const T& default_value() {
Andrew MacDonald469c2c02015-05-22 17:50:26 -0700105 RTC_DEFINE_STATIC_LOCAL(const T, def, ());
andresp@webrtc.org6b68c282013-05-13 08:06:36 +0000106 return def;
107 }
108
aluebs688e3082016-01-14 04:32:46 -0800109 typedef std::map<ConfigOptionID, BaseOption*> OptionMap;
andresp@webrtc.org6b68c282013-05-13 08:06:36 +0000110 OptionMap options_;
111
henrikg3c089d72015-09-16 05:37:44 -0700112 // RTC_DISALLOW_COPY_AND_ASSIGN
andresp@webrtc.org6b68c282013-05-13 08:06:36 +0000113 Config(const Config&);
114 void operator=(const Config&);
115};
116
117template<typename T>
118const T& Config::Get() const {
119 OptionMap::const_iterator it = options_.find(identifier<T>());
120 if (it != options_.end()) {
121 const T* t = static_cast<Option<T>*>(it->second)->value;
122 if (t) {
123 return *t;
124 }
125 }
126 return default_value<T>();
127}
128
129template<typename T>
130void Config::Set(T* value) {
131 BaseOption*& it = options_[identifier<T>()];
132 delete it;
133 it = new Option<T>(value);
134}
andrew@webrtc.org61e596f2013-07-25 18:28:29 +0000135
andresp@webrtc.org6b68c282013-05-13 08:06:36 +0000136} // namespace webrtc
andrew@webrtc.org61e596f2013-07-25 18:28:29 +0000137
138#endif // WEBRTC_COMMON_H_