Четене на настройки от файл
Здравейте,
искам да направя настройките да се четат от файл.
Това което направих за сега:
MonitorConfig.txt
name of the display:Hardwear renderering
display height:800
display width:600
EngineConfigLoader.cpp (не е целия)
const char* MONITOR_CFG_FILE = "../sdl_utils/config/MonitorConfig.txt";
static std::string readConfigFromFile(const int32_t lineNum) {
std::fstream file(MONITOR_CFG_FILE );
if (!file.is_open()) {
std::cerr << "Unable to open config file: " << MONITOR_CFG_FILE << std::endl;
}
std::string configLine;
int32_t currLine = 0;
while (!file.eof()) { // eof -> end of file
std::string discard;
if (currLine == lineNum) {
getline(file, discard, ':'); //delete text before ':'
getline(file, configLine);
//std::cerr << "Line: " << configLine << std::endl;
break;
}
getline(file, discard);
//std::cerr << "Discard: " << discard << std::endl;
currLine++;
}
return configLine;
}
static void populateMonitorConfig(MonitorConfig &outConfig) {
outConfig.windowName = readConfigFromFile(0);
outConfig.windowHeight = stoi(readConfigFromFile(1));
outConfig.windowWidth = stoi(readConfigFromFile(2));
outConfig.windowFlags = WINDOW_SHOWN;
}
И няколко неща не ми харесват или се чудя как да станат:
1. Като станат 100 настройки, while цикъла ще има да си върти докато стигне до 87-мия ред (примерно) за да го вземе. :Х И т. н..
2. Реда на настройките във файла трябва напълно да отговаря на реда, в който съм ги написал в populateMonitorConfig() (или поне номера на реда да отговаря). Това ми се струва бомба със закъснител и отделно трудно за промени..
3. populateMonitorConfig() стана адски нечетима.. :/
Ще продължа да го мисля и преработвам, но ще се радвам да се получи някаква дискусия и да съберем добри идеи :)
Поздрави,
Илиян
И още подобрения:
И все пак, това е един начин да се направи. А и станаха много include-и или това не е проблем?
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
Привет, Илиян,
Адмирации, че си правиш труда да работиш в тази посока!
За жалост, ако искаш функционалността да е четима, лесна за използване и трудна да правене на грешки - трябва да вложиш още усилия.
Главният проблем, е че във 1 файл се опитват да правиш 3 коренно различни неща:
- четене от файл следвайки някакъв стил (nameOfParam:value)
- валидация на прочетената ивформация
- попълване на информацията от файла в структурите на програмата ти.
Разбиий това в 3 отделни класа, които правят само по 1 нещо и си 6 :)
1) четене от файл - ще изчита информацията и ще я съхранява в удобна за ползване структура. Може да я сложиш в map/unordered_map, където за ключ имаш std::string (името на параметъра) и std::string за неговото value.
2) валидация на горната конфигурация - какво става ако ти попълня display width:pesho? std::stoi функцията в последствие би хвърлила exception
3) използваш новата си структура с валидирана информация да попълниш структурите от програмата си (това вече го имаш).
4) пиеш една бира за добре свършената работа
Поздрави
Благодаря за насоките!
Ето каква я свърших:..
Създадох още файлове:
..
> sdl_utils
> config
> tools
> ConfigApplier.h
> ConfigExtractor.h
> ConfigValidator.h
> MonitorConfig.h
> MonitorConfig.txt
MonitorConfig.txt
Сложих всички enum-и константи в MonitorConfig.h. Раздробих на класове. И вече EngineConfigLoader.cpp изглежда така:
По-добре е, ще видим като добавяме настройки дали ще сработва.
Мисля, че мястото на тези файлове не са в sdl_utils и май да изкарам папка tools отвън? Защото могат да се ползват и за други данни.
Поздрави!
П.С. Сега като го гледам втори път, не ми харесва в ConfigApplier.h да има windowName и т .н., неща които нямат общо с config applier. Може би не трябваше да го изкарвам от EngineConfigLoader.cpp, тоест да върна съдържанието на setConfigs() обратно както си беше. :?