|
1 /* |
|
2 * Copyright 2013 Google, Inc. |
|
3 * |
|
4 * Use of this source code is governed by a BSD-style license that can be |
|
5 * found in the LICENSE file. |
|
6 */ |
|
7 |
|
8 |
|
9 #ifndef SkRTConf_DEFINED |
|
10 #define SkRTConf_DEFINED |
|
11 |
|
12 #include "SkString.h" |
|
13 #include "SkStream.h" |
|
14 |
|
15 #include "SkTDict.h" |
|
16 #include "SkTArray.h" |
|
17 |
|
18 /** \class SkRTConfBase |
|
19 Non-templated base class for the runtime configs |
|
20 */ |
|
21 |
|
22 class SkRTConfBase { |
|
23 public: |
|
24 SkRTConfBase(const char *name) : fName(name) {} |
|
25 virtual ~SkRTConfBase() {} |
|
26 virtual const char *getName() const { return fName.c_str(); } |
|
27 virtual bool isDefault() const = 0; |
|
28 virtual void print(SkWStream *o) const = 0; |
|
29 virtual bool equals(const SkRTConfBase *conf) const = 0; |
|
30 protected: |
|
31 SkString fName; |
|
32 }; |
|
33 |
|
34 /** \class SkRTConf |
|
35 A class to provide runtime configurability. |
|
36 */ |
|
37 template<typename T> class SkRTConf: public SkRTConfBase { |
|
38 public: |
|
39 SkRTConf(const char *name, const T &defaultValue, const char *description); |
|
40 operator const T&() const { return fValue; } |
|
41 void print(SkWStream *o) const; |
|
42 bool equals(const SkRTConfBase *conf) const; |
|
43 bool isDefault() const { return fDefault == fValue; } |
|
44 void set(const T& value) { fValue = value; } |
|
45 protected: |
|
46 void doPrint(char *s) const; |
|
47 |
|
48 T fValue; |
|
49 T fDefault; |
|
50 SkString fDescription; |
|
51 }; |
|
52 |
|
53 #ifdef SK_DEVELOPER |
|
54 #define SK_CONF_DECLARE(confType, varName, confName, defaultValue, description) static SkRTConf<confType> varName(confName, defaultValue, description) |
|
55 #define SK_CONF_SET(confname, value) \ |
|
56 skRTConfRegistry().set(confname, value, true) |
|
57 /* SK_CONF_TRY_SET() is like SK_CONF_SET(), but doesn't complain if |
|
58 confname can't be found. This is useful if the SK_CONF_DECLARE is |
|
59 inside a source file whose linkage is dependent on the system. */ |
|
60 #define SK_CONF_TRY_SET(confname, value) \ |
|
61 skRTConfRegistry().set(confname, value, false) |
|
62 #else |
|
63 #define SK_CONF_DECLARE(confType, varName, confName, defaultValue, description) static confType varName = defaultValue |
|
64 #define SK_CONF_SET(confname, value) (void) confname, (void) value |
|
65 #define SK_CONF_TRY_SET(confname, value) (void) confname, (void) value |
|
66 #endif |
|
67 |
|
68 /** \class SkRTConfRegistry |
|
69 A class that maintains a systemwide registry of all runtime configuration |
|
70 parameters. Mainly used for printing them out and handling multiply-defined |
|
71 knobs. |
|
72 */ |
|
73 |
|
74 class SkRTConfRegistry { |
|
75 public: |
|
76 SkRTConfRegistry(); |
|
77 ~SkRTConfRegistry(); |
|
78 void printAll(const char *fname = NULL) const; |
|
79 bool hasNonDefault() const; |
|
80 void printNonDefault(const char *fname = NULL) const; |
|
81 const char *configFileLocation() const; |
|
82 void possiblyDumpFile() const; |
|
83 void validate() const; |
|
84 template <typename T> void set(const char *confname, |
|
85 T value, |
|
86 bool warnIfNotFound = true); |
|
87 #ifdef SK_SUPPORT_UNITTEST |
|
88 static void UnitTest(); |
|
89 #endif |
|
90 private: |
|
91 template<typename T> friend class SkRTConf; |
|
92 |
|
93 void registerConf(SkRTConfBase *conf); |
|
94 template <typename T> bool parse(const char *name, T* value); |
|
95 |
|
96 SkTDArray<SkString *> fConfigFileKeys, fConfigFileValues; |
|
97 typedef SkTDict< SkTDArray<SkRTConfBase *> * > ConfMap; |
|
98 ConfMap fConfs; |
|
99 #ifdef SK_SUPPORT_UNITTEST |
|
100 SkRTConfRegistry(bool); |
|
101 #endif |
|
102 }; |
|
103 |
|
104 // our singleton registry |
|
105 |
|
106 SkRTConfRegistry &skRTConfRegistry(); |
|
107 |
|
108 template<typename T> |
|
109 SkRTConf<T>::SkRTConf(const char *name, const T &defaultValue, const char *description) |
|
110 : SkRTConfBase(name) |
|
111 , fValue(defaultValue) |
|
112 , fDefault(defaultValue) |
|
113 , fDescription(description) { |
|
114 |
|
115 T value; |
|
116 if (skRTConfRegistry().parse(fName.c_str(), &value)) { |
|
117 fValue = value; |
|
118 } |
|
119 skRTConfRegistry().registerConf(this); |
|
120 } |
|
121 |
|
122 template<typename T> |
|
123 void SkRTConf<T>::print(SkWStream *o) const { |
|
124 char outline[200]; // should be ok because we specify a max. width for everything here. |
|
125 char *outptr; |
|
126 if (strlen(getName()) >= 30) { |
|
127 o->writeText(getName()); |
|
128 o->writeText(" "); |
|
129 outptr = &(outline[0]); |
|
130 } else { |
|
131 sprintf(outline, "%-30.30s", getName()); |
|
132 outptr = &(outline[30]); |
|
133 } |
|
134 |
|
135 doPrint(outptr); |
|
136 sprintf(outptr+30, " %.128s", fDescription.c_str()); |
|
137 for (size_t i = strlen(outline); i --> 0 && ' ' == outline[i];) { |
|
138 outline[i] = '\0'; |
|
139 } |
|
140 o->writeText(outline); |
|
141 } |
|
142 |
|
143 template<typename T> |
|
144 void SkRTConf<T>::doPrint(char *s) const { |
|
145 sprintf(s, "%-30.30s", "How do I print myself??"); |
|
146 } |
|
147 |
|
148 template<> inline void SkRTConf<bool>::doPrint(char *s) const { |
|
149 char tmp[30]; |
|
150 sprintf(tmp, "%s # [%s]", fValue ? "true" : "false", fDefault ? "true" : "false"); |
|
151 sprintf(s, "%-30.30s", tmp); |
|
152 } |
|
153 |
|
154 template<> inline void SkRTConf<int>::doPrint(char *s) const { |
|
155 char tmp[30]; |
|
156 sprintf(tmp, "%d # [%d]", fValue, fDefault); |
|
157 sprintf(s, "%-30.30s", tmp); |
|
158 } |
|
159 |
|
160 template<> inline void SkRTConf<unsigned int>::doPrint(char *s) const { |
|
161 char tmp[30]; |
|
162 sprintf(tmp, "%u # [%u]", fValue, fDefault); |
|
163 sprintf(s, "%-30.30s", tmp); |
|
164 } |
|
165 |
|
166 template<> inline void SkRTConf<float>::doPrint(char *s) const { |
|
167 char tmp[30]; |
|
168 sprintf(tmp, "%6.6f # [%6.6f]", fValue, fDefault); |
|
169 sprintf(s, "%-30.30s", tmp); |
|
170 } |
|
171 |
|
172 template<> inline void SkRTConf<double>::doPrint(char *s) const { |
|
173 char tmp[30]; |
|
174 sprintf(tmp, "%6.6f # [%6.6f]", fValue, fDefault); |
|
175 sprintf(s, "%-30.30s", tmp); |
|
176 } |
|
177 |
|
178 template<> inline void SkRTConf<const char *>::doPrint(char *s) const { |
|
179 char tmp[30]; |
|
180 sprintf(tmp, "%s # [%s]", fValue, fDefault); |
|
181 sprintf(s, "%-30.30s", tmp); |
|
182 } |
|
183 |
|
184 template<typename T> |
|
185 bool SkRTConf<T>::equals(const SkRTConfBase *conf) const { |
|
186 // static_cast here is okay because there's only one kind of child class. |
|
187 const SkRTConf<T> *child_pointer = static_cast<const SkRTConf<T> *>(conf); |
|
188 return child_pointer && |
|
189 fName == child_pointer->fName && |
|
190 fDescription == child_pointer->fDescription && |
|
191 fValue == child_pointer->fValue && |
|
192 fDefault == child_pointer->fDefault; |
|
193 } |
|
194 |
|
195 #endif |