mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-26 21:00:50 -04:00
cleanup old field remnants without abi break
This commit is contained in:
parent
fdb473ac7c
commit
34e51ff868
2 changed files with 24 additions and 66 deletions
loader
|
@ -53,11 +53,6 @@ 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>;
|
||||
|
@ -69,74 +64,39 @@ namespace geode::modifier {
|
|||
// the constructor that constructs the fields.
|
||||
// we construct the Parent first,
|
||||
static void fieldConstructor(void* offsetField) {
|
||||
if constexpr (HasFields<Parent>) {
|
||||
(void) new (offsetField) typename Parent::Fields();
|
||||
}
|
||||
else {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Parent();
|
||||
|
||||
parent->Intermediate::~Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
offsetField,
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
}
|
||||
(void) new (offsetField) typename Parent::Fields();
|
||||
}
|
||||
|
||||
static void fieldDestructor(void* offsetField) {
|
||||
if constexpr (HasFields<Parent>) {
|
||||
static_cast<typename Parent::Fields*>(offsetField)->~Fields();
|
||||
}
|
||||
else {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
|
||||
auto parent = new (parentContainer.data()) Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
offsetField,
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
|
||||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
}
|
||||
static_cast<typename Parent::Fields*>(offsetField)->~Fields();
|
||||
}
|
||||
|
||||
auto self() {
|
||||
if constexpr (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");
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we can get 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());
|
||||
// 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 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
|
||||
);
|
||||
// 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);
|
||||
}
|
||||
else {
|
||||
static_assert(!HasFields<Parent>, "Parent must have a Fields struct");
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
return reinterpret_cast<typename Parent::Fields*>(offsetField);
|
||||
}
|
||||
|
||||
auto operator->() {
|
||||
|
|
|
@ -17,7 +17,6 @@ struct ProxyCCNode;
|
|||
|
||||
class GeodeNodeMetadata final : public cocos2d::CCObject {
|
||||
private:
|
||||
FieldContainer* m_fieldContainer;
|
||||
std::unordered_map<std::string, FieldContainer*> m_classFieldContainers;
|
||||
std::string m_id = "";
|
||||
Ref<Layout> m_layout = nullptr;
|
||||
|
@ -29,10 +28,9 @@ private:
|
|||
friend class ProxyCCNode;
|
||||
friend class cocos2d::CCNode;
|
||||
|
||||
GeodeNodeMetadata() : m_fieldContainer(new FieldContainer()) {}
|
||||
GeodeNodeMetadata() {}
|
||||
|
||||
virtual ~GeodeNodeMetadata() {
|
||||
delete m_fieldContainer;
|
||||
for (auto& [_, container] : m_classFieldContainers) {
|
||||
delete container;
|
||||
}
|
||||
|
@ -65,7 +63,7 @@ public:
|
|||
}
|
||||
|
||||
FieldContainer* getFieldContainer() {
|
||||
return m_fieldContainer;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FieldContainer* getFieldContainer(char const* forClass) {
|
||||
|
|
Loading…
Add table
Reference in a new issue