Skip to content

Commit

Permalink
Refactor|libdeng2: Moved convenience getters from Config to Record
Browse files Browse the repository at this point in the history
These get*() methods are useful with any Record, not just Config.
  • Loading branch information
skyjake committed Mar 10, 2014
1 parent 355080e commit adb7a2c
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 25 deletions.
28 changes: 14 additions & 14 deletions doomsday/libdeng2/include/de/core/config.h
Expand Up @@ -49,10 +49,6 @@ class ArrayValue;
*/
class DENG2_PUBLIC Config
{
public:
/// Attempted to get the value of a variable while expecting the wrong type. @ingroup errors
DENG2_ERROR(ValueTypeError);

public:
/**
* Constructs a new configuration.
Expand All @@ -68,36 +64,40 @@ class DENG2_PUBLIC Config
void write() const;

/// Returns the value of @a name as a Value.
Value &get(String const &name) const;
Value const &get(String const &name) const;

/// Returns the value of @a name as an integer.
dint geti(String const &name) const;

dint geti(String const &name, dint defaultValue) const;

/// Returns the value of @a name as a boolean.
bool getb(String const &name) const;

bool getb(String const &name, bool defaultValue) const;

/// Returns the value of @a name as an unsigned integer.
duint getui(String const &name) const;

duint getui(String const &name, duint defaultValue) const;

/// Returns the value of @a name as a double-precision floating point number.
ddouble getd(String const &name) const;

ddouble getd(String const &name, ddouble defaultValue) const;

/// Returns the value of @a name as a string.
String gets(String const &name) const;

String gets(String const &name, String const &defaultValue) const;

/// Returns the value of @a name as an array value. An exception is thrown
/// if the variable does not have an array value.
ArrayValue &geta(String const &name) const;
ArrayValue const &geta(String const &name) const;

template <typename ValueType>
ValueType &getAs(String const &name) const {
ValueType *v = dynamic_cast<ValueType *>(&get(name));
if(!v)
{
throw ValueTypeError("Config::getAs", String("Cannot cast to expected type (") +
DENG2_TYPE_NAME(ValueType) + ")");
}
return *v;
ValueType const &getAs(String const &name) const {
return names().getAs<ValueType>(name);
}

/**
Expand Down
28 changes: 28 additions & 0 deletions doomsday/libdeng2/include/de/data/record.h
Expand Up @@ -58,6 +58,9 @@ class DENG2_PUBLIC Record : public ISerializable, public LogEntry::Arg::Base,
/// All variables and subrecords in the record must have a name. @ingroup errors
DENG2_ERROR(UnnamedError);

/// Attempted to get the value of a variable while expecting the wrong type. @ingroup errors
DENG2_ERROR(ValueTypeError);

typedef QMap<String, Variable *> Members;
typedef QMap<String, Record *> Subrecords;
typedef std::pair<String, String> KeyValue;
Expand Down Expand Up @@ -260,6 +263,31 @@ class DENG2_PUBLIC Record : public ISerializable, public LogEntry::Arg::Base,
*/
Record *remove(String const &name);

// Convenient value getters:
Value const &get(String const &name) const;
dint geti(String const &name) const;
dint geti(String const &name, dint defaultValue) const;
bool getb(String const &name) const;
bool getb(String const &name, bool defaultValue) const;
duint getui(String const &name) const;
duint getui(String const &name, duint defaultValue) const;
ddouble getd(String const &name) const;
ddouble getd(String const &name, ddouble defaultValue) const;
String gets(String const &name) const;
String gets(String const &name, String const &defaultValue) const;
ArrayValue const &geta(String const &name) const;

template <typename ValueType>
ValueType const &getAs(String const &name) const {
ValueType const *v = get(name).maybeAs<ValueType>();
if(!v)
{
throw ValueTypeError("Record::getAs", String("Cannot cast to expected type (") +
DENG2_TYPE_NAME(ValueType) + ")");
}
return *v;
}

/**
* Sets the value of a variable, creating the variable if needed.
*
Expand Down
10 changes: 10 additions & 0 deletions doomsday/libdeng2/include/de/data/value.h
Expand Up @@ -110,6 +110,16 @@ class DENG2_PUBLIC Value : public String::IPatternArg, public ISerializable
return *t;
}

template <typename ValueType>
ValueType *maybeAs() {
return dynamic_cast<ValueType *>(this);
}

template <typename ValueType>
ValueType const *maybeAs() const {
return dynamic_cast<ValueType const *>(this);
}

/**
* Determine the size of the value. The meaning of this
* depends on the type of the value.
Expand Down
43 changes: 34 additions & 9 deletions doomsday/libdeng2/src/core/config.cpp
Expand Up @@ -186,39 +186,64 @@ Version Config::upgradedFromVersion() const
return d->oldVersion;
}

Value &Config::get(String const &name) const
Value const &Config::get(String const &name) const
{
return d->config.globals()[name].value();
return names().get(name);
}

dint Config::geti(String const &name) const
{
return dint(get(name).asNumber());
return names().geti(name);
}

dint Config::geti(String const &name, dint defaultValue) const
{
return names().geti(name, defaultValue);
}

bool Config::getb(String const &name) const
{
return get(name).isTrue();
return names().getb(name);
}

bool Config::getb(String const &name, bool defaultValue) const
{
return names().getb(name, defaultValue);
}

duint Config::getui(String const &name) const
{
return duint(get(name).asNumber());
return names().getui(name);
}

duint Config::getui(String const &name, duint defaultValue) const
{
return names().getui(name, defaultValue);
}

ddouble Config::getd(String const &name) const
{
return get(name).asNumber();
return names().getd(name);
}

ddouble Config::getd(String const &name, ddouble defaultValue) const
{
return names().getd(name, defaultValue);
}

String Config::gets(String const &name) const
{
return get(name).asText();
return names().gets(name);
}

String Config::gets(String const &name, String const &defaultValue) const
{
return names().gets(name, defaultValue);
}

ArrayValue &Config::geta(String const &name) const
ArrayValue const &Config::geta(String const &name) const
{
return getAs<ArrayValue>(name);
return names().getAs<ArrayValue>(name);
}

Variable &Config::set(String const &name, bool value)
Expand Down
65 changes: 65 additions & 0 deletions doomsday/libdeng2/src/data/record.cpp
Expand Up @@ -361,6 +361,71 @@ Record *Record::remove(String const &name)
throw NotFoundError("Record::remove", "Subrecord '" + name + "' not found");
}

Value const &Record::get(String const &name) const
{
return (*this)[name].value();
}

dint Record::geti(String const &name) const
{
return dint(get(name).asNumber());
}

dint Record::geti(String const &name, dint defaultValue) const
{
if(!hasMember(name)) return defaultValue;
return geti(name);
}

bool Record::getb(String const &name) const
{
return get(name).isTrue();
}

bool Record::getb(String const &name, bool defaultValue) const
{
if(!hasMember(name)) return defaultValue;
return getb(name);
}

duint Record::getui(String const &name) const
{
return duint(get(name).asNumber());
}

duint Record::getui(String const &name, duint defaultValue) const
{
if(!hasMember(name)) return defaultValue;
return getui(name);
}

ddouble Record::getd(String const &name) const
{
return get(name).asNumber();
}

ddouble Record::getd(String const &name, ddouble defaultValue) const
{
if(!hasMember(name)) return defaultValue;
return getd(name);
}

String Record::gets(String const &name) const
{
return get(name).asText();
}

String Record::gets(String const &name, String const &defaultValue) const
{
if(!hasMember(name)) return defaultValue;
return gets(name);
}

ArrayValue const &Record::geta(String const &name) const
{
return getAs<ArrayValue>(name);
}

Variable &Record::set(String const &name, bool value)
{
if(hasMember(name))
Expand Down
4 changes: 2 additions & 2 deletions doomsday/libgui/src/persistentcanvaswindow.cpp
Expand Up @@ -203,7 +203,7 @@ DENG2_PIMPL(PersistentCanvasWindow)
Config &config = App::config();

// The default state of the window is determined by these values.
ArrayValue &rect = config.geta(configName("rect"));
ArrayValue const &rect = config.geta(configName("rect"));
if(rect.size() >= 4)
{
windowRect = Rectanglei(rect.at(0).asNumber(),
Expand All @@ -212,7 +212,7 @@ DENG2_PIMPL(PersistentCanvasWindow)
rect.at(3).asNumber());
}

ArrayValue &fs = config.geta(configName("fullSize"));
ArrayValue const &fs = config.geta(configName("fullSize"));
if(fs.size() >= 2)
{
fullSize = Size(fs.at(0).asNumber(), fs.at(1).asNumber());
Expand Down

0 comments on commit adb7a2c

Please sign in to comment.