Skip to content

Commit b1c06d1

Browse files
committed
fixes
1 parent eecf1da commit b1c06d1

11 files changed

Lines changed: 104 additions & 97 deletions

File tree

include/Horrible.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ struct matjson::Serialize<HorribleOptionSave> final {
3939

4040
// Container for Horrible Ideas API functions
4141
namespace horrible {
42+
// Type alias for `geode::Function<void(bool)>`, used in hook delegation
43+
using HookToggleCallback = geode::Function<void(bool)>;
44+
4245
// Option manager for Horrible Ideas
4346
class AWCW_HORRIBLE_API_DLL OptionManager final : public cocos2d::CCObject {
4447
private:
4548
std::vector<Option> m_options; // Array of registered options
4649
std::vector<std::string> m_categories; // Array of auto-registered categories
4750

48-
std::unordered_map<std::string_view, std::vector<geode::Function<void(bool)>>> m_delegates; // Map of option ID to array of delegates to call when that option is toggled
51+
std::unordered_map<std::string_view, std::vector<HookToggleCallback>> m_delegates; // Map of option ID to array of delegates to call when that option is toggled
4952

5053
protected:
5154
OptionManager() = default; // Default constructor
@@ -147,7 +150,7 @@ namespace horrible {
147150
* @param id The ID of the option to set the delegate for
148151
* @param callback The hook callback to register for this option's delegate
149152
*/
150-
void addDelegate(geode::ZStringView id, geode::Function<void(bool)>&& callback);
153+
void addDelegate(geode::ZStringView id, HookToggleCallback&& callback);
151154

152155
/**
153156
* Returns a reference to the array of all registered categories
@@ -163,7 +166,7 @@ namespace horrible {
163166
* @param id The ID of the option to delegate for
164167
* @param hooks The map of hooks to delegate
165168
*/
166-
AWCW_HORRIBLE_API_DLL void delegateHooks(geode::ZStringView id, geode::utils::StringMap<std::shared_ptr<geode::Hook>>& hooks);
169+
AWCW_HORRIBLE_API_DLL void delegateHooks(geode::ZStringView id, geode::utils::StringMap<std::shared_ptr<geode::Hook>> const& hooks);
167170
};
168171

169172
// Statically register an option

src/hooks/Mock.cpp

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -73,42 +73,47 @@ class $modify(MockMenuLayer, MenuLayer) {
7373
ss->setAnchorPoint({0.5, 0.5});
7474
ss->setPosition({-192.f, getScaledContentHeight() / 2.f});
7575

76-
ss->setLoadCallback([this, ss, percent, rnd](Result<> res) {
76+
ss->setLoadCallback([self = WeakRef(this), screenshot = WeakRef(ss), percent, rnd](Result<> res) {
7777
if (res.isOk()) {
78-
log::info("Sprite loaded successfully from save dir PNG");
78+
if (auto s = self.lock()) {
79+
log::info("Sprite loaded successfully from save dir PNG");
7980

80-
auto const percLabelText = fmt::format("{}%", percent);
81+
if (auto ss = screenshot.lock()) {
82+
auto const percLabelText = fmt::format("{}%", percent);
8183

82-
auto percLabel = CCLabelBMFont::create(percLabelText.c_str(), "bigFont.fnt");
83-
percLabel->setID("percentage");
84-
percLabel->setPosition(ss->getScaledContentSize() / 2.f);
85-
percLabel->setAlignment(CCTextAlignment::kCCTextAlignmentLeft);
86-
percLabel->ignoreAnchorPointForPosition(false);
87-
percLabel->setAnchorPoint({ 0, 0 });
88-
percLabel->setScale(2.5);
84+
auto percLabel = CCLabelBMFont::create(percLabelText.c_str(), "bigFont.fnt");
85+
percLabel->setID("percentage");
86+
percLabel->setPosition(ss->getScaledContentSize() / 2.f);
87+
percLabel->setAlignment(CCTextAlignment::kCCTextAlignmentLeft);
88+
percLabel->ignoreAnchorPointForPosition(false);
89+
percLabel->setAnchorPoint({0, 0});
90+
percLabel->setScale(2.5);
8991

90-
ss->addChild(percLabel);
92+
ss->addChild(percLabel);
9193

92-
auto rA = randng::pc();
93-
auto rB = randng::pc();
94+
auto rA = randng::pc();
95+
auto rB = randng::pc();
9496

95-
float yA = getScaledContentHeight() * rB; // starting height pos
96-
float yB = getScaledContentHeight() * rA; // ending height pos
97+
float yA = s->getScaledContentHeight() * rB; // starting height pos
98+
float yB = s->getScaledContentHeight() * rA; // ending height pos
9799

98-
ss->setPositionY(getScaledContentHeight() * yA);
99-
ss->setRotation(360.f * (yA * yB)); // random rotation
100+
ss->setPositionY(s->getScaledContentHeight() * yA);
101+
ss->setRotation(360.f * (yA * yB)); // random rotation
100102

101-
auto move = CCEaseIn::create(CCMoveTo::create(10.f, { getScaledContentWidth() + 192.f, getScaledContentHeight() * yB }), 1.f);
102-
auto rotate = CCEaseOut::create(CCRotateBy::create(12.5f, 45.f), 1.f);
103+
auto move = CCEaseIn::create(CCMoveTo::create(10.f, {s->getScaledContentWidth() + 192.f, s->getScaledContentHeight() * yB}), 1.f);
104+
auto rotate = CCEaseOut::create(CCRotateBy::create(12.5f, 45.f), 1.f);
103105

104-
auto action = CCSpawn::createWithTwoActions(move, rotate);
105-
ss->runAction(action);
106+
auto action = CCSpawn::createWithTwoActions(move, rotate);
107+
ss->runAction(action);
106108

107-
log::info("Animated sprite successfully");
109+
log::info("Animated sprite successfully");
110+
};
111+
};
108112
} else {
109113
log::error("Sprite failed to load: {}", res.unwrapErr());
110-
ss->removeMeAndCleanup();
111-
}; });
114+
if (auto ss = screenshot.lock()) ss->removeMeAndCleanup();
115+
};
116+
});
112117

113118
ss->loadFromFile(fs::path(pngPath));
114119
addChild(ss, 999);

src/hooks/PlayLayer/Math.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,21 @@ class $modify(MathPlayLayer, PlayLayer) {
3939
};
4040

4141
void doQuiz(float) {
42-
auto f = m_fields.self();
43-
4442
if (m_isPracticeMode && !m_hasCompletedLevel && !m_playerDied) {
4543
log::debug("Showing math quiz");
4644

4745
if (options::isEnabled(id)) {
4846
if (auto quiz = MathQuiz::create()) {
4947
// handle correct/wrong answer
50-
quiz->setCallback([this](bool correct) {
51-
log::debug("math {}", correct ? "succeeded" : "failed");
52-
if (!correct) resetLevelFromStart();
53-
nextQuiz();
48+
quiz->setCallback([self = WeakRef(this), math = WeakRef(quiz)](bool correct) {
49+
if (auto s = self.lock()) {
50+
log::debug("math {}", correct ? "succeeded" : "failed");
51+
52+
if (!correct) s->resetLevelFromStart();
53+
s->nextQuiz();
54+
55+
if (auto quiz = math.lock()) quiz->removeMeAndCleanup();
56+
};
5457
});
5558

5659
#ifdef GEODE_IS_WINDOWS
@@ -59,8 +62,8 @@ class $modify(MathPlayLayer, PlayLayer) {
5962
m_uiLayer->addChild(quiz, 99);
6063
};
6164
} else {
62-
queueInMainThread([this]() {
63-
nextQuiz();
65+
queueInMainThread([self = WeakRef(this)]() {
66+
if (auto s = self.lock()) s->nextQuiz();
6467
});
6568
};
6669
};

src/hooks/PlayLayer/Spam.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,15 @@ class $modify(SpamPlayLayer, PlayLayer) {
4646
auto f = m_fields.self();
4747

4848
// handle correct/wrong answer
49-
spam->setCallback([this, f](bool success) {
50-
log::debug("spam {}", success ? "succeeded" : "failed");
51-
if (!success) resetLevelFromStart();
52-
nextSpam();
53-
54-
queueInMainThread([f]() {
55-
if (f) f->m_currentSpam = nullptr;
56-
});
49+
spam->setCallback([self = WeakRef(this), challenge = WeakRef(spam)](bool success) {
50+
if (auto s = self.lock()) {
51+
log::debug("spam {}", success ? "succeeded" : "failed");
52+
53+
if (!success) s->resetLevelFromStart();
54+
s->nextSpam();
55+
56+
if (auto spam = challenge.lock()) spam->removeMeAndCleanup();
57+
};
5758
});
5859

5960
#ifdef GEODE_IS_WINDOWS
@@ -63,8 +64,8 @@ class $modify(SpamPlayLayer, PlayLayer) {
6364
f->m_currentSpam = spam;
6465
};
6566
} else {
66-
queueInMainThread([this]() {
67-
nextSpam();
67+
queueInMainThread([self = WeakRef(this)]() {
68+
if (auto s = self.lock()) s->nextSpam();
6869
});
6970
};
7071
};
@@ -76,11 +77,14 @@ class $modify(SpamPlayLayer, PlayLayer) {
7677
auto f = m_fields.self();
7778

7879
if (player->m_isDead) {
79-
if (f->m_currentSpam) {
80+
if (auto spam = WeakRef(f->m_currentSpam).lock()) {
8081
log::trace("removing activate spam challenge after player death");
81-
f->m_currentSpam->removeMeAndCleanup();
82+
83+
spam->removeMeAndCleanup();
8284
nextSpam();
8385
};
86+
87+
f->m_currentSpam = nullptr;
8488
};
8589
};
8690
};

src/include/Horrible.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ void OptionManager::registerCategory(std::string category) {
2929
};
3030

3131
bool OptionManager::doesOptionExist(std::string_view id) const noexcept {
32-
for (auto const& option : getOptions())
32+
for (auto const& option : getOptions()) {
3333
if (option.id == id) return true;
34+
};
35+
3436
return false;
3537
};
3638

@@ -45,7 +47,7 @@ void OptionManager::registerOption(Option option) {
4547
};
4648
};
4749

48-
void OptionManager::addDelegate(ZStringView id, Function<void(bool)>&& callback) {
50+
void OptionManager::addDelegate(ZStringView id, HookToggleCallback&& callback) {
4951
auto& thisDelegate = m_delegates[id];
5052
thisDelegate.push_back(std::move(callback));
5153
};
@@ -105,23 +107,25 @@ OptionManager* OptionManager::get() noexcept {
105107
return inst;
106108
};
107109

108-
void horrible::delegateHooks(ZStringView id, utils::StringMap<std::shared_ptr<Hook>>& hooks) {
110+
void horrible::delegateHooks(ZStringView id, utils::StringMap<std::shared_ptr<Hook>> const& hooks) {
109111
if (auto om = OptionManager::get()) {
110112
auto value = om->isEnabled(id);
111113

112-
std::vector<Hook*> allHooks;
113-
for (auto& hook : hooks | std::views::values) {
114+
std::vector<std::weak_ptr<Hook>> allHooks;
115+
for (auto const& hook : hooks | std::views::values) {
114116
hook->setAutoEnable(value);
115117
log::trace("Set default state of '{}' hook for option {} to {}", hook->getDisplayName(), id, value ? "ON" : "OFF");
116-
allHooks.push_back(hook.get());
118+
allHooks.push_back(hook);
117119
};
118120

119121
om->addDelegate(
120122
id,
121123
[id, allHooks = std::move(allHooks)](bool value) {
122-
for (auto& hook : allHooks) {
123-
log::trace("Toggling {} hook '{}' {}...", id, hook->getDisplayName(), value ? "ON" : "OFF");
124-
(void)hook->toggle(value);
124+
for (auto const& hook : allHooks) {
125+
if (auto const h = hook.lock()) {
126+
log::trace("Toggling {} hook '{}' {}...", id, h->getDisplayName(), value ? "ON" : "OFF");
127+
(void)h->toggle(value);
128+
};
125129
};
126130
});
127131
} else {

src/main.cpp

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,10 @@
1313

1414
using namespace horrible::prelude;
1515

16-
inline static std::vector<Hook*> safeModeHooks;
17-
inline static std::vector<std::weak_ptr<Hook>> floatingBtnHooks;
18-
19-
#define HORRIBLE_HOOK_SAFEMODE(hookName) \
20-
static void onModify(auto& self) { \
21-
Result<Hook*> hookRes = self.getHook(hookName); \
22-
\
23-
if (auto hook = hookRes.unwrap()) { \
24-
auto safe = thisMod->getSettingValue<bool>(setting::SafeMode); \
25-
\
26-
hook->setAutoEnable(safe); \
27-
(void)hook->toggle(safe); \
28-
\
29-
safeModeHooks.push_back(hook); \
30-
}; \
31-
}
16+
static std::vector<std::weak_ptr<Hook>> s_safeModeHooks;
17+
static std::vector<std::weak_ptr<Hook>> s_floatingBtnHooks;
3218

33-
#define HORRIBLE_HOOK_FLOATINGBTN \
19+
#define HORRIBLE_HOOK_INTERNAL(vectorRef) \
3420
static void onModify(auto& self) { \
3521
utils::StringMap<std::shared_ptr<Hook>>& hooks = self.m_hooks; \
3622
auto enable = thisMod->getSettingValue<bool>(setting::FloatingBtn); \
@@ -39,7 +25,7 @@ inline static std::vector<std::weak_ptr<Hook>> floatingBtnHooks;
3925
hook->setAutoEnable(enable); \
4026
(void)hook->toggle(enable); \
4127
\
42-
floatingBtnHooks.push_back(hook); \
28+
vectorRef.push_back(hook); \
4329
}; \
4430
}
4531

@@ -50,9 +36,11 @@ inline static std::vector<std::weak_ptr<Hook>> floatingBtnHooks;
5036
listenForSettingChanges<bool>(
5137
setting::SafeMode,
5238
[](bool value) {
53-
for (auto& hook : safeModeHooks) {
54-
log::trace("Toggling safe mode hook '{}' {}...", hook->getDisplayName(), value ? "ON" : "OFF");
55-
(void)hook->toggle(value);
39+
for (auto const& hook : s_safeModeHooks) {
40+
if (auto const h = hook.lock()) {
41+
log::trace("Toggling safe mode hook '{}' {}...", h->getDisplayName(), value ? "ON" : "OFF");
42+
(void)h->toggle(value);
43+
};
5644
};
5745
});
5846

@@ -67,8 +55,8 @@ inline static std::vector<std::weak_ptr<Hook>> floatingBtnHooks;
6755
[](bool value) {
6856
if (auto fb = OptionMenuButton::get()) fb->setVisible(value);
6957

70-
for (auto& hook : floatingBtnHooks) {
71-
if (auto h = hook.lock()) {
58+
for (auto const& hook : s_floatingBtnHooks) {
59+
if (auto const h = hook.lock()) {
7260
log::trace("Toggling floating button hook '{}' {}...", h->getDisplayName(), value ? "ON" : "OFF");
7361
(void)h->toggle(value);
7462
};
@@ -105,7 +93,7 @@ inline static std::vector<std::weak_ptr<Hook>> floatingBtnHooks;
10593

10694
// safe mode
10795
class $modify(HISafeGJGameLevel, GJGameLevel) {
108-
HORRIBLE_HOOK_SAFEMODE("GJGameLevel::savePercentage");
96+
HORRIBLE_HOOK_INTERNAL(s_safeModeHooks);
10997

11098
void savePercentage(int, bool, int, int, bool) {
11199
log::warn("Safe mode is enabled, progress will not be saved!");
@@ -114,7 +102,7 @@ class $modify(HISafeGJGameLevel, GJGameLevel) {
114102

115103
// safe mode
116104
class $modify(HISafePlayLayer, PlayLayer) {
117-
HORRIBLE_HOOK_SAFEMODE("PlayLayer::levelComplete");
105+
HORRIBLE_HOOK_INTERNAL(s_safeModeHooks);
118106

119107
// safe mode prevents level completion
120108
void levelComplete() {
@@ -129,7 +117,7 @@ class $modify(HISafePlayLayer, PlayLayer) {
129117
};
130118

131119
class $modify(HIFloatBtnPauseLayer, PauseLayer) {
132-
HORRIBLE_HOOK_FLOATINGBTN;
120+
HORRIBLE_HOOK_INTERNAL(s_floatingBtnHooks);
133121

134122
void customSetup() {
135123
auto toggle = thisMod->getSettingValue<bool>(setting::FloatingBtn);
@@ -142,7 +130,7 @@ class $modify(HIFloatBtnPauseLayer, PauseLayer) {
142130
};
143131

144132
class $modify(HIFloatBtnPlayLayer, PlayLayer) {
145-
HORRIBLE_HOOK_FLOATINGBTN;
133+
HORRIBLE_HOOK_INTERNAL(s_floatingBtnHooks);
146134

147135
void setupHasCompleted() {
148136
toggleButton();

src/menu/src/OptionMenu.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ bool OptionMenu::init() {
200200
m_impl->searchInput->setAnchorPoint({0, 0.5});
201201
m_impl->searchInput->setPosition({10.f, mainLayerSize.height - 51.25f});
202202

203-
m_impl->searchInput->setCallback([this](std::string_view str) {
204-
m_impl->searchText = str;
203+
m_impl->searchInput->setCallback([this](std::string str) {
204+
m_impl->searchText = std::move(str);
205205
m_impl->filterOptions(
206206
options::getAll(),
207207
m_impl->selectedTier,

src/util/ui/MathQuiz.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ namespace horrible {
1818
Geometry = 3
1919
};
2020

21+
using Callback = Function<void(bool)>;
22+
2123
protected:
2224
MathQuiz();
2325
~MathQuiz();
@@ -35,7 +37,7 @@ namespace horrible {
3537
public:
3638
static MathQuiz* create();
3739

38-
void setCallback(Function<void(bool)> cb);
40+
void setCallback(Callback&& cb);
3941
void setCorrect(bool v);
4042
};
4143

0 commit comments

Comments
 (0)