-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAPI.h
More file actions
189 lines (158 loc) · 5.96 KB
/
API.h
File metadata and controls
189 lines (158 loc) · 5.96 KB
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 "DLL.hpp"
#include "Option.hpp"
#include <cocos2d.h>
#include <matjson.hpp>
#include <Geode/Result.hpp>
#include <Geode/utils/function.hpp>
#include <Geode/utils/StringMap.hpp>
#include <Geode/utils/ZStringView.hpp>
struct HorribleOptionSave final {
bool enabled = false;
bool pin = false;
bool viewed = false;
};
template <>
struct matjson::Serialize<HorribleOptionSave> final {
static geode::Result<HorribleOptionSave> fromJson(matjson::Value const& value);
static matjson::Value toJson(HorribleOptionSave const& value);
};
// Container for Horrible Menu API functions
namespace horrible {
// Option manager for Horrible Menu
class AWCW_HORRIBLE_API_DLL OptionManager final {
private:
std::vector<Option> m_options; // Array of registered options
std::vector<std::string> m_categories; // Array of auto-registered categories
// Type alias for `geode::Function<void(bool)>`, used in hook delegation
using Callback = geode::Function<void(bool)>;
std::unordered_map<std::string_view, std::vector<Callback>> m_delegates; // Map of option ID to array of delegates to call when that option is toggled
protected:
OptionManager() = default;
OptionManager(const OptionManager&) = delete;
OptionManager& operator=(const OptionManager&) = delete;
/**
* Register a category if not already registered
*
* @param category Name of the category
*/
void registerCategory(std::string category);
/**
* Check if an option already exists
*
* @param id The ID of the option to check
*
* @returns Whether this option already exists or not
*/
bool doesOptionExist(std::string_view id) const noexcept;
public:
// Get option manager singleton
static OptionManager* get() noexcept;
/**
* Register a new option
*
* @param option Constructed option object
*/
void registerOption(Option option);
/**
* Returns a reference to the array of all registered options
*
* @returns An array of every registered option, main and external
*/
[[nodiscard]] std::span<const Option> getOptions() const noexcept;
/**
* Quickly check the toggle state of an option
*
* @param id The ID of the option to check
*
* @returns Boolean of the current value
*/
[[nodiscard]] bool isEnabled(std::string_view id) const;
/**
* Quickly check the pin state of an option
*
* @param id The ID of the option to check
*
* @returns Boolean of the current value
*/
[[nodiscard]] bool isPinned(std::string_view id) const;
/**
* Quickly check the viewed state of an option
*
* @param id The ID of the option to check
*
* @returns Boolean of the current value
*/
[[nodiscard]] bool isViewed(std::string_view id) const;
/**
* Get the saved data of an option
*
* @param id The ID of the option to check
*
* @returns The current save
*/
[[nodiscard]] HorribleOptionSave getOption(std::string_view id) const;
/**
* Returns the data of an option
*
* @param id The ID of the option to get
*
* @returns A result possibly containing the option object
*/
[[nodiscard]] geode::Result<Option const&> getOptionInfo(std::string_view id) const noexcept;
/**
* Returns the amount of delegate callbacks registered for an option
*
* @param id The ID of the option whose callbacks to check
*
* @returns The amount of callbacks registered for this option
*/
[[nodiscard]] size_t getDelegateCount(std::string_view id) const noexcept;
/**
* Set the toggle state of an option
*
* @param id The ID of the option to toggle
* @param enable Boolean to toggle to
*/
void toggleOption(geode::ZStringView id, bool enable);
/**
* Set the state of an option
*
* @param id The ID of the option to toggle
* @param enable Boolean to toggle to
* @param pin If this option is pinned by the user
* @param viewed If this option was already viewed by the user
*/
void setOption(geode::ZStringView id, bool enable, bool pin = false, bool viewed = true);
/**
* Upsert a new hook delegate
*
* @param id The ID of the option to set the delegate for
* @param callback The hook callback to register for this option's delegate
*/
void addDelegate(geode::ZStringView id, Callback&& callback);
/**
* Returns a reference to the array of all registered categories
*
* @returns An array of every category name
*/
[[nodiscard]] std::span<const std::string> getCategories() const noexcept;
};
/**
* Delegate hooks to OptionManager for dynamic toggling
*
* @param id The ID of the option to delegate for
* @param hooks The map of hooks to delegate
*/
AWCW_HORRIBLE_API_DLL void delegateHooks(geode::ZStringView id, geode::utils::StringMap<std::shared_ptr<geode::Hook>> const& hooks);
};
// Statically register an option
#define HORRIBLE_REGISTER_OPTION(opt) \
$execute { \
if (auto om = horrible::OptionManager::get()) om->registerOption(opt); \
}
// Delegate hooks to OptionManager for dynamic toggling
#define HORRIBLE_DELEGATE_HOOKS(optID) \
static void onModify(auto& self) { \
horrible::delegateHooks(optID, self.m_hooks); \
}