SkRTConf.h revision c1bf2de83549406de305e174af2b88630fdc3098
17af56bee17764a0c118c8856a035bb3d27766969humper@google.com/*
27af56bee17764a0c118c8856a035bb3d27766969humper@google.com * Copyright 2013 Google, Inc.
37af56bee17764a0c118c8856a035bb3d27766969humper@google.com *
47af56bee17764a0c118c8856a035bb3d27766969humper@google.com * Use of this source code is governed by a BSD-style license that can be
57af56bee17764a0c118c8856a035bb3d27766969humper@google.com * found in the LICENSE file.
67af56bee17764a0c118c8856a035bb3d27766969humper@google.com */
77af56bee17764a0c118c8856a035bb3d27766969humper@google.com
87af56bee17764a0c118c8856a035bb3d27766969humper@google.com
97af56bee17764a0c118c8856a035bb3d27766969humper@google.com#ifndef SkRTConf_DEFINED
107af56bee17764a0c118c8856a035bb3d27766969humper@google.com#define SkRTConf_DEFINED
117af56bee17764a0c118c8856a035bb3d27766969humper@google.com
127af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkString.h"
137af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkStream.h"
147af56bee17764a0c118c8856a035bb3d27766969humper@google.com
157af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkTDict.h"
167af56bee17764a0c118c8856a035bb3d27766969humper@google.com#include "SkTArray.h"
177af56bee17764a0c118c8856a035bb3d27766969humper@google.com
187af56bee17764a0c118c8856a035bb3d27766969humper@google.com/** \class SkRTConfBase
197af56bee17764a0c118c8856a035bb3d27766969humper@google.com    Non-templated base class for the runtime configs
207af56bee17764a0c118c8856a035bb3d27766969humper@google.com*/
217af56bee17764a0c118c8856a035bb3d27766969humper@google.com
227af56bee17764a0c118c8856a035bb3d27766969humper@google.comclass SkRTConfBase {
237af56bee17764a0c118c8856a035bb3d27766969humper@google.compublic:
247af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkRTConfBase(const char *name) : fName(name) {}
257af56bee17764a0c118c8856a035bb3d27766969humper@google.com    virtual ~SkRTConfBase() {}
267af56bee17764a0c118c8856a035bb3d27766969humper@google.com    virtual const char *getName() const { return fName.c_str(); }
277af56bee17764a0c118c8856a035bb3d27766969humper@google.com    virtual bool isDefault() const = 0;
287af56bee17764a0c118c8856a035bb3d27766969humper@google.com    virtual void print(SkWStream *o) const = 0;
297af56bee17764a0c118c8856a035bb3d27766969humper@google.com    virtual bool equals(const SkRTConfBase *conf) const = 0;
307af56bee17764a0c118c8856a035bb3d27766969humper@google.comprotected:
317af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkString fName;
327af56bee17764a0c118c8856a035bb3d27766969humper@google.com};
337af56bee17764a0c118c8856a035bb3d27766969humper@google.com
347af56bee17764a0c118c8856a035bb3d27766969humper@google.com/** \class SkRTConf
357af56bee17764a0c118c8856a035bb3d27766969humper@google.com    A class to provide runtime configurability.
367af56bee17764a0c118c8856a035bb3d27766969humper@google.com*/
377af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T> class SkRTConf: public SkRTConfBase {
387af56bee17764a0c118c8856a035bb3d27766969humper@google.compublic:
397af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkRTConf(const char *name, const T &defaultValue, const char *description);
407af56bee17764a0c118c8856a035bb3d27766969humper@google.com    operator const T&() const { return fValue; }
417af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void print(SkWStream *o) const;
427af56bee17764a0c118c8856a035bb3d27766969humper@google.com    bool equals(const SkRTConfBase *conf) const;
437af56bee17764a0c118c8856a035bb3d27766969humper@google.com    bool isDefault() const { return fDefault == fValue; }
447af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void set(const T& value) { fValue = value; }
457af56bee17764a0c118c8856a035bb3d27766969humper@google.comprotected:
467af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void doPrint(char *s) const;
47fb830981f2ec157674953650de6ddbf8723051a0skia.committer@gmail.com
48fb830981f2ec157674953650de6ddbf8723051a0skia.committer@gmail.com    T        fValue;
499b64cac7c8db2dce6759f551d3bab4192563d8c0humper@google.com    T        fDefault;
507af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkString fDescription;
517af56bee17764a0c118c8856a035bb3d27766969humper@google.com};
527af56bee17764a0c118c8856a035bb3d27766969humper@google.com
537af56bee17764a0c118c8856a035bb3d27766969humper@google.com#ifdef SK_DEVELOPER
547af56bee17764a0c118c8856a035bb3d27766969humper@google.com#define SK_CONF_DECLARE(confType, varName, confName, defaultValue, description) static SkRTConf<confType> varName(confName, defaultValue, description)
557af56bee17764a0c118c8856a035bb3d27766969humper@google.com#define SK_CONF_SET(confname, value) skRTConfRegistry().set(confname, value)
567af56bee17764a0c118c8856a035bb3d27766969humper@google.com#else
57807863839fd5fb9a3fac603241515863dc0790c0humper@google.com#define SK_CONF_DECLARE(confType, varName, confName, defaultValue, description) static confType varName = defaultValue
587af56bee17764a0c118c8856a035bb3d27766969humper@google.com#define SK_CONF_SET(confname, value) (void) confname, (void) value
597af56bee17764a0c118c8856a035bb3d27766969humper@google.com#endif
607af56bee17764a0c118c8856a035bb3d27766969humper@google.com
617af56bee17764a0c118c8856a035bb3d27766969humper@google.com/** \class SkRTConfRegistry
627af56bee17764a0c118c8856a035bb3d27766969humper@google.com    A class that maintains a systemwide registry of all runtime configuration
637af56bee17764a0c118c8856a035bb3d27766969humper@google.com    parameters.  Mainly used for printing them out and handling multiply-defined
647af56bee17764a0c118c8856a035bb3d27766969humper@google.com    knobs.
657af56bee17764a0c118c8856a035bb3d27766969humper@google.com*/
667af56bee17764a0c118c8856a035bb3d27766969humper@google.com
677af56bee17764a0c118c8856a035bb3d27766969humper@google.comclass SkRTConfRegistry {
687af56bee17764a0c118c8856a035bb3d27766969humper@google.compublic:
697af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkRTConfRegistry();
707af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void printAll(const char *fname = NULL) const;
717af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void printNonDefault(const char *fname = NULL) const;
727af56bee17764a0c118c8856a035bb3d27766969humper@google.com    const char *configFileLocation() const;
737af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void possiblyDumpFile() const;
747af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void validate() const;
757af56bee17764a0c118c8856a035bb3d27766969humper@google.com    template <typename T> void set(const char *confname, T value);
76c1bf2de83549406de305e174af2b88630fdc3098commit-bot@chromium.org#ifdef SK_SUPPORT_UNITTEST
77c1bf2de83549406de305e174af2b88630fdc3098commit-bot@chromium.org    static void UnitTest();
78c1bf2de83549406de305e174af2b88630fdc3098commit-bot@chromium.org#endif
797af56bee17764a0c118c8856a035bb3d27766969humper@google.comprivate:
807af56bee17764a0c118c8856a035bb3d27766969humper@google.com    template<typename T> friend class SkRTConf;
817fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
827af56bee17764a0c118c8856a035bb3d27766969humper@google.com    void registerConf(SkRTConfBase *conf);
837af56bee17764a0c118c8856a035bb3d27766969humper@google.com    template <typename T> bool parse(const char *name, T* value);
847fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
857af56bee17764a0c118c8856a035bb3d27766969humper@google.com    SkTDArray<SkString *> fConfigFileKeys, fConfigFileValues;
867af56bee17764a0c118c8856a035bb3d27766969humper@google.com    typedef SkTDict< SkTDArray<SkRTConfBase *> * > ConfMap;
877af56bee17764a0c118c8856a035bb3d27766969humper@google.com    ConfMap fConfs;
88c1bf2de83549406de305e174af2b88630fdc3098commit-bot@chromium.org#ifdef SK_SUPPORT_UNITTEST
89c1bf2de83549406de305e174af2b88630fdc3098commit-bot@chromium.org    SkRTConfRegistry(bool);
90c1bf2de83549406de305e174af2b88630fdc3098commit-bot@chromium.org#endif
917af56bee17764a0c118c8856a035bb3d27766969humper@google.com};
927af56bee17764a0c118c8856a035bb3d27766969humper@google.com
937af56bee17764a0c118c8856a035bb3d27766969humper@google.com// our singleton registry
947af56bee17764a0c118c8856a035bb3d27766969humper@google.com
957af56bee17764a0c118c8856a035bb3d27766969humper@google.comSkRTConfRegistry &skRTConfRegistry();
967af56bee17764a0c118c8856a035bb3d27766969humper@google.com
977af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T>
987af56bee17764a0c118c8856a035bb3d27766969humper@google.comSkRTConf<T>::SkRTConf(const char *name, const T &defaultValue, const char *description)
997af56bee17764a0c118c8856a035bb3d27766969humper@google.com    : SkRTConfBase(name)
1007af56bee17764a0c118c8856a035bb3d27766969humper@google.com    , fValue(defaultValue)
1017af56bee17764a0c118c8856a035bb3d27766969humper@google.com    , fDefault(defaultValue)
1027af56bee17764a0c118c8856a035bb3d27766969humper@google.com    , fDescription(description) {
1037fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com
1047af56bee17764a0c118c8856a035bb3d27766969humper@google.com    T value;
1057af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (skRTConfRegistry().parse(fName.c_str(), &value)) {
1067af56bee17764a0c118c8856a035bb3d27766969humper@google.com        fValue = value;
1077af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1087af56bee17764a0c118c8856a035bb3d27766969humper@google.com    skRTConfRegistry().registerConf(this);
1097af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1107af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1117af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T>
1127af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConf<T>::print(SkWStream *o) const {
1137af56bee17764a0c118c8856a035bb3d27766969humper@google.com    char outline[200]; // should be ok because we specify a max. width for everything here.
1147af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1157af56bee17764a0c118c8856a035bb3d27766969humper@google.com    sprintf(outline, "%-30.30s", getName());
1167af56bee17764a0c118c8856a035bb3d27766969humper@google.com    doPrint(&(outline[30]));
1177af56bee17764a0c118c8856a035bb3d27766969humper@google.com    sprintf(&(outline[60]), " %.128s", fDescription.c_str());
1187af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (' ' == outline[strlen(outline)-1]) {
1197af56bee17764a0c118c8856a035bb3d27766969humper@google.com        for (int i = strlen(outline)-1 ; ' ' == outline[i] ; i--) {
1207af56bee17764a0c118c8856a035bb3d27766969humper@google.com            outline[i] = '\0';
1217af56bee17764a0c118c8856a035bb3d27766969humper@google.com        }
1227af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1237af56bee17764a0c118c8856a035bb3d27766969humper@google.com    o->writeText(outline);
1247af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1257af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1267af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T>
1277af56bee17764a0c118c8856a035bb3d27766969humper@google.comvoid SkRTConf<T>::doPrint(char *s) const {
1287af56bee17764a0c118c8856a035bb3d27766969humper@google.com    sprintf(s, "%-30.30s", "How do I print myself??");
1297af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1307af56bee17764a0c118c8856a035bb3d27766969humper@google.com
131810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.comtemplate<> inline void SkRTConf<bool>::doPrint(char *s) const {
132810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    char tmp[30];
133810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(tmp, "%s # [%s]", fValue ? "true" : "false", fDefault ? "true" : "false");
134810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(s, "%-30.30s", tmp);
135810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com}
136810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com
137810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.comtemplate<> inline void SkRTConf<int>::doPrint(char *s) const {
138810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    char tmp[30];
139810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(tmp, "%d # [%d]", fValue, fDefault);
140810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(s, "%-30.30s", tmp);
141810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com}
142810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com
143810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.comtemplate<> inline void SkRTConf<unsigned int>::doPrint(char *s) const {
144810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    char tmp[30];
145810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(tmp, "%u # [%u]", fValue, fDefault);
146810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(s, "%-30.30s", tmp);
147810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com}
148810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com
149810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.comtemplate<> inline void SkRTConf<float>::doPrint(char *s) const {
150810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    char tmp[30];
151810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(tmp, "%6.6f # [%6.6f]", fValue, fDefault);
152810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(s, "%-30.30s", tmp);
153810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com}
154810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com
155810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.comtemplate<> inline void SkRTConf<double>::doPrint(char *s) const {
156810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    char tmp[30];
157810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(tmp, "%6.6f # [%6.6f]", fValue, fDefault);
158810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(s, "%-30.30s", tmp);
159810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com}
160810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com
161810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.comtemplate<> inline void SkRTConf<const char *>::doPrint(char *s) const {
162810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    char tmp[30];
163810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(tmp, "%s # [%s]", fValue, fDefault);
164810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com    sprintf(s, "%-30.30s", tmp);
165810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com}
166810ae48f82f82d6e7fc4cf78d7a5a69e3cf9f2edhumper@google.com
1677af56bee17764a0c118c8856a035bb3d27766969humper@google.comtemplate<typename T>
1687af56bee17764a0c118c8856a035bb3d27766969humper@google.combool SkRTConf<T>::equals(const SkRTConfBase *conf) const {
1696d29eda49129893d8f5e385bfbe8473af154b82bhumper@google.com    // static_cast here is okay because there's only one kind of child class.
1706d29eda49129893d8f5e385bfbe8473af154b82bhumper@google.com    const SkRTConf<T> *child_pointer = static_cast<const SkRTConf<T> *>(conf);
1717fc0e0a75a99ac5ea2e5d03ab3a00cacabacfa09skia.committer@gmail.com    return child_pointer &&
1727af56bee17764a0c118c8856a035bb3d27766969humper@google.com           fName == child_pointer->fName &&
1737af56bee17764a0c118c8856a035bb3d27766969humper@google.com           fDescription == child_pointer->fDescription &&
1747af56bee17764a0c118c8856a035bb3d27766969humper@google.com           fValue == child_pointer->fValue &&
1757af56bee17764a0c118c8856a035bb3d27766969humper@google.com           fDefault == child_pointer->fDefault;
1767af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
1777af56bee17764a0c118c8856a035bb3d27766969humper@google.com
1787af56bee17764a0c118c8856a035bb3d27766969humper@google.com#endif
179