Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

Smeshan avatar Smeshan 89 Точки

Четене на настройки от файл

Здравейте,

искам да направя настройките да се четат от файл.

Това което направих за сега:

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() стана адски нечетима.. :/

Ще продължа да го мисля и преработвам, но ще се радвам да се получи някаква дискусия и да съберем добри идеи :)

Поздрави,
Илиян

Тагове:
1
C++ Applications Development 17/10/2021 00:07:01
Smeshan avatar Smeshan 89 Точки

Оправих точка 3 с един enum. По-добре стана.

enum monitorConfig {
    WINDOW_NAME,
    DISPLAY_HEIGHT,
    DISPLAY_WIDTH
};

...

static void populateMonitorConfig(MonitorConfig &outConfig) {
    outConfig.windowName = readConfigFromFile(WINDOW_NAME);
    outConfig.windowHeight = stoi(readConfigFromFile(DISPLAY_HEIGHT));
    outConfig.windowWidth = stoi(readConfigFromFile(DISPLAY_WIDTH));
    outConfig.windowFlags = WINDOW_SHOWN;
}

 

1
Smeshan avatar Smeshan 89 Точки

И още подобрения:

enum monitorConfig {
    WINDOW_NAME,
    DISPLAY_HEIGHT,
    DISPLAY_WIDTH
};

const char *MONITOR_CFG_FILE = "../sdl_utils/config/MonitorConfig.txt";

static std::vector<std::string> readConfigsFromFile() {
    std::vector<std::string> configs;
    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;
    std::string discard;

    while (!file.eof()) { // eof -> end of file
        getline(file, discard, ':'); //delete text before ':'
        getline(file, configLine);
        configs.push_back(configLine);
    }
    return configs;
}

static void populateMonitorConfig(MonitorConfig &outConfig) {
    std::vector<std::string> configs = readConfigsFromFile();

    outConfig.windowName = configs[WINDOW_NAME];
    outConfig.windowHeight = stoi(configs[DISPLAY_HEIGHT]);
    outConfig.windowWidth = stoi(configs[DISPLAY_WIDTH]);
    outConfig.windowFlags = WINDOW_SHOWN;
}

И все пак, това е един начин да се направи. А и станаха много include-и или това не е проблем?
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

0
17/10/2021 00:17:14
j.petrov_90 avatar j.petrov_90 373 Точки

Привет, Илиян,

Адмирации, че си правиш труда да работиш в тази посока!
За жалост, ако искаш функционалността да е четима, лесна за използване и трудна да правене на грешки - трябва да вложиш още усилия.

Главният проблем, е че във 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) пиеш една бира за добре свършената работа

Поздрави
 

0
17/10/2021 00:21:02
Smeshan avatar Smeshan 89 Точки

Благодаря за насоките!

Ето каква я свърших:..
Създадох още файлове:
..
> sdl_utils
    > config
        > tools
            > ConfigApplier.h
            > ConfigExtractor.h
            > ConfigValidator.h
      > MonitorConfig.h
      > MonitorConfig.txt

 

MonitorConfig.txt

WINDOW_NAME:Hardwear renderering
DISPLAY_HEIGHT:800
DISPLAY_WIDTH:600

Сложих всички enum-и константи в MonitorConfig.h. Раздробих на класове. И вече EngineConfigLoader.cpp изглежда така:

. . .
/* C++ system icnludes */
#include <string>
#include <unordered_map>

/* Third-party icnludes */

/* Own icnludes */
#include "sdl_utils/config/tools/ConfigExtractor.h"
#include "sdl_utils/config/tools/ConfigApplier.h"

const char *MONITOR_CFG_FILE = "../sdl_utils/config/MonitorConfig.txt";

typedef std::unordered_map<std::string, std::string> configData;

static void populateMonitorConfig(MonitorConfig &outConfig) {
    const configData data = ConfigExtractor::readFromFile(MONITOR_CFG_FILE);
    ConfigApplier::setConfigs(data, outConfig);
}
. . .


По-добре е, ще видим като добавяме настройки дали ще сработва.
Мисля, че мястото на тези файлове не са в sdl_utils и май да изкарам папка tools отвън? Защото могат да се ползват и за други данни.

Поздрави!

П.С. Сега като го гледам втори път, не ми харесва в ConfigApplier.h да има windowName и т .н., неща които нямат общо с config applier. Може би не трябваше да го изкарвам от EngineConfigLoader.cpp, тоест да върна съдържанието на setConfigs() обратно както си беше. :?

1
17/10/2021 14:08:10
j.petrov_90 avatar j.petrov_90 373 Точки

Привет,

Започваш за си задаваш правилните въпроси. Това е хубаво.
"Туловете", които създаде нямат нищо общо с SDL.
Това са тулове за четене и валидиране на конфигурация. Тяхното място е ... в utils.

Грешно се мъчиш от "тула" да достъпъш логиката за съответния конфиг (например window name).
Тула трябва да е "глупав" и да не знае нищо за компонентите, които биха го използвали.
Той просто съхранява някакви стрингове.

Т.е. няма да имаш "ConfigApplier", а ще оставиш всеки, който го интересува да преизползва тоци тул и сам да си приложи логиката (да си сетне полетата).

Поздрави

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.