mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-27 01:45:35 -05:00
Merge branch 'main' of https://github.com/geode-sdk/geode
This commit is contained in:
commit
d83f2825f7
7 changed files with 93 additions and 89 deletions
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <Geode/platform/platform.hpp>
|
#include <Geode/platform/platform.hpp>
|
||||||
|
|
||||||
#include "string-base.hpp"
|
#include "string.hpp"
|
||||||
|
|
||||||
#if defined(GEODE_IS_WINDOWS)
|
#if defined(GEODE_IS_WINDOWS)
|
||||||
#include "msvcstl.hpp"
|
#include "msvcstl.hpp"
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
#include <compare>
|
#include <compare>
|
||||||
|
|
||||||
namespace geode::stl {
|
namespace geode::stl {
|
||||||
class StringImplAdapter;
|
class StringImpl;
|
||||||
|
|
||||||
struct StringImpl;
|
struct StringData;
|
||||||
|
|
||||||
#if defined(GEODE_IS_WINDOWS)
|
#if defined(GEODE_IS_WINDOWS)
|
||||||
struct StringImpl {
|
struct StringData {
|
||||||
union {
|
union {
|
||||||
std::array<char, 16> m_smallStorage;
|
std::array<char, 16> m_smallStorage;
|
||||||
char* m_bigStorage;
|
char* m_bigStorage;
|
||||||
|
@ -22,7 +22,7 @@ namespace geode::stl {
|
||||||
size_t m_capacity;
|
size_t m_capacity;
|
||||||
};
|
};
|
||||||
#elif defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
|
#elif defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
|
||||||
struct StringImpl {
|
struct StringData {
|
||||||
struct Internal {
|
struct Internal {
|
||||||
size_t m_size;
|
size_t m_size;
|
||||||
size_t m_capacity;
|
size_t m_capacity;
|
||||||
|
@ -31,7 +31,7 @@ namespace geode::stl {
|
||||||
Internal* m_data = nullptr;
|
Internal* m_data = nullptr;
|
||||||
};
|
};
|
||||||
#elif defined(GEODE_IS_IOS)
|
#elif defined(GEODE_IS_IOS)
|
||||||
struct StringImpl {
|
struct StringData {
|
||||||
struct Short {
|
struct Short {
|
||||||
uint8_t sizex2;
|
uint8_t sizex2;
|
||||||
std::array<char, 23> shortStorage;
|
std::array<char, 23> shortStorage;
|
||||||
|
@ -48,15 +48,13 @@ namespace geode::stl {
|
||||||
Long m_long;
|
Long m_long;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#else
|
|
||||||
using StringImpl = void;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace gd {
|
namespace gd {
|
||||||
class GEODE_DLL string {
|
class GEODE_DLL string {
|
||||||
geode::stl::StringImpl m_impl;
|
geode::stl::StringData m_data;
|
||||||
friend geode::stl::StringImplAdapter;
|
friend geode::stl::StringImpl;
|
||||||
public:
|
public:
|
||||||
string();
|
string();
|
||||||
string(string const&);
|
string(string const&);
|
|
@ -2,10 +2,10 @@
|
||||||
#include <Geode/c++stl/gdstdlib.hpp>
|
#include <Geode/c++stl/gdstdlib.hpp>
|
||||||
|
|
||||||
namespace geode::stl {
|
namespace geode::stl {
|
||||||
struct StringImplAdapter {
|
struct StringImpl {
|
||||||
StringImpl& impl;
|
StringData& data;
|
||||||
|
|
||||||
// clear but assumes the existing impl is uninit,
|
// clear but assumes the existing data is uninit,
|
||||||
// so basically a default ctor
|
// so basically a default ctor
|
||||||
void setEmpty();
|
void setEmpty();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <Geode/c++stl/gdstdlib.hpp>
|
#include <Geode/c++stl/gdstdlib.hpp>
|
||||||
#include "string-adapter.hpp"
|
#include "string-impl.hpp"
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <compare>
|
#include <compare>
|
||||||
|
@ -9,33 +9,33 @@ Type& intoMutRef(const Type& x) {
|
||||||
return const_cast<Type&>(x);
|
return const_cast<Type&>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
using geode::stl::StringImplAdapter;
|
using geode::stl::StringImpl;
|
||||||
|
|
||||||
#define getAdap(x) StringImplAdapter{intoMutRef(x)}
|
#define implFor(x) StringImpl{intoMutRef(x.m_data)}
|
||||||
#define adap getAdap(m_impl)
|
#define impl implFor((*this))
|
||||||
|
|
||||||
namespace gd {
|
namespace gd {
|
||||||
string::string() {
|
string::string() {
|
||||||
adap.setEmpty();
|
impl.setEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
string::string(string const& str) {
|
string::string(string const& str) {
|
||||||
adap.setStorage(str);
|
impl.setStorage(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// string::string(string&& other) {
|
// string::string(string&& other) {
|
||||||
// // TODO: do this better :-)
|
// // TODO: do this better :-)
|
||||||
// adap.setStorage(other);
|
// impl.setStorage(other);
|
||||||
// getAdap(other.m_impl).free();
|
// implFor(other).free();
|
||||||
// getAdap(other.m_impl).setEmpty();
|
// implFor(other).setEmpty();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
string::string(char const* str) {
|
string::string(char const* str) {
|
||||||
adap.setStorage(str);
|
impl.setStorage(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
string::string(std::string const& str) {
|
string::string(std::string const& str) {
|
||||||
adap.setStorage(str);
|
impl.setStorage(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
string::~string() {
|
string::~string() {
|
||||||
|
@ -44,53 +44,53 @@ namespace gd {
|
||||||
|
|
||||||
string& string::operator=(string const& other) {
|
string& string::operator=(string const& other) {
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
adap.free();
|
impl.free();
|
||||||
adap.setStorage(other);
|
impl.setStorage(other);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
string& string::operator=(string&& other) {
|
string& string::operator=(string&& other) {
|
||||||
// TODO: do this better :-)
|
// TODO: do this better :-)
|
||||||
adap.free();
|
impl.free();
|
||||||
adap.setStorage(other);
|
impl.setStorage(other);
|
||||||
getAdap(other.m_impl).free();
|
implFor(other).free();
|
||||||
getAdap(other.m_impl).setEmpty();
|
implFor(other).setEmpty();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
string& string::operator=(char const* other) {
|
string& string::operator=(char const* other) {
|
||||||
adap.free();
|
impl.free();
|
||||||
adap.setStorage(other);
|
impl.setStorage(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
string& string::operator=(std::string const& other) {
|
string& string::operator=(std::string const& other) {
|
||||||
adap.free();
|
impl.free();
|
||||||
adap.setStorage(other);
|
impl.setStorage(other);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void string::clear() {
|
void string::clear() {
|
||||||
adap.free();
|
impl.free();
|
||||||
adap.setEmpty();
|
impl.setEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
char& string::at(size_t pos) {
|
char& string::at(size_t pos) {
|
||||||
if (pos >= this->size())
|
if (pos >= this->size())
|
||||||
throw std::out_of_range("gd::string::at");
|
throw std::out_of_range("gd::string::at");
|
||||||
return adap.getStorage()[pos];
|
return impl.getStorage()[pos];
|
||||||
}
|
}
|
||||||
char const& string::at(size_t pos) const {
|
char const& string::at(size_t pos) const {
|
||||||
return const_cast<string*>(this)->at(pos);
|
return const_cast<string*>(this)->at(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
char& string::operator[](size_t pos) { return adap.getStorage()[pos]; }
|
char& string::operator[](size_t pos) { return impl.getStorage()[pos]; }
|
||||||
char const& string::operator[](size_t pos) const { return adap.getStorage()[pos]; }
|
char const& string::operator[](size_t pos) const { return impl.getStorage()[pos]; }
|
||||||
|
|
||||||
char* string::data() { return adap.getStorage(); }
|
char* string::data() { return impl.getStorage(); }
|
||||||
char const* string::data() const { return adap.getStorage(); }
|
char const* string::data() const { return impl.getStorage(); }
|
||||||
char const* string::c_str() const { return this->data(); }
|
char const* string::c_str() const { return this->data(); }
|
||||||
|
|
||||||
size_t string::size() const { return adap.getSize(); }
|
size_t string::size() const { return impl.getSize(); }
|
||||||
size_t string::capacity() const { return adap.getCapacity(); }
|
size_t string::capacity() const { return impl.getCapacity(); }
|
||||||
bool string::empty() const { return this->size() == 0; }
|
bool string::empty() const { return this->size() == 0; }
|
||||||
|
|
||||||
bool string::operator==(string const& other) const {
|
bool string::operator==(string const& other) const {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <Geode/c++stl/gdstdlib.hpp>
|
#include <Geode/c++stl/gdstdlib.hpp>
|
||||||
#include "../../c++stl/string-adapter.hpp"
|
#include "../../c++stl/string-impl.hpp"
|
||||||
|
|
||||||
#ifdef GEODE_IS_ANDROID32
|
#ifdef GEODE_IS_ANDROID32
|
||||||
|
|
||||||
|
@ -16,27 +16,29 @@ namespace geode::base {
|
||||||
|
|
||||||
namespace geode::stl {
|
namespace geode::stl {
|
||||||
static inline auto emptyInternalString() {
|
static inline auto emptyInternalString() {
|
||||||
return reinterpret_cast<StringImpl::Internal*>(
|
return reinterpret_cast<StringData::Internal*>(
|
||||||
geode::base::get() + (0xaa1c3c - 0x10000) + sizeof(StringImpl::Internal)
|
geode::base::get() + (0xaa1c3c - 0x10000) + sizeof(StringData::Internal)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringImplAdapter::setEmpty() {
|
void StringImpl::setEmpty() {
|
||||||
impl.m_data = emptyInternalString();
|
data.m_data = emptyInternalString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringImplAdapter::free() {
|
void StringImpl::free() {
|
||||||
if (impl.m_data == nullptr || impl.m_data == emptyInternalString()) return;
|
if (data.m_data == nullptr || data.m_data == emptyInternalString()) return;
|
||||||
// TODO: reimplement this
|
// TODO: reimplement this
|
||||||
reinterpret_cast<void (*)(StringImpl*)>(geode::base::get() + (0x7514c8 - 0x10000) + 1)(&impl);
|
reinterpret_cast<void (*)(StringData*)>(geode::base::get() + (0x7514c8 - 0x10000) + 1)(&data);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* StringImplAdapter::getStorage() {
|
char* StringImpl::getStorage() {
|
||||||
return reinterpret_cast<char*>(impl.m_data);
|
return reinterpret_cast<char*>(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();
|
this->free();
|
||||||
|
|
||||||
if (str.size() == 0) {
|
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 :-)
|
// TODO: should be using (char*, size_t) at the very least, or yknow, just reimplement it :-)
|
||||||
reinterpret_cast<void (*)(StringImpl*, char const*)>(geode::base::get() + (0x753a44 - 0x10000) + 1)(&impl, str.data());
|
reinterpret_cast<void (*)(StringData*, char const*)>(geode::base::get() + (0x753a44 - 0x10000) + 1)(&data, str.data());
|
||||||
return;
|
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_size = str.size();
|
||||||
internal.m_capacity = str.size();
|
internal.m_capacity = str.size();
|
||||||
internal.m_refcount = 0;
|
internal.m_refcount = 0;
|
||||||
|
|
||||||
auto* data = static_cast<char*>(operator new(str.size() + 1 + sizeof(internal)));
|
auto* buffer = static_cast<char*>(operator new(str.size() + 1 + sizeof(internal)));
|
||||||
std::memcpy(data, &internal, sizeof(internal));
|
std::memcpy(buffer, &internal, sizeof(internal));
|
||||||
std::memcpy(data + sizeof(internal), str.data(), str.size());
|
std::memcpy(buffer + sizeof(internal), str.data(), str.size());
|
||||||
data[sizeof(internal) + str.size()] = 0;
|
buffer[sizeof(internal) + str.size()] = 0;
|
||||||
|
|
||||||
impl.m_data = reinterpret_cast<StringImpl::Internal*>(data + sizeof(internal));
|
data.m_data = reinterpret_cast<StringData::Internal*>(buffer + sizeof(internal));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t StringImplAdapter::getSize() {
|
size_t StringImpl::getSize() {
|
||||||
return impl.m_data[-1].m_size;
|
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...
|
// TODO: implement this, remember its copy-on-write...
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t StringImplAdapter::getCapacity() {
|
size_t StringImpl::getCapacity() {
|
||||||
return impl.m_data[-1].m_capacity;
|
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...
|
// TODO: implement this, remember its copy-on-write...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +1,46 @@
|
||||||
#include "../../c++stl/string-adapter.hpp"
|
#include "../../c++stl/string-impl.hpp"
|
||||||
|
|
||||||
#ifdef GEODE_IS_WINDOWS
|
#ifdef GEODE_IS_WINDOWS
|
||||||
|
|
||||||
namespace geode::stl {
|
namespace geode::stl {
|
||||||
void StringImplAdapter::setEmpty() {
|
void StringImpl::setEmpty() {
|
||||||
impl.m_size = 0;
|
data.m_size = 0;
|
||||||
impl.m_capacity = 15;
|
data.m_capacity = 15;
|
||||||
impl.m_smallStorage[0] = 0;
|
data.m_smallStorage[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringImplAdapter::free() {
|
void StringImpl::free() {
|
||||||
if (impl.m_capacity > 15) {
|
if (data.m_capacity > 15) {
|
||||||
delete impl.m_bigStorage;
|
delete data.m_bigStorage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* StringImplAdapter::getStorage() {
|
char* StringImpl::getStorage() {
|
||||||
return impl.m_capacity <= 15 ? impl.m_smallStorage.data() : impl.m_bigStorage;
|
return data.m_capacity <= 15 ? data.m_smallStorage.data() : data.m_bigStorage;
|
||||||
}
|
}
|
||||||
void StringImplAdapter::setStorage(const std::string_view str) {
|
void StringImpl::setStorage(const std::string_view str) {
|
||||||
impl.m_size = impl.m_capacity = str.size();
|
data.m_size = data.m_capacity = str.size();
|
||||||
if (str.size() <= 15) {
|
if (str.size() <= 15) {
|
||||||
impl.m_capacity = 15;
|
data.m_capacity = 15;
|
||||||
} else {
|
} else {
|
||||||
impl.m_bigStorage = static_cast<char*>(operator new(str.size() + 1));
|
data.m_bigStorage = static_cast<char*>(operator new(str.size() + 1));
|
||||||
}
|
}
|
||||||
std::memcpy(getStorage(), str.data(), str.size());
|
std::memcpy(getStorage(), str.data(), str.size());
|
||||||
getStorage()[str.size()] = 0;
|
getStorage()[str.size()] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t StringImplAdapter::getSize() {
|
size_t StringImpl::getSize() {
|
||||||
return impl.m_size;
|
return data.m_size;
|
||||||
}
|
}
|
||||||
void StringImplAdapter::setSize(size_t size) {
|
void StringImpl::setSize(size_t size) {
|
||||||
impl.m_size = size;
|
data.m_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t StringImplAdapter::getCapacity() {
|
size_t StringImpl::getCapacity() {
|
||||||
return impl.m_capacity;
|
return data.m_capacity;
|
||||||
}
|
}
|
||||||
void StringImplAdapter::setCapacity(size_t cap) {
|
void StringImpl::setCapacity(size_t cap) {
|
||||||
impl.m_capacity = cap;
|
data.m_capacity = cap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -504,6 +504,7 @@ void ModListLayer::reloadList(bool keepScroll, std::optional<ModListQuery> const
|
||||||
m_listLabel->setVisible(true);
|
m_listLabel->setVisible(true);
|
||||||
m_listLabel->setString("Updating index...");
|
m_listLabel->setString("Updating index...");
|
||||||
if (!m_loadingCircle) {
|
if (!m_loadingCircle) {
|
||||||
|
// TODO: mat
|
||||||
m_loadingCircle = LoadingCircle::create();
|
m_loadingCircle = LoadingCircle::create();
|
||||||
|
|
||||||
m_loadingCircle->setPosition(.0f, -40.f);
|
m_loadingCircle->setPosition(.0f, -40.f);
|
||||||
|
|
Loading…
Reference in a new issue