diff --git a/loader/include/Geode/c++stl/gdstdlib.hpp b/loader/include/Geode/c++stl/gdstdlib.hpp index d928bf89..5fcaa2c6 100644 --- a/loader/include/Geode/c++stl/gdstdlib.hpp +++ b/loader/include/Geode/c++stl/gdstdlib.hpp @@ -2,7 +2,7 @@ #include -#include "string-base.hpp" +#include "string.hpp" #if defined(GEODE_IS_WINDOWS) #include "msvcstl.hpp" diff --git a/loader/include/Geode/c++stl/string-base.hpp b/loader/include/Geode/c++stl/string.hpp similarity index 88% rename from loader/include/Geode/c++stl/string-base.hpp rename to loader/include/Geode/c++stl/string.hpp index b4c6def8..81eb524e 100644 --- a/loader/include/Geode/c++stl/string-base.hpp +++ b/loader/include/Geode/c++stl/string.hpp @@ -7,12 +7,12 @@ #include namespace geode::stl { - class StringImplAdapter; + class StringImpl; - struct StringImpl; + struct StringData; #if defined(GEODE_IS_WINDOWS) - struct StringImpl { + struct StringData { union { std::array m_smallStorage; char* m_bigStorage; @@ -22,7 +22,7 @@ namespace geode::stl { size_t m_capacity; }; #elif defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID) - struct StringImpl { + struct StringData { struct Internal { size_t m_size; size_t m_capacity; @@ -31,7 +31,7 @@ namespace geode::stl { Internal* m_data = nullptr; }; #elif defined(GEODE_IS_IOS) - struct StringImpl { + struct StringData { struct Short { uint8_t sizex2; std::array shortStorage; @@ -48,15 +48,13 @@ namespace geode::stl { Long m_long; }; }; -#else - using StringImpl = void; #endif } namespace gd { class GEODE_DLL string { - geode::stl::StringImpl m_impl; - friend geode::stl::StringImplAdapter; + geode::stl::StringData m_data; + friend geode::stl::StringImpl; public: string(); string(string const&); diff --git a/loader/src/c++stl/string-adapter.hpp b/loader/src/c++stl/string-impl.hpp similarity index 77% rename from loader/src/c++stl/string-adapter.hpp rename to loader/src/c++stl/string-impl.hpp index 6664069f..99abf1e2 100644 --- a/loader/src/c++stl/string-adapter.hpp +++ b/loader/src/c++stl/string-impl.hpp @@ -2,10 +2,10 @@ #include namespace geode::stl { - struct StringImplAdapter { - StringImpl& impl; + struct StringImpl { + StringData& data; - // clear but assumes the existing impl is uninit, + // clear but assumes the existing data is uninit, // so basically a default ctor void setEmpty(); diff --git a/loader/src/c++stl/string.cpp b/loader/src/c++stl/string.cpp index e2770c2e..63a5edca 100644 --- a/loader/src/c++stl/string.cpp +++ b/loader/src/c++stl/string.cpp @@ -1,5 +1,5 @@ #include -#include "string-adapter.hpp" +#include "string-impl.hpp" #include #include #include @@ -9,33 +9,33 @@ Type& intoMutRef(const Type& x) { return const_cast(x); } -using geode::stl::StringImplAdapter; +using geode::stl::StringImpl; -#define getAdap(x) StringImplAdapter{intoMutRef(x)} -#define adap getAdap(m_impl) +#define implFor(x) StringImpl{intoMutRef(x.m_data)} +#define impl implFor((*this)) namespace gd { string::string() { - adap.setEmpty(); + impl.setEmpty(); } string::string(string const& str) { - adap.setStorage(str); + impl.setStorage(str); } // string::string(string&& other) { // // TODO: do this better :-) - // adap.setStorage(other); - // getAdap(other.m_impl).free(); - // getAdap(other.m_impl).setEmpty(); + // impl.setStorage(other); + // implFor(other).free(); + // implFor(other).setEmpty(); // } string::string(char const* str) { - adap.setStorage(str); + impl.setStorage(str); } string::string(std::string const& str) { - adap.setStorage(str); + impl.setStorage(str); } string::~string() { @@ -44,53 +44,53 @@ namespace gd { string& string::operator=(string const& other) { if (this != &other) { - adap.free(); - adap.setStorage(other); + impl.free(); + impl.setStorage(other); } return *this; } string& string::operator=(string&& other) { // TODO: do this better :-) - adap.free(); - adap.setStorage(other); - getAdap(other.m_impl).free(); - getAdap(other.m_impl).setEmpty(); + impl.free(); + impl.setStorage(other); + implFor(other).free(); + implFor(other).setEmpty(); return *this; } string& string::operator=(char const* other) { - adap.free(); - adap.setStorage(other); + impl.free(); + impl.setStorage(other); return *this; } string& string::operator=(std::string const& other) { - adap.free(); - adap.setStorage(other); + impl.free(); + impl.setStorage(other); return *this; } void string::clear() { - adap.free(); - adap.setEmpty(); + impl.free(); + impl.setEmpty(); } char& string::at(size_t pos) { if (pos >= this->size()) throw std::out_of_range("gd::string::at"); - return adap.getStorage()[pos]; + return impl.getStorage()[pos]; } char const& string::at(size_t pos) const { return const_cast(this)->at(pos); } - char& string::operator[](size_t pos) { return adap.getStorage()[pos]; } - char const& string::operator[](size_t pos) const { return adap.getStorage()[pos]; } + char& string::operator[](size_t pos) { return impl.getStorage()[pos]; } + char const& string::operator[](size_t pos) const { return impl.getStorage()[pos]; } - char* string::data() { return adap.getStorage(); } - char const* string::data() const { return adap.getStorage(); } + char* string::data() { return impl.getStorage(); } + char const* string::data() const { return impl.getStorage(); } char const* string::c_str() const { return this->data(); } - size_t string::size() const { return adap.getSize(); } - size_t string::capacity() const { return adap.getCapacity(); } + size_t string::size() const { return impl.getSize(); } + size_t string::capacity() const { return impl.getCapacity(); } bool string::empty() const { return this->size() == 0; } bool string::operator==(string const& other) const { diff --git a/loader/src/platform/android/gdstdlib.cpp b/loader/src/platform/android/gdstdlib.cpp index c3b1a374..d41be179 100644 --- a/loader/src/platform/android/gdstdlib.cpp +++ b/loader/src/platform/android/gdstdlib.cpp @@ -1,5 +1,5 @@ #include -#include "../../c++stl/string-adapter.hpp" +#include "../../c++stl/string-impl.hpp" #ifdef GEODE_IS_ANDROID32 @@ -16,27 +16,29 @@ namespace geode::base { namespace geode::stl { static inline auto emptyInternalString() { - return reinterpret_cast( - geode::base::get() + (0xaa1c3c - 0x10000) + sizeof(StringImpl::Internal) + return reinterpret_cast( + geode::base::get() + (0xaa1c3c - 0x10000) + sizeof(StringData::Internal) ); } - void StringImplAdapter::setEmpty() { - impl.m_data = emptyInternalString(); + void StringImpl::setEmpty() { + data.m_data = emptyInternalString(); } - void StringImplAdapter::free() { - if (impl.m_data == nullptr || impl.m_data == emptyInternalString()) return; + void StringImpl::free() { + if (data.m_data == nullptr || data.m_data == emptyInternalString()) return; // TODO: reimplement this - reinterpret_cast(geode::base::get() + (0x7514c8 - 0x10000) + 1)(&impl); + reinterpret_cast(geode::base::get() + (0x7514c8 - 0x10000) + 1)(&data); } - char* StringImplAdapter::getStorage() { - return reinterpret_cast(impl.m_data); + char* StringImpl::getStorage() { + return reinterpret_cast(data.m_data); } - void StringImplAdapter::setStorage(const std::string_view str) { + // TODO: add a copyFrom(string const&) to take advantage + // of gnustl refcounted strings + void StringImpl::setStorage(const std::string_view str) { this->free(); if (str.size() == 0) { @@ -45,33 +47,36 @@ namespace geode::stl { } // TODO: should be using (char*, size_t) at the very least, or yknow, just reimplement it :-) - reinterpret_cast(geode::base::get() + (0x753a44 - 0x10000) + 1)(&impl, str.data()); + reinterpret_cast(geode::base::get() + (0x753a44 - 0x10000) + 1)(&data, str.data()); return; - StringImpl::Internal internal; + // TODO: this crashes because we need to use gd's operator new... +#if 0 + StringData::Internal internal; internal.m_size = str.size(); internal.m_capacity = str.size(); internal.m_refcount = 0; - auto* data = static_cast(operator new(str.size() + 1 + sizeof(internal))); - std::memcpy(data, &internal, sizeof(internal)); - std::memcpy(data + sizeof(internal), str.data(), str.size()); - data[sizeof(internal) + str.size()] = 0; + auto* buffer = static_cast(operator new(str.size() + 1 + sizeof(internal))); + std::memcpy(buffer, &internal, sizeof(internal)); + std::memcpy(buffer + sizeof(internal), str.data(), str.size()); + buffer[sizeof(internal) + str.size()] = 0; - impl.m_data = reinterpret_cast(data + sizeof(internal)); + data.m_data = reinterpret_cast(buffer + sizeof(internal)); +#endif } - size_t StringImplAdapter::getSize() { - return impl.m_data[-1].m_size; + size_t StringImpl::getSize() { + return data.m_data[-1].m_size; } - void StringImplAdapter::setSize(size_t size) { + void StringImpl::setSize(size_t size) { // TODO: implement this, remember its copy-on-write... } - size_t StringImplAdapter::getCapacity() { - return impl.m_data[-1].m_capacity; + size_t StringImpl::getCapacity() { + return data.m_data[-1].m_capacity; } - void StringImplAdapter::setCapacity(size_t cap) { + void StringImpl::setCapacity(size_t cap) { // TODO: implement this, remember its copy-on-write... } } diff --git a/loader/src/platform/windows/gdstdlib.cpp b/loader/src/platform/windows/gdstdlib.cpp index f1b2b951..6a637488 100644 --- a/loader/src/platform/windows/gdstdlib.cpp +++ b/loader/src/platform/windows/gdstdlib.cpp @@ -1,46 +1,46 @@ -#include "../../c++stl/string-adapter.hpp" +#include "../../c++stl/string-impl.hpp" #ifdef GEODE_IS_WINDOWS namespace geode::stl { - void StringImplAdapter::setEmpty() { - impl.m_size = 0; - impl.m_capacity = 15; - impl.m_smallStorage[0] = 0; + void StringImpl::setEmpty() { + data.m_size = 0; + data.m_capacity = 15; + data.m_smallStorage[0] = 0; } - void StringImplAdapter::free() { - if (impl.m_capacity > 15) { - delete impl.m_bigStorage; + void StringImpl::free() { + if (data.m_capacity > 15) { + delete data.m_bigStorage; } } - char* StringImplAdapter::getStorage() { - return impl.m_capacity <= 15 ? impl.m_smallStorage.data() : impl.m_bigStorage; + char* StringImpl::getStorage() { + return data.m_capacity <= 15 ? data.m_smallStorage.data() : data.m_bigStorage; } - void StringImplAdapter::setStorage(const std::string_view str) { - impl.m_size = impl.m_capacity = str.size(); + void StringImpl::setStorage(const std::string_view str) { + data.m_size = data.m_capacity = str.size(); if (str.size() <= 15) { - impl.m_capacity = 15; + data.m_capacity = 15; } else { - impl.m_bigStorage = static_cast(operator new(str.size() + 1)); + data.m_bigStorage = static_cast(operator new(str.size() + 1)); } std::memcpy(getStorage(), str.data(), str.size()); getStorage()[str.size()] = 0; } - size_t StringImplAdapter::getSize() { - return impl.m_size; + size_t StringImpl::getSize() { + return data.m_size; } - void StringImplAdapter::setSize(size_t size) { - impl.m_size = size; + void StringImpl::setSize(size_t size) { + data.m_size = size; } - size_t StringImplAdapter::getCapacity() { - return impl.m_capacity; + size_t StringImpl::getCapacity() { + return data.m_capacity; } - void StringImplAdapter::setCapacity(size_t cap) { - impl.m_capacity = cap; + void StringImpl::setCapacity(size_t cap) { + data.m_capacity = cap; } } diff --git a/loader/src/ui/internal/list/ModListLayer.cpp b/loader/src/ui/internal/list/ModListLayer.cpp index cadd9188..482b99a1 100644 --- a/loader/src/ui/internal/list/ModListLayer.cpp +++ b/loader/src/ui/internal/list/ModListLayer.cpp @@ -504,6 +504,7 @@ void ModListLayer::reloadList(bool keepScroll, std::optional const m_listLabel->setVisible(true); m_listLabel->setString("Updating index..."); if (!m_loadingCircle) { + // TODO: mat m_loadingCircle = LoadingCircle::create(); m_loadingCircle->setPosition(.0f, -40.f);