Пользовательские параметры конфигурационного файла
Как вы помните, мы написали много кода, совершенствуя наш тестовый локомотив. При этом мы ввели множество параметров, описывающих его характеристики. Значения этих параметров жестко задаются в коде, и не подлежат изменению без пересборки DLL-модуля. И это очень плохо.
Хорошим тоном для любого разработчика является дать пользователю возможность изменять параметры программы без доступа к её исходному коду.
Такая возможность есть в RRS, и заключается она в том, что в конфиге подвижной единицы можно, наряду со стандартными, описать и собственные параметры. Добавим в конфиг ПЕ vehicles/simple-loco/simple-loco.xml, в секцию Vehicle следующие параметры
<F_max>450.0</F_max> <F_nom>350.0</F_nom> <V_nom>80.0</V_nom>
Как вы уже догадались, это характерные токи тяговой характеристики нашего локомотива. Чтобы прочитать эти параметры, необходимо переопределить в кассе SimpleLoco метод loadConfig()
/// Обработка нажатия клавиш void keyProcess(); /// Шаг моделирования систем локомотива void step(double t, double dt); /// Расчет тяговой характеристики double trac_char(double v); /// Загрузка пользовательских параметров из конфига void loadConfig(QString cfg_path); };
Пишем реализацию данного метода в simple-loco.cpp
void SimpleLoco::loadConfig(QString cfg_path)
{
// Создаем экземпляр "читателя" XML-конфигов
CfgReader cfg;
// Открываем конфигурационный файл по переданному движком пути
if (cfg.load(cfg_path))
{
// Задаем имя секции конфига, из которой будем читать параметры
QString sectionName = "Vehicle";
// Читаем интересующие нас параметы в соотвествующие переменные
cfg.getDouble(sectionName, "F_max", F_max);
cfg.getDouble(sectionName, "F_nom", F_nom);
cfg.getDouble(sectionName, "V_nom", V_nom);
}
}
Вызов этого методы выполняется движком игры, и через параметр cfg_path в него передается абсолютный путь к конфигу ПЕ. Остается только создать специальный объект класса CfgReader, который выполняет отказоустойчивое удобное чтение параметров из XML-конфига. Параметры содержаться в секции Vehicle конфига. Класс CfgReader имеет несколько методов, для получения значений из конфигов
- bool getDouble(QString secName, QString paramName, double ¶m) — получение вещественного параметра paramName из секции secName. Параметр помещается в переменную param, передаваемую по ссылке;
- bool getInt(QString secName, QString paramName, int ¶m) — получение целого параметра;
- bool getString(QString secName, QString paramName, QString ¶m) — получение строкового параметра.
То есть код
cfg.getDouble(sectionName, "F_max", F_max);
читает параметр с именем «F_max», секции «Vehicle» конфига, и помещает значение в переменную F_max. Остальные вызовы действуют аналогичным образом.
То есть теперь, не пересобирая модуль ПЕ, мы сможем менять его параметры через конфиг, в частности настраивать тяговую характеристику в данном случае.
Можете провести теперь несколько экспериментов, меняя параметры в конфиге и наблюдая, как меняются тяговые свойства локомотива.