mirror of
https://github.com/geode-sdk/geode.git
synced 2025-03-22 02:45:49 -04:00
Merge branch 'main' into new-index-but-better
This commit is contained in:
commit
f44f392b97
3 changed files with 63 additions and 68 deletions
|
@ -1,5 +1,11 @@
|
|||
# Geode Changelog
|
||||
|
||||
## v2.0.0-beta.25
|
||||
* Fix updater sometimes skipping releases (18dd0b7)
|
||||
* Fix resources getting downloaded every time (5f571d9)
|
||||
* Modify fields are now done using an explicit `Fields` struct to avoid forgetting `m_fields` (4505b0d)
|
||||
* Fix memory leak on new field containers (db32732)
|
||||
|
||||
## v2.0.0-beta.24
|
||||
* CMake error when compiling with Android SDK below 23 (ea34e12)
|
||||
* Fix rendering of soft line breaks in MDTextArea (c7f8b5f)
|
||||
|
|
|
@ -95,7 +95,7 @@ struct _ListImpl {
|
|||
template <class _Traits>
|
||||
class _Hash { // hash table -- list with vector of iterators for quick access
|
||||
protected:
|
||||
using _MylistImpl = typename _ListImpl<typename _Traits::value_type, typename _Traits::allocator_type>;
|
||||
using _MylistImpl = _ListImpl<typename _Traits::value_type, typename _Traits::allocator_type>;
|
||||
using _Mylist = typename _MylistImpl::_Mylist;
|
||||
using _Alnode = typename /* _Mylist */ _MylistImpl::_Alnode;
|
||||
using _Alnode_traits = typename /* _Mylist */ _MylistImpl::_Alnode_traits;
|
||||
|
|
|
@ -66,35 +66,46 @@ namespace geode::modifier {
|
|||
public:
|
||||
// the constructor that constructs the fields.
|
||||
// we construct the Parent first,
|
||||
static void fieldConstructor(void* offsetField) requires (!HasFields<Parent>) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
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();
|
||||
auto parent = new (parentContainer.data()) Parent();
|
||||
|
||||
parent->Intermediate::~Intermediate();
|
||||
parent->Intermediate::~Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
offsetField,
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
std::memcpy(
|
||||
offsetField,
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void fieldDestructor(void* offsetField) requires (!HasFields<Parent>) {
|
||||
std::array<std::byte, sizeof(Parent)> parentContainer;
|
||||
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();
|
||||
auto parent = new (parentContainer.data()) Intermediate();
|
||||
|
||||
std::memcpy(
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
offsetField,
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
std::memcpy(
|
||||
std::launder(&parentContainer[sizeof(Intermediate)]),
|
||||
offsetField,
|
||||
sizeof(Parent) - sizeof(Intermediate)
|
||||
);
|
||||
|
||||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
static_cast<Parent*>(parent)->Parent::~Parent();
|
||||
}
|
||||
}
|
||||
|
||||
operator Parent*() requires (!HasFields<Parent>) {
|
||||
[[deprecated("Fields are now done using an explicit `Fields` struct. Please refer to https://docs.geode-sdk.org/tutorials/fields/ for more information.")]]
|
||||
auto deprecatedSelf() {
|
||||
// get the this pointer of the base
|
||||
// field intermediate is the first member of Modify
|
||||
// meaning we canget the base from ourself
|
||||
|
@ -124,62 +135,40 @@ namespace geode::modifier {
|
|||
);
|
||||
}
|
||||
|
||||
Parent* self() requires (!HasFields<Parent>) {
|
||||
return this->operator Parent*();
|
||||
}
|
||||
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");
|
||||
|
||||
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
|
||||
// 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<Parent*>(69420);
|
||||
#else
|
||||
return this->operator Parent*();
|
||||
#endif
|
||||
}
|
||||
// generating the container if it doesn't exist
|
||||
auto container = FieldContainer::from(node, typeid(Base).name());
|
||||
|
||||
static void fieldConstructor(void* offsetField) requires (HasFields<Parent>) {
|
||||
(void) new (offsetField) typename Parent::Fields();
|
||||
}
|
||||
// the index is global across all mods, so the
|
||||
// function is defined in the loader source
|
||||
static size_t index = getFieldIndexForClass(typeid(Base).name());
|
||||
|
||||
static void fieldDestructor(void* offsetField) requires (HasFields<Parent>) {
|
||||
static_cast<typename Parent::Fields*>(offsetField)->~Fields();
|
||||
}
|
||||
// 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
|
||||
);
|
||||
|
||||
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");
|
||||
FieldIntermediate::fieldConstructor(offsetField);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
else {
|
||||
return this->deprecatedSelf();
|
||||
}
|
||||
|
||||
return reinterpret_cast<typename Parent::Fields*>(offsetField);
|
||||
}
|
||||
|
||||
auto operator->() requires (HasFields<Parent>) {
|
||||
auto operator->() {
|
||||
// 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
|
||||
|
|
Loading…
Reference in a new issue