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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
#pragma once
#include <hyprutils/animation/AnimationConfig.hpp>
#include <vector>
#include <string>
#include <optional>
#include <chrono>
#include <string_view>
#include <unordered_map>
#include "../../helpers/memory/Memory.hpp"
#include "../ConfigManager.hpp"
#include "../../managers/eventLoop/EventLoopTimer.hpp"
#include "./types/LuaConfigValue.hpp"
#include "./LuaEventHandler.hpp"
#include "../../desktop/rule/windowRule/WindowRule.hpp"
#include "../../desktop/rule/layerRule/LayerRule.hpp"
#include "../../SharedDefs.hpp"
#include "../../managers/KeybindManager.hpp"
#include "../shared/ConfigErrors.hpp"
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
namespace Config::Supplementary {
struct SConfigOptionDescription;
};
namespace Config::Lua {
class CConfigManager;
class CConfigManagerPluginLuaTestAccessor;
}
namespace Config::Lua::Bindings {
void registerBindings(lua_State* L, CConfigManager* mgr);
}
namespace Config::Lua {
class CConfigManager : public Config::IConfigManager {
public:
CConfigManager();
virtual eConfigManagerType type() override;
virtual void init() override;
virtual void reload() override;
virtual std::string verify() override;
virtual int getDeviceInt(const std::string&, const std::string&, const std::string& fallback = "") override;
virtual float getDeviceFloat(const std::string&, const std::string&, const std::string& fallback = "") override;
virtual Vector2D getDeviceVec(const std::string&, const std::string&, const std::string& fallback = "") override;
virtual std::string getDeviceString(const std::string&, const std::string&, const std::string& fallback = "") override;
virtual bool deviceConfigExplicitlySet(const std::string&, const std::string&) override;
virtual bool deviceConfigExists(const std::string&) override;
virtual SConfigOptionReply getConfigValue(const std::string&) override;
virtual std::string getMainConfigPath() override;
virtual std::string getErrors() override;
virtual std::string getConfigString() override;
virtual std::string currentConfigPath() override;
virtual const std::vector<std::string>& getConfigPaths() override;
virtual std::expected<void, std::string> generateDefaultConfig(const std::filesystem::path&, bool safeMode) override;
virtual void handlePluginLoads() override;
virtual bool configVerifPassed() override;
virtual std::expected<void, std::string> registerPluginValue(void* handle, SP<Config::Values::IValue> value) override;
virtual void onPluginUnload(void* handle) override;
int invokePluginLuaFunctionByID(uint64_t id, lua_State* L);
std::expected<void, std::string> registerPluginLuaFunction(void* handle, const std::string& namespace_, const std::string& name, PLUGIN_LUA_FN fn);
std::expected<void, std::string> unregisterPluginLuaFunction(void* handle, const std::string& namespace_, const std::string& name);
void addError(std::string&& str);
void addEvalIssue(const Config::SConfigError& err);
void registerLuaRef(int ref);
void callLuaFn(int ref);
// execute an arbitrary lua string on the current state.
std::optional<std::string> eval(const std::string& code);
int guardedPCall(int nargs, int nresults, int errfunc, int timeoutMs, std::string_view context);
static CConfigManager* fromLuaState(lua_State* L);
static constexpr int LUA_WATCHDOG_INSTRUCTION_INTERVAL = 10000;
static constexpr int LUA_TIMEOUT_CONFIG_RELOAD_MS = 1500;
static constexpr int LUA_TIMEOUT_EVENT_CALLBACK_MS = 50;
static constexpr int LUA_TIMEOUT_KEYBIND_CALLBACK_MS = 100;
static constexpr int LUA_TIMEOUT_TIMER_CALLBACK_MS = 50;
static constexpr int LUA_TIMEOUT_EVAL_MS = 250;
static constexpr int LUA_TIMEOUT_DISPATCH_MS = 100;
bool isFirstLaunch() const;
bool isDynamicParse() const;
std::string m_currentSubmap;
std::string m_currentSubmapReset;
UP<CLuaEventHandler> m_eventHandler;
struct SLuaTimer {
SP<CEventLoopTimer> timer;
int luaRef = LUA_NOREF; // registry ref to the lua callback
};
std::vector<SLuaTimer> m_luaTimers;
std::vector<std::string> m_registeredPlugins;
std::unordered_map<std::string, UP<ILuaConfigValue>> m_configValues;
struct SDeviceConfig {
SDeviceConfig();
std::unordered_map<std::string, UP<ILuaConfigValue>> values;
};
std::unordered_map<std::string, SDeviceConfig> m_deviceConfigs;
std::vector<std::string> m_errors, m_configPaths;
std::vector<Config::SConfigError> m_evalIssues;
// named window/layer rules for merge-on-redeclaration
std::unordered_map<std::string, SP<Desktop::Rule::CWindowRule>> m_luaWindowRules;
std::unordered_map<std::string, SP<Desktop::Rule::CLayerRule>> m_luaLayerRules;
private:
void reinitLuaState();
void postConfigReload();
void registerValue(const char* name, ILuaConfigValue* val);
void cleanTimers();
void clearHeldLuaRefs();
std::string luaConfigValueName(const std::string& s);
std::expected<void, std::string> registerPluginLuaFunctionInState(uint64_t id, const std::string& namespace_, const std::string& name);
std::expected<void, std::string> unregisterPluginLuaFunctionInState(const std::string& namespace_, const std::string& name);
void erasePluginLuaFunction(uint64_t id);
void reregisterLuaPluginFns();
static void watchdogHook(lua_State* L, lua_Debug* ar);
lua_State* m_lua = nullptr;
bool m_lastConfigVerificationWasSuccessful = true;
bool m_isFirstLaunch = true;
bool m_manualCrashInitiated = false;
bool m_watchdogActive = false;
bool m_isParsingConfig = false;
bool m_isEvaluating = false;
std::chrono::steady_clock::time_point m_watchdogDeadline;
std::string m_watchdogContext;
std::string m_mainConfigPath;
std::vector<int> m_heldLuaRefs;
// this is here for legacy reasons.
std::unordered_map<std::string, const void*> m_configPtrMap;
// this is here for plugin reasons.
std::unordered_map<void* /* HANDLE */, std::vector<std::string>> m_pluginValues;
struct SPluginLuaFunction {
uint64_t id = 0;
void* handle = nullptr;
std::string namespace_;
std::string name;
Config::PLUGIN_LUA_FN fn = nullptr;
};
std::vector<SPluginLuaFunction> m_pluginLuaFunctions;
ILuaConfigValue* findDeviceValue(const std::string& dev, const std::string& field);
friend class CConfigManagerPluginLuaTestAccessor;
};
WP<CConfigManager> mgr();
}
|