Initial revision.
This commit is contained in:
parent
044ac5d5d3
commit
1c2289dacd
@ -11,6 +11,7 @@ lib_LIBRARIES = libsgmisc.a
|
||||
include_HEADERS = \
|
||||
fgpath.hxx \
|
||||
fgstream.hxx \
|
||||
props.hxx \
|
||||
stopwatch.hxx \
|
||||
strutils.hxx \
|
||||
texcoord.hxx \
|
||||
@ -19,6 +20,7 @@ include_HEADERS = \
|
||||
libsgmisc_a_SOURCES = \
|
||||
fgpath.cxx \
|
||||
fgstream.cxx \
|
||||
props.cxx \
|
||||
strutils.cxx \
|
||||
texcoord.cxx \
|
||||
zfstream.cxx
|
||||
|
803
simgear/misc/props.cxx
Normal file
803
simgear/misc/props.cxx
Normal file
@ -0,0 +1,803 @@
|
||||
// props.cxx -- implementation of FGFS global properties.
|
||||
//
|
||||
// Copyright (C) 2000 David Megginson - david@megginson.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "props.hxx"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
FGPropertyList current_properties;
|
||||
|
||||
static string empty_string;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGValue.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new value.
|
||||
*/
|
||||
FGValue::FGValue ()
|
||||
: _type(UNKNOWN), _tied(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy a value.
|
||||
*/
|
||||
FGValue::~FGValue ()
|
||||
{
|
||||
if (!_tied && _type == STRING) {
|
||||
delete _value.string_val;
|
||||
_value.string_val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::getRawBool () const
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.bool_func.getter != 0)
|
||||
return (*(_value.bool_func.getter))();
|
||||
else
|
||||
return false;
|
||||
} else {
|
||||
return _value.bool_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FGValue::getRawInt () const
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.int_func.getter != 0)
|
||||
return (*(_value.int_func.getter))();
|
||||
else
|
||||
return 0;
|
||||
} else {
|
||||
return _value.int_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
FGValue::getRawFloat () const
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.float_func.getter != 0)
|
||||
return (*(_value.float_func.getter))();
|
||||
else
|
||||
return 0.0;
|
||||
} else {
|
||||
return _value.float_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
FGValue::getRawDouble () const
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.double_func.getter != 0)
|
||||
return (*(_value.double_func.getter))();
|
||||
else
|
||||
return 0.0L;
|
||||
} else {
|
||||
return _value.double_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const string &
|
||||
FGValue::getRawString () const
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.string_func.getter != 0)
|
||||
return (*(_value.string_func.getter))();
|
||||
else
|
||||
return empty_string;
|
||||
} else {
|
||||
return *_value.string_val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setRawBool (bool value)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.bool_func.setter != 0) {
|
||||
(*_value.bool_func.setter)(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_value.bool_val = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setRawInt (int value)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.int_func.setter != 0) {
|
||||
(*_value.int_func.setter)(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_value.int_val = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setRawFloat (float value)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.float_func.setter != 0) {
|
||||
(*_value.float_func.setter)(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_value.float_val = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setRawDouble (double value)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.double_func.setter != 0) {
|
||||
(*_value.double_func.setter)(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_value.double_val = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setRawString (const string &value)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.string_func.setter != 0) {
|
||||
(*_value.string_func.setter)(value);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (_value.string_val == 0)
|
||||
_value.string_val = new string;
|
||||
*(_value.string_val) = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to get the boolean value of a property.
|
||||
*/
|
||||
bool
|
||||
FGValue::getBoolValue () const
|
||||
{
|
||||
switch (_type) {
|
||||
case UNKNOWN:
|
||||
return false;
|
||||
case BOOL:
|
||||
return getRawBool();
|
||||
case INT:
|
||||
return (getRawInt() == 0 ? false : true);
|
||||
case FLOAT:
|
||||
return (getRawFloat() == 0.0 ? false : true);
|
||||
case DOUBLE:
|
||||
return (getRawDouble() == 0.0 ? false : true);
|
||||
case STRING:
|
||||
return (getRawString() == "false" ? false : true);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to get the integer value of a property.
|
||||
*/
|
||||
int
|
||||
FGValue::getIntValue () const
|
||||
{
|
||||
switch (_type) {
|
||||
case UNKNOWN:
|
||||
return 0;
|
||||
case BOOL:
|
||||
return getRawBool();
|
||||
case INT:
|
||||
return getRawInt();
|
||||
case FLOAT:
|
||||
return (int)(getRawFloat());
|
||||
case DOUBLE:
|
||||
return (int)(getRawDouble());
|
||||
case STRING:
|
||||
return atoi(getRawString().c_str());
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to get the float value of a property.
|
||||
*/
|
||||
float
|
||||
FGValue::getFloatValue () const
|
||||
{
|
||||
switch (_type) {
|
||||
case UNKNOWN:
|
||||
return 0.0;
|
||||
case BOOL:
|
||||
return (float)(getRawBool());
|
||||
case INT:
|
||||
return (float)(getRawInt());
|
||||
case FLOAT:
|
||||
return getRawFloat();
|
||||
case DOUBLE:
|
||||
return (float)(getRawDouble());
|
||||
case STRING:
|
||||
return (float)atof(getRawString().c_str());
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to get the double value of a property.
|
||||
*/
|
||||
double
|
||||
FGValue::getDoubleValue () const
|
||||
{
|
||||
switch (_type) {
|
||||
case UNKNOWN:
|
||||
return 0.0;
|
||||
case BOOL:
|
||||
return (double)(getRawBool());
|
||||
case INT:
|
||||
return (double)(getRawInt());
|
||||
case FLOAT:
|
||||
return (double)(getRawFloat());
|
||||
case DOUBLE:
|
||||
return getRawDouble();
|
||||
case STRING:
|
||||
return atof(getRawString().c_str());
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to get the string value of a property.
|
||||
*/
|
||||
const string &
|
||||
FGValue::getStringValue () const
|
||||
{
|
||||
switch (_type) {
|
||||
case UNKNOWN:
|
||||
case BOOL:
|
||||
case INT:
|
||||
case FLOAT:
|
||||
case DOUBLE:
|
||||
return empty_string;
|
||||
case STRING:
|
||||
return getRawString();
|
||||
default:
|
||||
return empty_string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setBoolValue (bool value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == BOOL) {
|
||||
_type = BOOL;
|
||||
return setRawBool(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setIntValue (int value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == INT) {
|
||||
_type = INT;
|
||||
return setRawInt(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setFloatValue (float value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == FLOAT) {
|
||||
_type = FLOAT;
|
||||
return setRawFloat(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setDoubleValue (double value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == DOUBLE) {
|
||||
_type = DOUBLE;
|
||||
return setRawDouble(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::setStringValue (const string &value)
|
||||
{
|
||||
if (_type == UNKNOWN || _type == STRING) {
|
||||
_type = STRING;
|
||||
return setRawString(value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::tieBool (bool_getter getter, bool_setter setter = 0,
|
||||
bool useDefault = true)
|
||||
{
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
(*setter)(getBoolValue());
|
||||
_tied = true;
|
||||
_type = BOOL;
|
||||
_value.bool_func.getter = getter;
|
||||
_value.bool_func.setter = setter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::tieInt (int_getter getter, int_setter setter = 0,
|
||||
bool useDefault = true)
|
||||
{
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
(*setter)(getIntValue());
|
||||
_tied = true;
|
||||
_type = INT;
|
||||
_value.int_func.getter = getter;
|
||||
_value.int_func.setter = setter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::tieFloat (float_getter getter, float_setter setter = 0,
|
||||
bool useDefault = true)
|
||||
{
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
(*setter)(getFloatValue());
|
||||
_tied = true;
|
||||
_type = FLOAT;
|
||||
_value.float_func.getter = getter;
|
||||
_value.float_func.setter = setter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::tieDouble (double_getter getter, double_setter setter = 0,
|
||||
bool useDefault = true)
|
||||
{
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
(*setter)(getDoubleValue());
|
||||
_tied = true;
|
||||
_type = DOUBLE;
|
||||
_value.double_func.getter = getter;
|
||||
_value.double_func.setter = setter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::tieString (string_getter getter, string_setter setter = 0,
|
||||
bool useDefault = true)
|
||||
{
|
||||
if (_tied) {
|
||||
return false;
|
||||
} else {
|
||||
if (useDefault && setter && _type != UNKNOWN)
|
||||
(*setter)(getStringValue());
|
||||
if (_type == STRING)
|
||||
delete _value.string_val;
|
||||
_tied = true;
|
||||
_type = STRING;
|
||||
_value.string_func.getter = getter;
|
||||
_value.string_func.setter = setter;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::untieBool ()
|
||||
{
|
||||
if (_tied && _type == BOOL) {
|
||||
bool value = getRawBool();
|
||||
_value.bool_val = value;
|
||||
_tied = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::untieInt ()
|
||||
{
|
||||
if (_tied && _type == INT) {
|
||||
int value = getRawInt();
|
||||
_value.int_val = value;
|
||||
_tied = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::untieFloat ()
|
||||
{
|
||||
if (_tied && _type == FLOAT) {
|
||||
float value = getRawFloat();
|
||||
_value.float_val = value;
|
||||
_tied = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::untieDouble ()
|
||||
{
|
||||
if (_tied && _type == DOUBLE) {
|
||||
double value = getRawDouble();
|
||||
_value.double_val = value;
|
||||
_tied = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGValue::untieString ()
|
||||
{
|
||||
if (_tied && _type == STRING) {
|
||||
const string &value = getRawString();
|
||||
_value.string_val = new string(value);
|
||||
_tied = false;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of FGPropertyList.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FGPropertyList::FGPropertyList ()
|
||||
{
|
||||
}
|
||||
|
||||
FGPropertyList::~FGPropertyList ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
FGValue *
|
||||
FGPropertyList::getValue (const string &name, bool create = false)
|
||||
{
|
||||
const_iterator el = _props.find(name);
|
||||
if (el == _props.end()) {
|
||||
if (!create)
|
||||
return 0;
|
||||
else {
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Creating new property '" << name << '\'');
|
||||
}
|
||||
}
|
||||
return &(_props[name]);
|
||||
}
|
||||
|
||||
|
||||
const FGValue *
|
||||
FGPropertyList::getValue (const string &name) const
|
||||
{
|
||||
value_map::const_iterator el = _props.find(name);
|
||||
return &(el->second);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::getBoolValue (const string &name) const
|
||||
{
|
||||
const FGValue * val = getValue(name);
|
||||
if (val == 0)
|
||||
return false;
|
||||
else
|
||||
return val->getBoolValue();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
FGPropertyList::getIntValue (const string &name) const
|
||||
{
|
||||
const FGValue * val = getValue(name);
|
||||
if (val == 0)
|
||||
return 0;
|
||||
else
|
||||
return val->getIntValue();
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
FGPropertyList::getFloatValue (const string &name) const
|
||||
{
|
||||
const FGValue * val = getValue(name);
|
||||
if (val == 0)
|
||||
return 0.0;
|
||||
else
|
||||
return val->getFloatValue();
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
FGPropertyList::getDoubleValue (const string &name) const
|
||||
{
|
||||
const FGValue * val = getValue(name);
|
||||
if (val == 0)
|
||||
return 0.0;
|
||||
else
|
||||
return val->getDoubleValue();
|
||||
}
|
||||
|
||||
|
||||
const string &
|
||||
FGPropertyList::getStringValue (const string &name) const
|
||||
{
|
||||
const FGValue * val = getValue(name);
|
||||
if (val == 0)
|
||||
return empty_string;
|
||||
else
|
||||
return val->getStringValue();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::setBoolValue (const string &name, bool value)
|
||||
{
|
||||
return getValue(name, true)->setBoolValue(value);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::setIntValue (const string &name, int value)
|
||||
{
|
||||
return getValue(name, true)->setIntValue(value);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::setFloatValue (const string &name, float value)
|
||||
{
|
||||
return getValue(name, true)->setFloatValue(value);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::setDoubleValue (const string &name, double value)
|
||||
{
|
||||
return getValue(name, true)->setDoubleValue(value);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::setStringValue (const string &name, const string &value)
|
||||
{
|
||||
return getValue(name, true)->setStringValue(value);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::tieBool (const string &name,
|
||||
bool_getter getter,
|
||||
bool_setter setter,
|
||||
bool useDefault = true)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying bool property '" << name << '\'');
|
||||
return getValue(name, true)->tieBool(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::tieInt (const string &name,
|
||||
int_getter getter,
|
||||
int_setter setter,
|
||||
bool useDefault = true)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying int property '" << name << '\'');
|
||||
return getValue(name, true)->tieInt(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::tieFloat (const string &name,
|
||||
float_getter getter,
|
||||
float_setter setter,
|
||||
bool useDefault = true)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying float property '" << name << '\'');
|
||||
return getValue(name, true)->tieFloat(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::tieDouble (const string &name,
|
||||
double_getter getter,
|
||||
double_setter setter,
|
||||
bool useDefault = true)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying double property '" << name << '\'');
|
||||
return getValue(name, true)->tieDouble(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::tieString (const string &name,
|
||||
string_getter getter,
|
||||
string_setter setter,
|
||||
bool useDefault = true)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Tying string property '" << name << '\'');
|
||||
return getValue(name, true)->tieString(getter, setter, useDefault);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::untieBool (const string &name)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Untying bool property '" << name << '\'');
|
||||
return getValue(name, true)->untieBool();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::untieInt (const string &name)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Untying int property '" << name << '\'');
|
||||
return getValue(name, true)->untieInt();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::untieFloat (const string &name)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Untying float property '" << name << '\'');
|
||||
return getValue(name, true)->untieFloat();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::untieDouble (const string &name)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Untying double property '" << name << '\'');
|
||||
return getValue(name, true)->untieDouble();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FGPropertyList::untieString (const string &name)
|
||||
{
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Untying string property '" << name << '\'');
|
||||
return getValue(name, true)->untieString();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FGPropertyList::dumpToLog () const
|
||||
{
|
||||
const_iterator it = FGPropertyList::begin();
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Begin property list dump...");
|
||||
while (it != end()) {
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "Property: " << it->first);
|
||||
it++;
|
||||
}
|
||||
FG_LOG(FG_GENERAL, FG_INFO, "...End property list dump");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// end of props.cxx
|
295
simgear/misc/props.hxx
Normal file
295
simgear/misc/props.hxx
Normal file
@ -0,0 +1,295 @@
|
||||
// props.hxx -- class to manage global FlightGear properties.
|
||||
//
|
||||
// Copyright (C) 2000 David Megginson - david@megginson.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef __PROPS_HXX
|
||||
#define __PROPS_HXX
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
using std::string;
|
||||
using std::map;
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Values.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Abstract representation of a FlightGear value.
|
||||
*
|
||||
* This value is designed to be fairly robust -- it can exist without
|
||||
* a specified value, it can be any of several types, and it can
|
||||
* be tied to an external variable without disrupting any existing
|
||||
* pointers or references to the value. Some basic type conversions
|
||||
* are also handled automatically.
|
||||
*
|
||||
* Values also have attributes that control whether they can be read
|
||||
* from, written to, or archived (i.e. saved to disk).
|
||||
*/
|
||||
class FGValue
|
||||
{
|
||||
public:
|
||||
|
||||
// External getters
|
||||
typedef bool (*bool_getter)();
|
||||
typedef int (*int_getter)();
|
||||
typedef float (*float_getter)();
|
||||
typedef double (*double_getter)();
|
||||
typedef const string &(*string_getter)();
|
||||
|
||||
// External setters
|
||||
typedef void (*bool_setter)(bool);
|
||||
typedef void (*int_setter)(int);
|
||||
typedef void (*float_setter)(float);
|
||||
typedef void (*double_setter)(double);
|
||||
typedef void (*string_setter)(const string &);
|
||||
|
||||
enum Type {
|
||||
UNKNOWN, // no value assigned yet
|
||||
BOOL, // boolean
|
||||
INT, // integer
|
||||
FLOAT, // floating point
|
||||
DOUBLE, // double precision
|
||||
STRING // text
|
||||
};
|
||||
|
||||
FGValue ();
|
||||
virtual ~FGValue ();
|
||||
|
||||
// Meta information.
|
||||
virtual Type getType () const { return _type; }
|
||||
virtual bool isTied () const { return _tied; }
|
||||
|
||||
// Accessors.
|
||||
virtual bool getBoolValue () const;
|
||||
virtual int getIntValue () const;
|
||||
virtual float getFloatValue () const;
|
||||
virtual double getDoubleValue () const;
|
||||
virtual const string &getStringValue () const;
|
||||
|
||||
// Setters.
|
||||
virtual bool setBoolValue (bool value);
|
||||
virtual bool setIntValue (int value);
|
||||
virtual bool setFloatValue (float value);
|
||||
virtual bool setDoubleValue (double value);
|
||||
virtual bool setStringValue (const string &value);
|
||||
|
||||
// Tie to external variables.
|
||||
virtual bool tieBool (bool_getter getter,
|
||||
bool_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieInt (int_getter getter,
|
||||
int_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieFloat (float_getter getter,
|
||||
float_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieDouble (double_getter getter,
|
||||
double_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieString (string_getter getter,
|
||||
string_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
|
||||
// Untie from external variables.
|
||||
virtual bool untieBool ();
|
||||
virtual bool untieInt ();
|
||||
virtual bool untieFloat ();
|
||||
virtual bool untieDouble ();
|
||||
virtual bool untieString ();
|
||||
|
||||
protected:
|
||||
|
||||
bool getRawBool () const;
|
||||
int getRawInt () const;
|
||||
float getRawFloat () const;
|
||||
double getRawDouble () const;
|
||||
const string &getRawString () const;
|
||||
|
||||
bool setRawBool (bool value);
|
||||
bool setRawInt (int value);
|
||||
bool setRawFloat (float value);
|
||||
bool setRawDouble (double value);
|
||||
bool setRawString (const string & value);
|
||||
|
||||
private:
|
||||
|
||||
Type _type;
|
||||
bool _tied;
|
||||
|
||||
// The value is one of the following...
|
||||
union {
|
||||
|
||||
bool bool_val;
|
||||
int int_val;
|
||||
float float_val;
|
||||
double double_val;
|
||||
string * string_val;
|
||||
|
||||
struct {
|
||||
bool_setter setter;
|
||||
bool_getter getter;
|
||||
} bool_func;
|
||||
|
||||
struct {
|
||||
int_setter setter;
|
||||
int_getter getter;
|
||||
} int_func;
|
||||
|
||||
struct {
|
||||
void * obj;
|
||||
float_setter setter;
|
||||
float_getter getter;
|
||||
} float_func;
|
||||
|
||||
struct {
|
||||
void * obj;
|
||||
double_setter setter;
|
||||
double_getter getter;
|
||||
} double_func;
|
||||
|
||||
struct {
|
||||
string_setter setter;
|
||||
string_getter getter;
|
||||
} string_func;
|
||||
|
||||
} _value;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Top-level manager.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* A list of FlightGear properties.
|
||||
*
|
||||
* This list associates names (conventional written as paths,
|
||||
* i.e. "/foo/bar/hack") with FGValue classes. Once an FGValue
|
||||
* object is associated with the name, the association is
|
||||
* permanent -- it is safe to keep a pointer or reference.
|
||||
* however, that the type of a value may change if it is tied
|
||||
* to a variable.
|
||||
*
|
||||
* When iterating through the list, the value type is
|
||||
*
|
||||
* pair<string,FGValue>
|
||||
*
|
||||
* To get the name from a const_iterator, use
|
||||
*
|
||||
* it->first
|
||||
*
|
||||
* and to get the value from a const_iterator, use
|
||||
*
|
||||
* it->second
|
||||
*/
|
||||
class FGPropertyList
|
||||
{
|
||||
public:
|
||||
typedef map<string, FGValue> value_map;
|
||||
|
||||
typedef FGValue::bool_getter bool_getter;
|
||||
typedef FGValue::int_getter int_getter;
|
||||
typedef FGValue::float_getter float_getter;
|
||||
typedef FGValue::double_getter double_getter;
|
||||
typedef FGValue::string_getter string_getter;
|
||||
|
||||
typedef FGValue::bool_setter bool_setter;
|
||||
typedef FGValue::int_setter int_setter;
|
||||
typedef FGValue::float_setter float_setter;
|
||||
typedef FGValue::double_setter double_setter;
|
||||
typedef FGValue::string_setter string_setter;
|
||||
|
||||
typedef value_map::value_type value_type;
|
||||
typedef value_map::size_type size_type;
|
||||
typedef value_map::const_iterator const_iterator;
|
||||
|
||||
FGPropertyList ();
|
||||
virtual ~FGPropertyList ();
|
||||
|
||||
virtual size_type size () const { return _props.size(); }
|
||||
|
||||
virtual const_iterator begin () const { return _props.begin(); }
|
||||
virtual const_iterator end () const { return _props.end(); }
|
||||
|
||||
virtual FGValue * getValue (const string &name, bool create = false);
|
||||
virtual const FGValue * getValue (const string &name) const;
|
||||
|
||||
virtual bool getBoolValue (const string &name) const;
|
||||
virtual int getIntValue (const string &name) const;
|
||||
virtual float getFloatValue (const string &name) const;
|
||||
virtual double getDoubleValue (const string &name) const;
|
||||
virtual const string &getStringValue (const string &name) const;
|
||||
|
||||
virtual bool setBoolValue (const string &name, bool value);
|
||||
virtual bool setIntValue (const string &name, int value);
|
||||
virtual bool setFloatValue (const string &name, float value);
|
||||
virtual bool setDoubleValue (const string &name, double value);
|
||||
virtual bool setStringValue (const string &name, const string &value);
|
||||
|
||||
virtual bool tieBool (const string &name,
|
||||
bool_getter getter,
|
||||
bool_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieInt (const string &name,
|
||||
int_getter getter,
|
||||
int_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieFloat (const string &name,
|
||||
float_getter getter,
|
||||
float_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieDouble (const string &name,
|
||||
double_getter getter,
|
||||
double_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
virtual bool tieString (const string &name,
|
||||
string_getter getter,
|
||||
string_setter setter = 0,
|
||||
bool useDefault = true);
|
||||
|
||||
virtual bool untieBool (const string &name);
|
||||
virtual bool untieInt (const string &name);
|
||||
virtual bool untieFloat (const string &name);
|
||||
virtual bool untieDouble (const string &name);
|
||||
virtual bool untieString (const string &name);
|
||||
|
||||
virtual void dumpToLog () const;
|
||||
|
||||
private:
|
||||
value_map _props;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Global property manager.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern FGPropertyList current_properties;
|
||||
|
||||
|
||||
#endif __PROPS_HXX
|
Loading…
Reference in New Issue
Block a user