mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-20 18:09:59 -04:00
Merge branch 'main' into new-index-but-better
This commit is contained in:
commit
fbdb6265df
4 changed files with 96 additions and 13 deletions
loader
|
@ -51,6 +51,11 @@ namespace geode::modifier {
|
|||
|
||||
GEODE_DLL size_t getFieldIndexForClass(char const* name);
|
||||
|
||||
template <class Parent>
|
||||
concept HasFields = requires {
|
||||
typename Parent::Fields;
|
||||
};
|
||||
|
||||
template <class Parent, class Base>
|
||||
class FieldIntermediate {
|
||||
using Intermediate = Modify<Parent, Base>;
|
||||
|
@ -61,7 +66,7 @@ namespace geode::modifier {
|
|||
public:
|
||||
// the constructor that constructs the fields.
|
||||
// we construct the Parent first,
|
||||
static void fieldConstructor(void* offsetField) {
|
||||
static void fieldConstructor(void* offsetField) requires (!HasFields<Parent>) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Parent();
|
||||
|
@ -75,7 +80,7 @@ namespace geode::modifier {
|
|||
);
|
||||
}
|
||||
|
||||
static void fieldDestructor(void* offsetField) {
|
||||
static void fieldDestructor(void* offsetField) requires (!HasFields<Parent>) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Intermediate();
|
||||
|
@ -89,7 +94,7 @@ namespace geode::modifier {
|
|||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
}
|
||||
|
||||
operator Parent*() {
|
||||
operator Parent*() requires (!HasFields<Parent>) {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
|
@ -119,11 +124,11 @@ namespace geode::modifier {
|
|||
);
|
||||
}
|
||||
|
||||
Parent* self() {
|
||||
Parent* self() requires (!HasFields<Parent>) {
|
||||
return this->operator Parent*();
|
||||
}
|
||||
|
||||
Parent* operator->() {
|
||||
Parent* operator->() requires (!HasFields<Parent>) {
|
||||
// workaround for "static assertion is not an integral constant expression" in CLion
|
||||
// while the solution in https://github.com/microsoft/STL/issues/3311 works, you can't provide
|
||||
// cli args to clang-tidy in clion, so we use this workaround instead
|
||||
|
@ -135,6 +140,57 @@ namespace geode::modifier {
|
|||
return reinterpret_cast<Parent*>(69420);
|
||||
#else
|
||||
return this->operator Parent*();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fieldConstructor(void* offsetField) requires (HasFields<Parent>) {
|
||||
(void) new (offsetField) typename Parent::Fields();
|
||||
}
|
||||
|
||||
static void fieldDestructor(void* offsetField) requires (HasFields<Parent>) {
|
||||
static_cast<typename Parent::Fields*>(offsetField)->~Fields();
|
||||
}
|
||||
|
||||
auto self() requires (HasFields<Parent>) {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
auto node = reinterpret_cast<Parent*>(reinterpret_cast<std::byte*>(this) - sizeof(Base));
|
||||
static_assert(sizeof(Base) == offsetof(Parent, m_fields), "offsetof not correct");
|
||||
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node, typeid(Base).name());
|
||||
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).name());
|
||||
|
||||
// the fields are actually offset from their original
|
||||
// offset, this is done to save on allocation and space
|
||||
auto offsetField = container->getField(index);
|
||||
if (!offsetField) {
|
||||
offsetField = container->setField(
|
||||
index, sizeof(typename Parent::Fields), &FieldIntermediate::fieldDestructor
|
||||
);
|
||||
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
return reinterpret_cast<typename Parent::Fields*>(offsetField);
|
||||
}
|
||||
|
||||
auto operator->() requires (HasFields<Parent>) {
|
||||
// workaround for "static assertion is not an integral constant expression" in CLion
|
||||
// while the solution in https://github.com/microsoft/STL/issues/3311 works, you can't provide
|
||||
// cli args to clang-tidy in clion, so we use this workaround instead
|
||||
// https://youtrack.jetbrains.com/issue/CPP-27446/spurious-offsetof-in-staticassert-error-from-clangd#focus=Comments-27-8172811.0-0
|
||||
// update: that workaround didn't work,
|
||||
// undefining and re-defining offsetof caused another error further down
|
||||
// so we're doing this now
|
||||
#ifdef __CLION_IDE__
|
||||
return reinterpret_cast<typename Parent::Fields*>(69420);
|
||||
#else
|
||||
return this->self();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
using namespace geode::prelude;
|
||||
|
||||
struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
||||
bool m_menuDisabled;
|
||||
CCLabelBMFont* m_smallLabel = nullptr;
|
||||
CCLabelBMFont* m_smallLabel2 = nullptr;
|
||||
int m_geodeLoadStep = 0;
|
||||
int m_totalMods = 0;
|
||||
struct Fields {
|
||||
bool m_menuDisabled = false;
|
||||
CCLabelBMFont* m_smallLabel = nullptr;
|
||||
CCLabelBMFont* m_smallLabel2 = nullptr;
|
||||
int m_geodeLoadStep = 0;
|
||||
int m_totalMods = 0;
|
||||
};
|
||||
|
||||
static void onModify(auto& self) {
|
||||
if (!self.setHookPriority("LoadingLayer::init", geode::node_ids::GEODE_ID_PRIORITY)) {
|
||||
|
|
|
@ -28,9 +28,11 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
GEODE_FORWARD_COMPAT_DISABLE_HOOKS_INNER("MenuLayer stuff disabled")
|
||||
}
|
||||
|
||||
bool m_menuDisabled;
|
||||
CCSprite* m_geodeButton;
|
||||
Task<std::monostate> m_updateCheckTask;
|
||||
struct Fields {
|
||||
bool m_menuDisabled = false;
|
||||
CCSprite* m_geodeButton = nullptr;
|
||||
Task<std::monostate> m_updateCheckTask;
|
||||
};
|
||||
|
||||
bool init() {
|
||||
if (!MenuLayer::init()) return false;
|
||||
|
|
|
@ -114,3 +114,26 @@ struct GJGarageLayerTest : Modify<GJGarageLayerTest, GJGarageLayer> {
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#include <Geode/modify/GJGarageLayer.hpp>
|
||||
|
||||
struct GJGarageLayerTest2 : Modify<GJGarageLayerTest2, GJGarageLayer> {
|
||||
struct Fields {
|
||||
int myOtherValue = 80085;
|
||||
};
|
||||
|
||||
bool init() {
|
||||
if (!GJGarageLayer::init()) return false;
|
||||
|
||||
if (m_fields->myOtherValue == 80085) {
|
||||
auto label = CCLabelBMFont::create("Alternate Fields works!", "bigFont.fnt");
|
||||
label->setPosition(100, 60);
|
||||
label->setScale(.4f);
|
||||
label->setZOrder(99999);
|
||||
this->addChild(label);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue