Skip to content

Commit 7c1b48f

Browse files
committed
Add static creation method for ConfigManager
1 parent 4696dd6 commit 7c1b48f

File tree

3 files changed

+79
-47
lines changed

3 files changed

+79
-47
lines changed

fly/config/config_manager.cpp

+43-25
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,40 @@
1111

1212
namespace fly {
1313

14+
//==================================================================================================
15+
std::shared_ptr<ConfigManager> ConfigManager::create(
16+
std::shared_ptr<SequencedTaskRunner> task_runner,
17+
ConfigFileType file_type,
18+
std::filesystem::path path)
19+
{
20+
// ConfigManager has a private constructor, thus cannot be used with std::make_shared. This
21+
// class is used to expose the private constructor locally.
22+
struct ConfigManagerImpl final : public ConfigManager
23+
{
24+
ConfigManagerImpl(
25+
std::shared_ptr<SequencedTaskRunner> task_runner,
26+
ConfigFileType file_type,
27+
std::filesystem::path path) noexcept :
28+
ConfigManager(std::move(task_runner), file_type, std::move(path))
29+
{
30+
}
31+
};
32+
33+
auto config_manager =
34+
std::make_shared<ConfigManagerImpl>(std::move(task_runner), file_type, std::move(path));
35+
return config_manager->start() ? config_manager : nullptr;
36+
}
37+
1438
//==================================================================================================
1539
ConfigManager::ConfigManager(
16-
const std::shared_ptr<SequencedTaskRunner> &task_runner,
40+
std::shared_ptr<SequencedTaskRunner> task_runner,
1741
ConfigFileType file_type,
18-
const std::filesystem::path &path) noexcept :
19-
m_path(path),
20-
m_task_runner(task_runner)
42+
std::filesystem::path path) noexcept :
43+
m_task_runner(std::move(task_runner)),
44+
m_path(std::move(path))
2145
{
46+
m_monitor = std::make_shared<PathMonitorImpl>(m_task_runner, create_config<PathConfig>());
47+
2248
switch (file_type)
2349
{
2450
case ConfigFileType::Ini:
@@ -47,35 +73,27 @@ ConfigManager::~ConfigManager()
4773
//==================================================================================================
4874
bool ConfigManager::start()
4975
{
50-
if (m_parser)
76+
if (!m_parser || !m_monitor)
5177
{
52-
m_monitor = std::make_shared<PathMonitorImpl>(m_task_runner, create_config<PathConfig>());
78+
return false;
79+
}
5380

54-
if (m_monitor->start())
55-
{
56-
std::weak_ptr<ConfigManager> weak_self = shared_from_this();
81+
std::weak_ptr<ConfigManager> weak_self = shared_from_this();
5782

58-
auto callback = [weak_self](const std::filesystem::path &, PathMonitor::PathEvent)
83+
auto callback = [weak_self](std::filesystem::path, PathMonitor::PathEvent)
84+
{
85+
if (auto self = weak_self.lock(); self)
86+
{
87+
auto task = [](std::shared_ptr<ConfigManager> nested_self)
5988
{
60-
if (auto self = weak_self.lock(); self)
61-
{
62-
auto task = [](std::shared_ptr<ConfigManager> nested_self)
63-
{
64-
nested_self->update_config();
65-
};
66-
67-
self->m_task_runner->post_task(
68-
FROM_HERE,
69-
std::move(task),
70-
std::move(weak_self));
71-
}
89+
nested_self->update_config();
7290
};
7391

74-
return m_monitor->add_file(m_path, callback);
92+
self->m_task_runner->post_task(FROM_HERE, std::move(task), std::move(weak_self));
7593
}
76-
}
94+
};
7795

78-
return false;
96+
return m_monitor->add_file(m_path, callback);
7997
}
8098

8199
//==================================================================================================

fly/config/config_manager.hpp

+27-13
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,24 @@ class ConfigManager : public std::enable_shared_from_this<ConfigManager>
4242
};
4343

4444
/**
45-
* Constructor.
45+
* Create and start a configuration manager.
4646
*
4747
* @param task_runner Task runner for posting config-related tasks onto.
4848
* @param file_type File format of the configuration file.
4949
* @param path Path to the configuration file.
50+
*
51+
* @return The created configuration manager.
5052
*/
51-
ConfigManager(
52-
const std::shared_ptr<SequencedTaskRunner> &task_runner,
53+
static std::shared_ptr<ConfigManager> create(
54+
std::shared_ptr<SequencedTaskRunner> task_runner,
5355
ConfigFileType file_type,
54-
const std::filesystem::path &path) noexcept;
56+
std::filesystem::path path);
5557

5658
/**
5759
* Destructor. Stop the configuration manager and underlying objects.
5860
*/
5961
~ConfigManager();
6062

61-
/**
62-
* Start the configuration manager and underlying objects.
63-
*
64-
* @return True if the manager could be started.
65-
*/
66-
bool start();
67-
6863
/**
6964
* Create a configuration object, or if one with the given type's name exists, fetch it.
7065
*
@@ -83,19 +78,38 @@ class ConfigManager : public std::enable_shared_from_this<ConfigManager>
8378
ConfigMap::size_type prune();
8479

8580
private:
81+
/**
82+
* Constructor.
83+
*
84+
* @param task_runner Task runner for posting config-related tasks onto.
85+
* @param file_type File format of the configuration file.
86+
* @param path Path to the configuration file.
87+
*/
88+
ConfigManager(
89+
std::shared_ptr<SequencedTaskRunner> task_runner,
90+
ConfigFileType file_type,
91+
std::filesystem::path path) noexcept;
92+
93+
/**
94+
* Start the configuration manager and underlying objects.
95+
*
96+
* @return True if the manager could be started.
97+
*/
98+
bool start();
99+
86100
/**
87101
* Parse the configuration file and store the parsed values in memory.
88102
*/
89103
void update_config();
90104

105+
std::shared_ptr<SequencedTaskRunner> m_task_runner;
106+
91107
std::shared_ptr<PathMonitor> m_monitor;
92108
std::unique_ptr<Parser> m_parser;
93109
Json m_values;
94110

95111
const std::filesystem::path m_path;
96112

97-
std::shared_ptr<SequencedTaskRunner> m_task_runner;
98-
99113
mutable std::mutex m_configs_mutex;
100114
ConfigMap m_configs;
101115
};

test/config/config_manager.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,37 @@ CATCH_TEST_CASE("ConfigManager", "[config]")
5353
fly::test::PathUtil::ScopedTempDirectory config_path;
5454
std::filesystem::path config_file = config_path.file();
5555

56-
auto config_manager = std::make_shared<fly::ConfigManager>(
56+
auto config_manager = fly::ConfigManager::create(
5757
task_runner,
5858
fly::ConfigManager::ConfigFileType::Json,
5959
config_file);
60-
auto path_config = config_manager->create_config<TestPathConfig>();
61-
CATCH_REQUIRE(config_manager->start());
60+
CATCH_REQUIRE(config_manager);
6261

62+
auto path_config = config_manager->create_config<TestPathConfig>();
6363
auto initial_size = config_manager->prune();
6464

6565
CATCH_SECTION("Config managers can be started for all file types")
6666
{
67-
config_manager = std::make_shared<fly::ConfigManager>(
67+
config_manager = fly::ConfigManager::create(
6868
task_runner,
6969
fly::ConfigManager::ConfigFileType::Ini,
7070
config_file);
71-
CATCH_CHECK(config_manager->start());
71+
CATCH_CHECK(config_manager);
7272

73-
config_manager = std::make_shared<fly::ConfigManager>(
73+
config_manager = fly::ConfigManager::create(
7474
task_runner,
7575
fly::ConfigManager::ConfigFileType::Json,
7676
config_file);
77-
CATCH_CHECK(config_manager->start());
77+
CATCH_CHECK(config_manager);
7878
}
7979

8080
CATCH_SECTION("Cannot start a config manager of an unsupported file type")
8181
{
82-
config_manager = std::make_shared<fly::ConfigManager>(
82+
config_manager = fly::ConfigManager::create(
8383
task_runner,
8484
static_cast<fly::ConfigManager::ConfigFileType>(-1),
8585
config_file);
86-
CATCH_CHECK_FALSE(config_manager->start());
86+
CATCH_CHECK_FALSE(config_manager);
8787
}
8888

8989
CATCH_SECTION("Cannot create a config with a duplicated identifier")

0 commit comments

Comments
 (0)