aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/config/luaconfig.h
blob: ce7013a9ac0c17b488f76c82d4a2607792387cda (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include <zenbase/concepts.h>
#include <zencore/fmtutils.h>
#include <zenutil/commandlineoptions.h>

ZEN_THIRD_PARTY_INCLUDES_START
#include <fmt/format.h>
#include <sol/sol.hpp>
ZEN_THIRD_PARTY_INCLUDES_END

#include <filesystem>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>

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<Integral T>
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>(); }
	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<std::string>& Value);
	virtual void Print(std::string_view Indent, zen::StringBuilderBase& StringBuilder) override;
	virtual void Parse(sol::object Object) override;

private:
	std::vector<std::string>& Value;
};

std::shared_ptr<OptionValue> MakeOption(std::string& Value);
std::shared_ptr<OptionValue> MakeOption(std::filesystem::path& Value);

template<Integral T>
std::shared_ptr<OptionValue>
MakeOption(T& Value)
{
	return std::make_shared<NumberOption<T>>(Value);
};

std::shared_ptr<OptionValue> MakeOption(bool& Value);
std::shared_ptr<OptionValue> MakeOption(std::vector<std::string>& Value);

struct Option
{
	std::string					 CommandLineOptionName;
	std::shared_ptr<OptionValue> Value;
};

struct Options
{
public:
	template<typename T>
	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<std::string, Option> OptionMap;
	std::unordered_set<std::string>			UsedKeys;
};

}  // namespace zen::LuaConfig