実行時に調整出来るパラメータ
実行時に調整できるシリーズ。正確には CSV/JSON/TOML/XML のホットリロードを簡単に出来るようにする、という趣旨のもの。なお、INI はなぜかコピーコンストラクタが無いので除外。
code:config.cpp
namespace fs = std::filesystem;
namespace tomolatoon
{
namespace CollectionLoader
{
template <class T>
T Load(FilePathView fpv)
{
return T{fpv};
}
template <>
JSON Load<JSON>(FilePathView fpv)
{
return JSON::Load(fpv);
}
} // namespace CollectionLoader
template <class T>
struct Config
{
using Dir = fs::path;
using FullPath = fs::path;
using ID = String;
struct TrackData
{
DirectoryWatcher watcher;
HashTable<FullPath, ID> refs;
};
struct Addon: IAddon
{
friend Config;
bool update() override
{
{
for (auto&& path, action : trackdata.watcher.retrieveChanges()) {
if (action == FileAction::Added || action == FileAction::Modified)
{
if (auto it = trackdata.refs.find(fs::path{path.toUTF32()}.make_preferred()); it != trackdata.refs.end())
{
collectionsit->second = CollectionLoader::Load<T>(path); }
}
}
}
return true;
}
private:
inline static HashTable<Dir, TrackData> watchers;
inline static HashTable<ID, T> collections;
inline static HashTable<ID, Dir> dirs;
};
static bool Add(ID id, fs::path path)
{
std::error_code ec;
fs::path full = fs::canonical(path, ec);
if (ec)
{
Console << U"Config::add: {}"_fmt(Unicode::Widen(ec.message()));
return false;
}
if (Addon::collections.contains(id))
{
Console << U"Config::add: The id is already used.";
return false;
}
auto parent = full.parent_path();
if (Addon::watchers.contains(parent))
{
Addon::watchersparent.refs.emplace(full, id); Addon::collectionsid = CollectionLoader::Load<T>(full.u32string()); }
else
{
Addon::watchersparent = {DirectoryWatcher{parent.u32string()}, {{full, id}}}; Addon::collectionsid = CollectionLoader::Load<T>(full.u32string()); }
return true;
}
static void Remove(ID id)
{
if (auto i_dir = Addon::dirs.find(id); i_dir != Addon::dirs.end())
{
if (auto i_watcher = Addon::watchers.find(i_dir->second); i_watcher != Addon::watchers.end())
{
if (auto i_ref = i_watcher->second.refs.find(i_dir->second); i_ref != i_watcher->second.refs.end())
{
i_watcher->second.refs.erase(i_ref);
if (i_watcher->second.refs.empty())
{
Addon::watchers.erase(i_watcher);
}
Addon::collections.erase(id);
Addon::dirs.erase(id);
}
}
}
}
Config(ID id)
: m_id(id)
{}
const T& data() const
{
return Addon::collectionsm_id; }
private:
ID m_id;
};
} // namespace tomolatoon
void Main()
{
Window::Resize(1755, 810, Centering::Yes);
Scene::SetResizeMode(ResizeMode::Actual);
Scene::SetBackground(Color(U"#B8C9CD"));
Addon::Register<tomolatoon::Config<CSV>::Addon>(U"config");
//Addon::Register<tomolatoon::Config<INI>::Addon>(U"config");
Addon::Register<tomolatoon::Config<JSON>::Addon>(U"config");
Addon::Register<tomolatoon::Config<TOMLReader>::Addon>(U"config");
Addon::Register<tomolatoon::Config<XMLReader>::Addon>(U"config");
tomolatoon::Config<CSV>::Add(U"config", U"./test_csv.csv");
//tomolatoon::Config<INI>::Add(U"config", U"./test_config.ini");
tomolatoon::Config<JSON>::Add(U"config", U"./test_config.json");
tomolatoon::Config<TOMLReader>::Add(U"config", U"./test_config.toml");
tomolatoon::Config<XMLReader>::Add(U"config", U"./test_config.xml");
while (System::Update())
{
ClearPrint();
auto&& csv = tomolatoon::Config<CSV>(U"config").data();
//auto&& ini = tomolatoon::Config<INI>(U"config").data();
auto&& json = tomolatoon::Config<JSON>(U"config").data();
auto&& toml = tomolatoon::Config<TOMLReader>(U"config").data();
auto&& xml = tomolatoon::Config<XMLReader>(U"config").data();
}
}