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