// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include ZEN_THIRD_PARTY_INCLUDES_START #include #include ZEN_THIRD_PARTY_INCLUDES_END #include #include #include #include #include #include namespace zen::LuaConfig { void EscapeBackslash(std::string& InOutString); class OptionValue { public: virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) = 0; virtual void Parse(sol::object Object) = 0; virtual ~OptionValue() {} }; class StringOption : public OptionValue { public: explicit StringOption(std::string& Value); virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override; virtual void Parse(sol::object Object) override; std::string& Value; }; class FilePathOption : public OptionValue { public: explicit FilePathOption(std::filesystem::path& Value); virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override; virtual void Parse(sol::object Object) override; std::filesystem::path& Value; }; class BoolOption : public OptionValue { public: explicit BoolOption(bool& Value); virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder); virtual void Parse(sol::object Object); bool& Value; }; template class NumberOption : public OptionValue { public: explicit NumberOption(T& Value) : Value(Value) {} virtual void Print(std::string_view, zen::StringBuilderBase& StringBuilder) override { StringBuilder.Append(fmt::format("{}", Value)); } virtual void Parse(sol::object Object) override { Value = Object.as(); } T& Value; }; class LuaContainerWriter { public: LuaContainerWriter(zen::StringBuilderBase& StringBuilder, std::string_view Indent); ~LuaContainerWriter(); void BeginContainer(std::string_view Name); void WriteValue(std::string_view Name, std::string_view Value); void EndContainer(); private: zen::StringBuilderBase& StringBuilder; const std::size_t InitialIndent; std::string LocalIndent; }; class StringArrayOption : public OptionValue { public: explicit StringArrayOption(std::vector& Value); virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override; virtual void Parse(sol::object Object) override; private: std::vector& Value; }; std::shared_ptr MakeOption(std::string& Value); std::shared_ptr MakeOption(std::filesystem::path& Value); template std::shared_ptr MakeOption(T& Value) { return std::make_shared>(Value); }; std::shared_ptr MakeOption(bool& Value); std::shared_ptr MakeOption(std::vector& Value); struct Option { std::string CommandLineOptionName; std::shared_ptr Value; }; struct Options { public: template void AddOption(std::string_view Key, T& Value, std::string_view CommandLineOptionName = "") { OptionMap.insert_or_assign(std::string(Key), Option{.CommandLineOptionName = std::string(CommandLineOptionName), .Value = MakeOption(Value)}); }; void Parse(const std::filesystem::path& Path, const cxxopts::ParseResult& CmdLineResult); void Parse(const sol::state& LuaState, const cxxopts::ParseResult& CmdLineResult); void Touch(std::string_view Key); void Print(zen::StringBuilderBase& SB, const cxxopts::ParseResult& CmdLineResult); private: void Traverse(sol::table Table, std::string_view PathPrefix, const cxxopts::ParseResult& CmdLineResult); std::unordered_map OptionMap; std::unordered_set UsedKeys; }; } // namespace zen::LuaConfig