-
-
Save Reputeless/0168858830805b8c2f90085869ad45b4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # include <Siv3D.hpp> // OpenSiv3D v0.6.15 | |
| struct MyClass | |
| { | |
| String name; | |
| int32 id = 0; | |
| }; | |
| template <> | |
| MyClass s3d::Parse<MyClass>(StringView s) | |
| { | |
| if (s.isEmpty()) | |
| { | |
| return{ U"ERROR", -1 }; | |
| } | |
| // | |
| // ここでは、文字列を「(name id)」という形式でパースする。 | |
| // | |
| // 先頭の ( を削除する | |
| s.remove_prefix(1); | |
| // 末尾の ) を削除する | |
| s.remove_suffix(1); | |
| // 空白で 2 つに分割する | |
| const Array<String> items = String{ s }.split(U' '); | |
| if (items.size() != 2) | |
| { | |
| return{ U"ERROR", -1 }; | |
| } | |
| return{ items[0], ParseOr<int32>(items[1], -1) }; | |
| } | |
| template <> | |
| struct SIV3D_HIDDEN fmt::formatter<MyClass, s3d::char32> | |
| { | |
| std::u32string tag; | |
| auto parse(basic_format_parse_context<s3d::char32>& ctx) | |
| { | |
| return s3d::detail::GetFormatTag(tag, ctx); | |
| } | |
| template <class FormatContext> | |
| auto format(const MyClass& value, FormatContext& ctx) | |
| { | |
| // 出力形式を指定する。ここでは「(name id)」という形式で出力。 | |
| // これに対応した Parse 関数を定義しておく必要がある。 | |
| return format_to(ctx.out(), U"({} {})", value.name, value.id); | |
| } | |
| }; | |
| namespace s3d::Productivity | |
| { | |
| class QuickConfig | |
| { | |
| private: | |
| using Variant = std::variant<int8*, int16*, int32*, int64*, uint8*, uint16*, uint32*, uint64*, | |
| float*, double*, bool*, String*, Point*, Float2*, Vec2*, Float3*, Float4*, Vec4*, | |
| Color*, ColorF*, HSV*, Circular*, Rect*, Circle*, Line*, Triangle*, Quad*, Ellipse*, RoundRect*, | |
| MyClass*>; | |
| HashTable<std::string, std::pair<Variant, size_t>> m_data; | |
| FilePath m_iniPath = FileSystem::FullPath(U"QUICK_CONFIG.ini"); | |
| DirectoryWatcher m_watcher; | |
| public: | |
| template <class Type> | |
| void capture(Type& value, const std::string& name) | |
| { | |
| m_data.emplace(name, std::pair<Variant, size_t>{ std::addressof(value), m_data.size() }); | |
| } | |
| void generateINI() | |
| { | |
| Array<std::pair<std::string, Variant>> values(m_data.size()); | |
| for (const auto& data : m_data) | |
| { | |
| values[data.second.second] = { data.first, data.second.first }; | |
| } | |
| { | |
| TextWriter writer(m_iniPath); | |
| for (const auto& value : values) | |
| { | |
| std::visit([&](const auto p) | |
| { | |
| writer.writeln(U"{} = {}"_fmt(Unicode::Widen(value.first), *p)); | |
| }, value.second); | |
| } | |
| } | |
| m_watcher = DirectoryWatcher{ FileSystem::ParentPath(m_iniPath) }; | |
| } | |
| void update() | |
| { | |
| for (auto&& [path, action] : m_watcher.retrieveChanges()) | |
| { | |
| if ((path == m_iniPath) | |
| && ((action == FileAction::Modified) || (action == FileAction::Added))) | |
| { | |
| return read(); | |
| } | |
| } | |
| } | |
| void read() | |
| { | |
| const INI ini{ m_iniPath }; | |
| for (auto& data : m_data) | |
| { | |
| const String s = ini[Unicode::Widen(data.first)]; | |
| std::visit([&](auto p) | |
| { | |
| *p = Parse<std::remove_pointer_t<decltype(p)>>(s); | |
| }, data.second.first); | |
| } | |
| } | |
| }; | |
| # define QC_BEGIN() Productivity::QuickConfig _quickConfig; | |
| # define QC(value) _quickConfig.capture(value, #value); | |
| # define QC_END() _quickConfig.generateINI(); | |
| # define QC_UPDATE() _quickConfig.update(); | |
| } | |
| void Main() | |
| { | |
| const Font font{ FontMethod::MSDF, 48 }; | |
| QC_BEGIN(); | |
| int32 a = 100; QC(a); | |
| double b = 3.1415; QC(b); | |
| ColorF bg{ 0.1, 0.5, 0.3 }; QC(bg); | |
| String text = U"Siv3D"; QC(text); | |
| Point pos{ 20, 30 }; QC(pos); | |
| ColorF col{ 0.7 }; QC(col); | |
| Rect rect{ 20, 90, 80, 20 }; QC(rect); | |
| RoundRect rrect{ 200, 100, 100, 40, 8 }; QC(rrect); | |
| MyClass myClass{ U"Test", 123 }; QC(myClass); | |
| QC_END(); | |
| while (System::Update()) | |
| { | |
| QC_UPDATE(); | |
| Scene::SetBackground(bg); | |
| font(U"{}, {}, {}"_fmt(a, b, text)).draw(30, pos, col); | |
| rect.draw(); | |
| rrect.draw(); | |
| font(U"{}"_fmt(myClass)).draw(30, 200); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment