mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 02:54:58 -05:00
added clang-format
This commit is contained in:
parent
a1c9063767
commit
94d45ccf21
10 changed files with 963 additions and 703 deletions
140
.clang-format
Normal file
140
.clang-format
Normal file
|
@ -0,0 +1,140 @@
|
|||
---
|
||||
Language: Cpp
|
||||
IndentWidth: 4
|
||||
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: DontAlign
|
||||
AlignTrailingComments: false
|
||||
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortLambdasOnASingleLine: Empty
|
||||
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AlwaysBreakAfterReturnType: None
|
||||
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: false
|
||||
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 100
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
|
||||
DeriveLineEnding: false
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
|
||||
PointerAlignment: Left
|
||||
ReferenceAlignment: Pointer
|
||||
|
||||
EmptyLineBeforeAccessModifier: Always
|
||||
FixNamespaceComments: false
|
||||
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^".*"'
|
||||
Priority: 1
|
||||
|
||||
- Regex: '^<.*>'
|
||||
Priority: 2
|
||||
|
||||
IndentAccessModifiers: false
|
||||
AccessModifierOffset: -4
|
||||
IndentCaseBlocks: false
|
||||
IndentCaseLabels: false
|
||||
IndentExternBlock: Indent
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentWrappedFunctionNames: true
|
||||
# InsertBraces: true
|
||||
InsertTrailingCommas: None
|
||||
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
LambdaBodyIndentation: Signature
|
||||
NamespaceIndentation: All
|
||||
|
||||
PPIndentWidth: -1
|
||||
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyIndentedWhitespace: 0
|
||||
|
||||
QualifierAlignment: Right
|
||||
|
||||
ReflowComments: true
|
||||
SeparateDefinitionBlocks: Always
|
||||
|
||||
SortIncludes: CaseSensitive
|
||||
SortUsingDeclarations: true
|
||||
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceBeforeSquareBrackets: false
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++20
|
|
@ -952,6 +952,7 @@ class cocos2d::extension::CCScale9Sprite {
|
|||
CCScale9Sprite() = mac 0x211330;
|
||||
static cocos2d::extension::CCScale9Sprite* create(char const*) = mac 0x2130d0;
|
||||
static cocos2d::extension::CCScale9Sprite* create(char const*, cocos2d::CCRect) = mac 0x212ef0;
|
||||
static cocos2d::extension::CCScale9Sprite* create(char const*, cocos2d::CCRect, cocos2d::CCRect) = mac 0x212dd0;
|
||||
static cocos2d::extension::CCScale9Sprite* createWithSpriteFrameName(char const*, cocos2d::CCRect) = mac 0x213380;
|
||||
static cocos2d::extension::CCScale9Sprite* createWithSpriteFrameName(char const*) = mac 0x213460;
|
||||
virtual ~CCScale9Sprite() = mac 0x211590;
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
// geode additions to make stl containers easier
|
||||
class GDString {
|
||||
void winDtor() = win 0xf6e0;
|
||||
char const* winCStr() = win 0xf710;
|
||||
GDString& winAssign(GDString const&, size_t, size_t) = win 0xf720;
|
||||
GDString& winAssign(char const*) = win 0xf680;
|
||||
GDString& winAssign(char const*, size_t) = win 0xf840;
|
||||
|
||||
static uintptr_t macEmptyContainer() {
|
||||
return geode::base::get() + 0x6030d0;
|
||||
}
|
||||
void macCtor(char const*) = mac 0x489fc0;
|
||||
void macCtor(GDString const&) = mac 0x489fcc;
|
||||
GDString& macAssign(char const*) = mac 0x489f96;
|
||||
GDString& macAssign(GDString const&) = mac 0x489f9c;
|
||||
void macDestroy() = mac 0x489f78;
|
||||
}
|
||||
|
||||
|
||||
class AchievementBar : cocos2d::CCNodeRGBA {
|
||||
static AchievementBar* create(const char* title, const char* desc, const char* icon, bool quest) = mac 0x379f80, win 0x3b120, ios 0x1a4784;
|
||||
|
||||
|
@ -67,7 +86,9 @@ class AppDelegate : cocos2d::CCApplication {
|
|||
virtual void applicationWillResignActive() = mac 0x3aab50, win 0x3cf20;
|
||||
virtual void trySaveGame() = mac 0x3aaf10, win 0x3d5e0, ios 0x1a28f0;
|
||||
virtual void willSwitchToScene(cocos2d::CCScene*) = mac 0x3aaf40, win 0x3d690;
|
||||
static AppDelegate* get() = mac 0x3aab10;
|
||||
static AppDelegate* get() {
|
||||
return static_cast<AppDelegate*>(cocos2d::CCApplication::sharedApplication());
|
||||
}
|
||||
bool musicTest() = win 0x3d580;
|
||||
void pauseGame() = mac 0x3aab60, win 0x3d3e0;
|
||||
void resumeSound() = win 0x3d4d0;
|
||||
|
@ -814,7 +835,7 @@ class CreatorLayer : cocos2d::CCLayer {
|
|||
void onBack(cocos2d::CCObject*) = win 0x4fae0;
|
||||
void onChallenge(cocos2d::CCObject*) = win 0x4f1b0;
|
||||
void onLeaderboards(cocos2d::CCObject*) = win 0x4ed20;
|
||||
void onMyLevels(cocos2d::CCObject*) = mac 0x142b70;
|
||||
void onMyLevels(cocos2d::CCObject*) = mac 0x142b70, win 0x4eaa0;
|
||||
void onSavedLevels(cocos2d::CCObject*) = mac 0x142860;
|
||||
virtual void sceneWillResume() = win 0x4fb50;
|
||||
virtual bool init() = mac 0x141c10, win 0x4de40;
|
||||
|
@ -910,6 +931,7 @@ class DailyLevelPage : FLAlertLayer {
|
|||
static DailyLevelPage* create(bool weekly) = win 0x6a860;
|
||||
bool init(bool weekly) = win 0x6a900;
|
||||
void updateTimers(float) = win 0x6bef0;
|
||||
virtual void show() = mac 0x10a4b0, win 0x3f360;
|
||||
|
||||
PAD = win 0x21;
|
||||
bool m_weekly;
|
||||
|
@ -1021,7 +1043,7 @@ class EditButtonBar : cocos2d::CCNode {
|
|||
}
|
||||
void addButton(CCMenuItemSpriteExtra* btn, bool reload) {
|
||||
if (this->m_buttonArray)
|
||||
this->m_buttonArray->addObject(static_cast<cocos2d::CCObject*>(btn));
|
||||
this->m_buttonArray->addObject(btn);
|
||||
if (reload)
|
||||
this->reloadItemsInNormalSize();
|
||||
}
|
||||
|
@ -1040,7 +1062,7 @@ class EditLevelLayer : cocos2d::CCLayer, FLAlertLayerProtocol, TextInputDelegate
|
|||
static void scene(GJGameLevel* level) {
|
||||
auto scene = cocos2d::CCScene::create();
|
||||
|
||||
scene->addChild(static_cast<cocos2d::CCNode*>(EditLevelLayer::create(level)));
|
||||
scene->addChild(EditLevelLayer::create(level));
|
||||
|
||||
cocos2d::CCDirector::sharedDirector()->replaceScene(
|
||||
cocos2d::CCTransitionFade::create(.5f, scene)
|
||||
|
@ -4826,6 +4848,7 @@ class SelectArtLayer {
|
|||
}
|
||||
|
||||
class SetGroupIDLayer : FLAlertLayer, TextInputDelegate {
|
||||
bool init(GameObject* object, cocos2d::CCArray* objects) = mac 0x1947c0, win 0x22b670;
|
||||
void onNextGroupID1(cocos2d::CCObject*) = mac 0x1967a0, win 0x22d790;
|
||||
void textChanged(CCTextInputNode*) = mac 0x197af0, win 0x22d610;
|
||||
void updateGroupIDLabel() = mac 0x197260, win 0x22e450;
|
||||
|
|
|
@ -1,513 +1,2 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <variant> // for std::monostate
|
||||
#include <algorithm>
|
||||
#include <Geode/platform/platform.hpp>
|
||||
|
||||
//#include "../utils/platform.hpp"
|
||||
|
||||
namespace geode::base {
|
||||
uintptr_t get();
|
||||
}
|
||||
|
||||
#if defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
|
||||
namespace gd {
|
||||
struct _internal_string {
|
||||
size_t m_len;
|
||||
size_t m_capacity;
|
||||
int m_refcount;
|
||||
};
|
||||
|
||||
class GEODE_DLL string {
|
||||
public:
|
||||
string();
|
||||
string(char const* ok);
|
||||
string(std::string ok) : string(ok.c_str()) {}
|
||||
operator std::string() const {
|
||||
return std::string((char*)m_data, m_data[-1].m_len);
|
||||
}
|
||||
bool operator==(string const& other) const;
|
||||
string(string const& ok);
|
||||
string& operator=(char const* ok);
|
||||
string& operator=(string const& ok);
|
||||
__attribute__((noinline)) ~string();
|
||||
char const* c_str() const { return (char const*)m_data; }
|
||||
size_t size() const { return m_data[-1].m_len; }
|
||||
protected:
|
||||
_internal_string* m_data;
|
||||
};
|
||||
|
||||
struct _rb_tree_base {
|
||||
bool m_isblack;
|
||||
_rb_tree_base* m_parent;
|
||||
_rb_tree_base* m_left;
|
||||
_rb_tree_base* m_right;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _rb_tree_node : public _rb_tree_base {
|
||||
T m_value;
|
||||
};
|
||||
|
||||
static void _rb_tree_rotate_left(_rb_tree_base* const x, _rb_tree_base*& root) {
|
||||
_rb_tree_base* const y = x->m_right;
|
||||
|
||||
x->m_right = y->m_left;
|
||||
if (y->m_left !=0)
|
||||
y->m_left->m_parent = x;
|
||||
y->m_parent = x->m_parent;
|
||||
|
||||
if (x == root)
|
||||
root = y;
|
||||
else if (x == x->m_parent->m_left)
|
||||
x->m_parent->m_left = y;
|
||||
else
|
||||
x->m_parent->m_right = y;
|
||||
y->m_left = x;
|
||||
x->m_parent = y;
|
||||
}
|
||||
|
||||
static void _rb_tree_rotate_right(_rb_tree_base* const x, _rb_tree_base*& root) {
|
||||
_rb_tree_base* const y = x->m_left;
|
||||
|
||||
x->m_left = y->m_right;
|
||||
if (y->m_right != 0)
|
||||
y->m_right->m_parent = x;
|
||||
y->m_parent = x->m_parent;
|
||||
|
||||
if (x == root)
|
||||
root = y;
|
||||
else if (x == x->m_parent->m_right)
|
||||
x->m_parent->m_right = y;
|
||||
else
|
||||
x->m_parent->m_left = y;
|
||||
y->m_right = x;
|
||||
x->m_parent = y;
|
||||
}
|
||||
|
||||
static void _rb_insert_rebalance(const bool insert_left, _rb_tree_base* x, _rb_tree_base* p, _rb_tree_base& header) {
|
||||
_rb_tree_base *& root = header.m_parent;
|
||||
|
||||
x->m_parent = p;
|
||||
x->m_left = 0;
|
||||
x->m_right = 0;
|
||||
x->m_isblack = false;
|
||||
|
||||
if (insert_left) {
|
||||
p->m_left = x;
|
||||
|
||||
if (p == &header) {
|
||||
header.m_parent = x;
|
||||
header.m_right = x;
|
||||
} else if (p == header.m_left){
|
||||
header.m_left = x;
|
||||
}
|
||||
} else {
|
||||
p->m_right = x;
|
||||
|
||||
if (p == header.m_right) {
|
||||
header.m_right = x;
|
||||
}
|
||||
}
|
||||
|
||||
while (x != root && x->m_parent->m_isblack == false) {
|
||||
_rb_tree_base* const xpp = x->m_parent->m_parent;
|
||||
|
||||
if (x->m_parent == xpp->m_left) {
|
||||
_rb_tree_base* const y = xpp->m_right;
|
||||
if (y && y->m_isblack == false) {
|
||||
x->m_parent->m_isblack = true;
|
||||
y->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
x = xpp;
|
||||
} else {
|
||||
if (x == x->m_parent->m_right) {
|
||||
x = x->m_parent;
|
||||
_rb_tree_rotate_left(x, root);
|
||||
}
|
||||
x->m_parent->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
_rb_tree_rotate_right(xpp, root);
|
||||
}
|
||||
} else {
|
||||
_rb_tree_base* const y = xpp->m_left;
|
||||
if (y && y->m_isblack == false) {
|
||||
x->m_parent->m_isblack = true;
|
||||
y->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
x = xpp;
|
||||
} else {
|
||||
if (x == x->m_parent->m_left) {
|
||||
x = x->m_parent;
|
||||
_rb_tree_rotate_right(x, root);
|
||||
}
|
||||
x->m_parent->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
_rb_tree_rotate_left(xpp, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
root->m_isblack = true;
|
||||
}
|
||||
|
||||
static _rb_tree_base* _rb_increment(_rb_tree_base* __x) throw () {
|
||||
if (__x->m_right != 0) {
|
||||
__x = __x->m_right;
|
||||
while (__x->m_left != 0)
|
||||
__x = __x->m_left;
|
||||
} else {
|
||||
_rb_tree_base* __y = __x->m_parent;
|
||||
while (__x == __y->m_right) {
|
||||
__x = __y;
|
||||
__y = __y->m_parent;
|
||||
}
|
||||
if (__x->m_right != __y)
|
||||
__x = __y;
|
||||
}
|
||||
return __x;
|
||||
}
|
||||
|
||||
static _rb_tree_base* _rb_decrement(_rb_tree_base* __x) throw () {
|
||||
if (!__x->m_isblack && __x->m_parent->m_parent == __x)
|
||||
__x = __x->m_right;
|
||||
else if (__x->m_left != 0) {
|
||||
_rb_tree_base* __y = __x->m_left;
|
||||
while (__y->m_right != 0)
|
||||
__y = __y->m_right;
|
||||
__x = __y;
|
||||
} else {
|
||||
_rb_tree_base* __y = __x->m_parent;
|
||||
while (__x == __y->m_left) {
|
||||
__x = __y;
|
||||
__y = __y->m_parent;
|
||||
}
|
||||
__x = __y;
|
||||
}
|
||||
return __x;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
class GEODE_DLL map {
|
||||
protected:
|
||||
std::less<K> compare;
|
||||
_rb_tree_base m_header;
|
||||
size_t m_nodecount;
|
||||
public:
|
||||
typedef _rb_tree_node<std::pair<K,V> >* _tree_node;
|
||||
|
||||
std::map<K, V> std() {
|
||||
return (std::map<K, V>)(*this);
|
||||
}
|
||||
|
||||
operator std::map<K, V>() {
|
||||
auto iter_node = static_cast<_tree_node>(m_header.m_left);
|
||||
auto end_node = static_cast<_tree_node>(&m_header);
|
||||
std::map<K, V> out;
|
||||
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
|
||||
out[iter_node->m_value.first] = iter_node->m_value.second;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
operator std::map<K, V>() const {
|
||||
auto iter_node = static_cast<_tree_node>(m_header.m_left);
|
||||
auto end_node = (_tree_node)(&m_header);
|
||||
std::map<K, V> out;
|
||||
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
|
||||
out[iter_node->m_value.first] = iter_node->m_value.second;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
void insert(_tree_node x, _tree_node p, const std::pair<K, V>& val) {
|
||||
bool insert_left = (x != 0 || p == static_cast<_tree_node>(&m_header) || val.first < p->m_value.first);
|
||||
|
||||
_tree_node z = new _rb_tree_node<std::pair<K,V> >();
|
||||
z->m_value = val;
|
||||
|
||||
_rb_insert_rebalance(insert_left, z, p, m_header);
|
||||
++m_nodecount;
|
||||
}
|
||||
void insert_pair(const std::pair<K, V>& val) {
|
||||
_tree_node x = static_cast<_tree_node>(m_header.m_parent);
|
||||
_tree_node y = static_cast<_tree_node>(&m_header);
|
||||
bool comp = true;
|
||||
while (x != 0) {
|
||||
y = x;
|
||||
comp = val.first < x->m_value.first;
|
||||
x = comp ? static_cast<_tree_node>(x->m_left) : static_cast<_tree_node>(x->m_right);
|
||||
}
|
||||
auto iter = y;
|
||||
|
||||
if (comp) {
|
||||
if (iter == static_cast<_tree_node>(m_header.m_left)) {
|
||||
insert(x, y, val);
|
||||
} else {
|
||||
iter = static_cast<_tree_node>(_rb_decrement(iter));
|
||||
}
|
||||
}
|
||||
if (iter->m_value.first < val.first) {
|
||||
insert(x, y, val);
|
||||
}
|
||||
}
|
||||
|
||||
map(std::map<K, V> input) {
|
||||
m_header.m_isblack = false;
|
||||
m_header.m_parent = 0;
|
||||
m_header.m_left = &m_header;
|
||||
m_header.m_right = &m_header;
|
||||
|
||||
for (auto i : input) {
|
||||
insert_pair(i);
|
||||
}
|
||||
}
|
||||
void erase(_tree_node x) {
|
||||
while (x != 0) {
|
||||
erase(static_cast<_tree_node>(x->m_right));
|
||||
auto y = static_cast<_tree_node>(x->m_left);
|
||||
delete y;
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
map(map const& lol) : map(std::map<K, V>(lol)) {}
|
||||
map() : map(std::map<K, V>()) {}
|
||||
~map() {
|
||||
erase(static_cast<_tree_node>(m_header.m_parent));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class GEODE_DLL vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
operator std::vector<T>() const {
|
||||
std::vector<T> out;
|
||||
|
||||
for (auto i = m_start; i != m_finish; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
vector(std::vector<T> input) {
|
||||
auto tmp = new T[input.size()];
|
||||
|
||||
m_start = tmp;
|
||||
m_finish = m_start + input.size();
|
||||
m_capacity_end = m_start + input.size();
|
||||
for (auto i : input) {
|
||||
*tmp = i;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
vector(std::initializer_list<T> const& input) {
|
||||
auto tmp = new T[input.size()];
|
||||
m_start = tmp;
|
||||
m_finish = m_start + input.size();
|
||||
m_capacity_end = m_start + input.size();
|
||||
std::copy(input.begin(), input.end(), tmp);
|
||||
}
|
||||
|
||||
T& front() {
|
||||
return *m_start;
|
||||
}
|
||||
|
||||
auto begin() { return m_start; }
|
||||
auto end() { return m_finish; }
|
||||
auto begin() const { return static_cast<const T*>(m_start); }
|
||||
auto end() const { return static_cast<const T*>(m_finish); }
|
||||
|
||||
vector(vector const& lol) : vector(std::vector<T>(lol)) {}
|
||||
|
||||
vector() : vector(std::vector<T>()) {}
|
||||
|
||||
~vector() {
|
||||
delete[] m_start;
|
||||
}
|
||||
protected:
|
||||
T* m_start;
|
||||
T* m_finish;
|
||||
T* m_capacity_end;
|
||||
};
|
||||
|
||||
struct _bit_reference {
|
||||
uintptr_t* m_bitptr;
|
||||
uintptr_t m_mask;
|
||||
|
||||
_bit_reference(uintptr_t* x, uintptr_t y) : m_bitptr(x), m_mask(y) {}
|
||||
_bit_reference() : m_bitptr(0), m_mask(0) {}
|
||||
|
||||
operator bool() const {
|
||||
return !!(*m_bitptr & m_mask);
|
||||
}
|
||||
|
||||
_bit_reference& operator=(bool x) {
|
||||
if (x)
|
||||
*m_bitptr |= m_mask;
|
||||
else
|
||||
*m_bitptr &= ~m_mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_bit_reference& operator=(const _bit_reference& x) {
|
||||
return *this = bool(x);
|
||||
}
|
||||
|
||||
bool operator==(const _bit_reference& x) const {
|
||||
return bool(*this) == bool(x);
|
||||
}
|
||||
|
||||
bool operator<(const _bit_reference& x) const {
|
||||
return !bool(*this) && bool(x);
|
||||
}
|
||||
|
||||
void flip() {
|
||||
*m_bitptr ^= m_mask;
|
||||
}
|
||||
};
|
||||
|
||||
struct _bit_iterator {
|
||||
uintptr_t* m_bitptr;
|
||||
unsigned int m_offset;
|
||||
_bit_iterator(uintptr_t* x) : m_bitptr(x), m_offset(0) {}
|
||||
_bit_iterator(uintptr_t* x, unsigned o) : m_bitptr(x), m_offset(o) {}
|
||||
_bit_reference operator*() const {
|
||||
return _bit_reference(m_bitptr, 1UL << m_offset);
|
||||
}
|
||||
_bit_iterator& operator++() {
|
||||
if (m_offset++ == sizeof(uintptr_t)-1) {
|
||||
m_offset = 0;
|
||||
m_bitptr++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator!=(const _bit_iterator& b) {
|
||||
return !(m_bitptr == b.m_bitptr && m_offset == b.m_offset);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class vector<bool> {
|
||||
protected:
|
||||
_bit_iterator m_start;
|
||||
_bit_iterator m_end;
|
||||
uintptr_t* m_capacity_end;
|
||||
public:
|
||||
vector(std::vector<bool> input) : m_start(0), m_end(0) {
|
||||
auto realsize = input.size()/int(sizeof(uintptr_t));
|
||||
auto tmp = new uintptr_t[realsize];
|
||||
|
||||
m_start = _bit_iterator(tmp);
|
||||
m_end = _bit_iterator(tmp + realsize, input.size()%sizeof(uintptr_t));
|
||||
m_capacity_end = tmp + realsize;
|
||||
|
||||
auto itmp = m_start;
|
||||
for (auto i : input) {
|
||||
*itmp = i;
|
||||
++itmp;
|
||||
}
|
||||
}
|
||||
|
||||
operator std::vector<bool>() {
|
||||
std::vector<bool> out;
|
||||
for (auto i = m_start; i != m_end; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
operator std::vector<bool>() const {
|
||||
std::vector<bool> out;
|
||||
for (auto i = m_start; i != m_end; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
vector(vector<bool> const& lol) : vector(std::vector<bool>(lol)) {}
|
||||
|
||||
vector() : vector(std::vector<bool>()) {}
|
||||
|
||||
~vector() {
|
||||
delete[] m_start.m_bitptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#elif defined(GEODE_IS_IOS)
|
||||
namespace gd {
|
||||
class GEODE_DLL string {
|
||||
public:
|
||||
string() {}
|
||||
string(char const* ok) : m_internal(ok) {}
|
||||
string(std::string ok) : m_internal(ok) {}
|
||||
operator std::string() {
|
||||
return m_internal;
|
||||
}
|
||||
operator std::string() const {
|
||||
return m_internal;
|
||||
}
|
||||
string(string const& ok) : m_internal(ok) {}
|
||||
string& operator=(char const* ok) {m_internal = ok; return *this;}
|
||||
string& operator=(string const& ok) {m_internal = ok; return *this;}
|
||||
~string() {}
|
||||
char const* c_str() const {return m_internal.c_str(); }
|
||||
protected:
|
||||
std::string m_internal;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class GEODE_DLL vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
operator std::vector<T>() {
|
||||
return m_internal;
|
||||
}
|
||||
operator std::vector<T>() const {
|
||||
return m_internal;
|
||||
}
|
||||
|
||||
vector(std::vector<T> input) : m_internal(input) {}
|
||||
|
||||
T& front() {
|
||||
return m_internal.front();
|
||||
}
|
||||
|
||||
vector(vector const& lol) : m_internal(lol) {}
|
||||
|
||||
vector() : m_internal() {}
|
||||
|
||||
~vector() {}
|
||||
protected:
|
||||
std::vector<T> m_internal;
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class GEODE_DLL map {
|
||||
protected:
|
||||
std::map<K, V> m_internal;
|
||||
public:
|
||||
operator std::map<K, V>() {
|
||||
return m_internal;
|
||||
}
|
||||
operator std::map<K, V>() const {
|
||||
return m_internal;
|
||||
}
|
||||
map(std::map<K, V> input) : m_internal(input) {}
|
||||
|
||||
map(map const& lol) : m_internal(lol) {}
|
||||
map() {}
|
||||
~map() {}
|
||||
};
|
||||
}
|
||||
#else
|
||||
namespace gd = std;
|
||||
#endif
|
||||
#include "gnustl.hpp"
|
||||
// #include "msvcstl.hpp"
|
512
loader/include/Geode/c++stl/gnustl.hpp
Normal file
512
loader/include/Geode/c++stl/gnustl.hpp
Normal file
|
@ -0,0 +1,512 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <Geode/platform/platform.hpp>
|
||||
// #include <Geode/binding/GDString.hpp>
|
||||
|
||||
//#include "../utils/platform.hpp"
|
||||
|
||||
namespace geode::base {
|
||||
uintptr_t get();
|
||||
}
|
||||
|
||||
#if defined(GEODE_IS_MACOS) || defined(GEODE_IS_ANDROID)
|
||||
namespace gd {
|
||||
struct _internal_string {
|
||||
size_t m_len;
|
||||
size_t m_capacity;
|
||||
int m_refcount;
|
||||
};
|
||||
|
||||
class GEODE_DLL string {
|
||||
public:
|
||||
string();
|
||||
string(char const* ok);
|
||||
string(std::string ok) : string(ok.c_str()) {}
|
||||
operator std::string() const {
|
||||
return std::string((char*)m_data, m_data[-1].m_len);
|
||||
}
|
||||
bool operator==(string const& other) const;
|
||||
string(string const& ok);
|
||||
string& operator=(char const* ok);
|
||||
string& operator=(string const& ok);
|
||||
__attribute__((noinline)) ~string();
|
||||
char const* c_str() const { return (char const*)m_data; }
|
||||
size_t size() const { return m_data[-1].m_len; }
|
||||
protected:
|
||||
_internal_string* m_data;
|
||||
};
|
||||
|
||||
struct _rb_tree_base {
|
||||
bool m_isblack;
|
||||
_rb_tree_base* m_parent;
|
||||
_rb_tree_base* m_left;
|
||||
_rb_tree_base* m_right;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct _rb_tree_node : public _rb_tree_base {
|
||||
T m_value;
|
||||
};
|
||||
|
||||
static void _rb_tree_rotate_left(_rb_tree_base* const x, _rb_tree_base*& root) {
|
||||
_rb_tree_base* const y = x->m_right;
|
||||
|
||||
x->m_right = y->m_left;
|
||||
if (y->m_left !=0)
|
||||
y->m_left->m_parent = x;
|
||||
y->m_parent = x->m_parent;
|
||||
|
||||
if (x == root)
|
||||
root = y;
|
||||
else if (x == x->m_parent->m_left)
|
||||
x->m_parent->m_left = y;
|
||||
else
|
||||
x->m_parent->m_right = y;
|
||||
y->m_left = x;
|
||||
x->m_parent = y;
|
||||
}
|
||||
|
||||
static void _rb_tree_rotate_right(_rb_tree_base* const x, _rb_tree_base*& root) {
|
||||
_rb_tree_base* const y = x->m_left;
|
||||
|
||||
x->m_left = y->m_right;
|
||||
if (y->m_right != 0)
|
||||
y->m_right->m_parent = x;
|
||||
y->m_parent = x->m_parent;
|
||||
|
||||
if (x == root)
|
||||
root = y;
|
||||
else if (x == x->m_parent->m_right)
|
||||
x->m_parent->m_right = y;
|
||||
else
|
||||
x->m_parent->m_left = y;
|
||||
y->m_right = x;
|
||||
x->m_parent = y;
|
||||
}
|
||||
|
||||
static void _rb_insert_rebalance(const bool insert_left, _rb_tree_base* x, _rb_tree_base* p, _rb_tree_base& header) {
|
||||
_rb_tree_base *& root = header.m_parent;
|
||||
|
||||
x->m_parent = p;
|
||||
x->m_left = 0;
|
||||
x->m_right = 0;
|
||||
x->m_isblack = false;
|
||||
|
||||
if (insert_left) {
|
||||
p->m_left = x;
|
||||
|
||||
if (p == &header) {
|
||||
header.m_parent = x;
|
||||
header.m_right = x;
|
||||
} else if (p == header.m_left){
|
||||
header.m_left = x;
|
||||
}
|
||||
} else {
|
||||
p->m_right = x;
|
||||
|
||||
if (p == header.m_right) {
|
||||
header.m_right = x;
|
||||
}
|
||||
}
|
||||
|
||||
while (x != root && x->m_parent->m_isblack == false) {
|
||||
_rb_tree_base* const xpp = x->m_parent->m_parent;
|
||||
|
||||
if (x->m_parent == xpp->m_left) {
|
||||
_rb_tree_base* const y = xpp->m_right;
|
||||
if (y && y->m_isblack == false) {
|
||||
x->m_parent->m_isblack = true;
|
||||
y->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
x = xpp;
|
||||
} else {
|
||||
if (x == x->m_parent->m_right) {
|
||||
x = x->m_parent;
|
||||
_rb_tree_rotate_left(x, root);
|
||||
}
|
||||
x->m_parent->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
_rb_tree_rotate_right(xpp, root);
|
||||
}
|
||||
} else {
|
||||
_rb_tree_base* const y = xpp->m_left;
|
||||
if (y && y->m_isblack == false) {
|
||||
x->m_parent->m_isblack = true;
|
||||
y->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
x = xpp;
|
||||
} else {
|
||||
if (x == x->m_parent->m_left) {
|
||||
x = x->m_parent;
|
||||
_rb_tree_rotate_right(x, root);
|
||||
}
|
||||
x->m_parent->m_isblack = true;
|
||||
xpp->m_isblack = false;
|
||||
_rb_tree_rotate_left(xpp, root);
|
||||
}
|
||||
}
|
||||
}
|
||||
root->m_isblack = true;
|
||||
}
|
||||
|
||||
static _rb_tree_base* _rb_increment(_rb_tree_base* __x) throw () {
|
||||
if (__x->m_right != 0) {
|
||||
__x = __x->m_right;
|
||||
while (__x->m_left != 0)
|
||||
__x = __x->m_left;
|
||||
} else {
|
||||
_rb_tree_base* __y = __x->m_parent;
|
||||
while (__x == __y->m_right) {
|
||||
__x = __y;
|
||||
__y = __y->m_parent;
|
||||
}
|
||||
if (__x->m_right != __y)
|
||||
__x = __y;
|
||||
}
|
||||
return __x;
|
||||
}
|
||||
|
||||
static _rb_tree_base* _rb_decrement(_rb_tree_base* __x) throw () {
|
||||
if (!__x->m_isblack && __x->m_parent->m_parent == __x)
|
||||
__x = __x->m_right;
|
||||
else if (__x->m_left != 0) {
|
||||
_rb_tree_base* __y = __x->m_left;
|
||||
while (__y->m_right != 0)
|
||||
__y = __y->m_right;
|
||||
__x = __y;
|
||||
} else {
|
||||
_rb_tree_base* __y = __x->m_parent;
|
||||
while (__x == __y->m_left) {
|
||||
__x = __y;
|
||||
__y = __y->m_parent;
|
||||
}
|
||||
__x = __y;
|
||||
}
|
||||
return __x;
|
||||
}
|
||||
|
||||
template <typename K, typename V>
|
||||
class GEODE_DLL map {
|
||||
protected:
|
||||
std::less<K> compare;
|
||||
_rb_tree_base m_header;
|
||||
size_t m_nodecount;
|
||||
public:
|
||||
typedef _rb_tree_node<std::pair<K,V> >* _tree_node;
|
||||
|
||||
std::map<K, V> std() {
|
||||
return (std::map<K, V>)(*this);
|
||||
}
|
||||
|
||||
operator std::map<K, V>() {
|
||||
auto iter_node = static_cast<_tree_node>(m_header.m_left);
|
||||
auto end_node = static_cast<_tree_node>(&m_header);
|
||||
std::map<K, V> out;
|
||||
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
|
||||
out[iter_node->m_value.first] = iter_node->m_value.second;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
operator std::map<K, V>() const {
|
||||
auto iter_node = static_cast<_tree_node>(m_header.m_left);
|
||||
auto end_node = (_tree_node)(&m_header);
|
||||
std::map<K, V> out;
|
||||
for (;iter_node != end_node; iter_node = static_cast<_tree_node>(_rb_increment(iter_node))) {
|
||||
out[iter_node->m_value.first] = iter_node->m_value.second;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
void insert(_tree_node x, _tree_node p, const std::pair<K, V>& val) {
|
||||
bool insert_left = (x != 0 || p == static_cast<_tree_node>(&m_header) || val.first < p->m_value.first);
|
||||
|
||||
_tree_node z = new _rb_tree_node<std::pair<K,V> >();
|
||||
z->m_value = val;
|
||||
|
||||
_rb_insert_rebalance(insert_left, z, p, m_header);
|
||||
++m_nodecount;
|
||||
}
|
||||
void insert_pair(const std::pair<K, V>& val) {
|
||||
_tree_node x = static_cast<_tree_node>(m_header.m_parent);
|
||||
_tree_node y = static_cast<_tree_node>(&m_header);
|
||||
bool comp = true;
|
||||
while (x != 0) {
|
||||
y = x;
|
||||
comp = val.first < x->m_value.first;
|
||||
x = comp ? static_cast<_tree_node>(x->m_left) : static_cast<_tree_node>(x->m_right);
|
||||
}
|
||||
auto iter = y;
|
||||
|
||||
if (comp) {
|
||||
if (iter == static_cast<_tree_node>(m_header.m_left)) {
|
||||
insert(x, y, val);
|
||||
} else {
|
||||
iter = static_cast<_tree_node>(_rb_decrement(iter));
|
||||
}
|
||||
}
|
||||
if (iter->m_value.first < val.first) {
|
||||
insert(x, y, val);
|
||||
}
|
||||
}
|
||||
|
||||
map(std::map<K, V> input) {
|
||||
m_header.m_isblack = false;
|
||||
m_header.m_parent = 0;
|
||||
m_header.m_left = &m_header;
|
||||
m_header.m_right = &m_header;
|
||||
|
||||
for (auto i : input) {
|
||||
insert_pair(i);
|
||||
}
|
||||
}
|
||||
void erase(_tree_node x) {
|
||||
while (x != 0) {
|
||||
erase(static_cast<_tree_node>(x->m_right));
|
||||
auto y = static_cast<_tree_node>(x->m_left);
|
||||
delete y;
|
||||
x = y;
|
||||
}
|
||||
}
|
||||
map(map const& lol) : map(std::map<K, V>(lol)) {}
|
||||
map() : map(std::map<K, V>()) {}
|
||||
~map() {
|
||||
erase(static_cast<_tree_node>(m_header.m_parent));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class GEODE_DLL vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
operator std::vector<T>() const {
|
||||
std::vector<T> out;
|
||||
|
||||
for (auto i = m_start; i != m_finish; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
vector(std::vector<T> input) {
|
||||
auto tmp = new T[input.size()];
|
||||
|
||||
m_start = tmp;
|
||||
m_finish = m_start + input.size();
|
||||
m_capacity_end = m_start + input.size();
|
||||
for (auto i : input) {
|
||||
*tmp = i;
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
vector(std::initializer_list<T> const& input) {
|
||||
auto tmp = new T[input.size()];
|
||||
m_start = tmp;
|
||||
m_finish = m_start + input.size();
|
||||
m_capacity_end = m_start + input.size();
|
||||
std::copy(input.begin(), input.end(), tmp);
|
||||
}
|
||||
|
||||
T& front() {
|
||||
return *m_start;
|
||||
}
|
||||
|
||||
auto begin() { return m_start; }
|
||||
auto end() { return m_finish; }
|
||||
auto begin() const { return static_cast<const T*>(m_start); }
|
||||
auto end() const { return static_cast<const T*>(m_finish); }
|
||||
|
||||
vector(vector const& lol) : vector(std::vector<T>(lol)) {}
|
||||
|
||||
vector() : vector(std::vector<T>()) {}
|
||||
|
||||
~vector() {
|
||||
delete[] m_start;
|
||||
}
|
||||
protected:
|
||||
T* m_start;
|
||||
T* m_finish;
|
||||
T* m_capacity_end;
|
||||
};
|
||||
|
||||
struct _bit_reference {
|
||||
uintptr_t* m_bitptr;
|
||||
uintptr_t m_mask;
|
||||
|
||||
_bit_reference(uintptr_t* x, uintptr_t y) : m_bitptr(x), m_mask(y) {}
|
||||
_bit_reference() : m_bitptr(0), m_mask(0) {}
|
||||
|
||||
operator bool() const {
|
||||
return !!(*m_bitptr & m_mask);
|
||||
}
|
||||
|
||||
_bit_reference& operator=(bool x) {
|
||||
if (x)
|
||||
*m_bitptr |= m_mask;
|
||||
else
|
||||
*m_bitptr &= ~m_mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_bit_reference& operator=(const _bit_reference& x) {
|
||||
return *this = bool(x);
|
||||
}
|
||||
|
||||
bool operator==(const _bit_reference& x) const {
|
||||
return bool(*this) == bool(x);
|
||||
}
|
||||
|
||||
bool operator<(const _bit_reference& x) const {
|
||||
return !bool(*this) && bool(x);
|
||||
}
|
||||
|
||||
void flip() {
|
||||
*m_bitptr ^= m_mask;
|
||||
}
|
||||
};
|
||||
|
||||
struct _bit_iterator {
|
||||
uintptr_t* m_bitptr;
|
||||
unsigned int m_offset;
|
||||
_bit_iterator(uintptr_t* x) : m_bitptr(x), m_offset(0) {}
|
||||
_bit_iterator(uintptr_t* x, unsigned o) : m_bitptr(x), m_offset(o) {}
|
||||
_bit_reference operator*() const {
|
||||
return _bit_reference(m_bitptr, 1UL << m_offset);
|
||||
}
|
||||
_bit_iterator& operator++() {
|
||||
if (m_offset++ == sizeof(uintptr_t)-1) {
|
||||
m_offset = 0;
|
||||
m_bitptr++;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator!=(const _bit_iterator& b) {
|
||||
return !(m_bitptr == b.m_bitptr && m_offset == b.m_offset);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class vector<bool> {
|
||||
protected:
|
||||
_bit_iterator m_start;
|
||||
_bit_iterator m_end;
|
||||
uintptr_t* m_capacity_end;
|
||||
public:
|
||||
vector(std::vector<bool> input) : m_start(0), m_end(0) {
|
||||
auto realsize = input.size()/int(sizeof(uintptr_t));
|
||||
auto tmp = new uintptr_t[realsize];
|
||||
|
||||
m_start = _bit_iterator(tmp);
|
||||
m_end = _bit_iterator(tmp + realsize, input.size()%sizeof(uintptr_t));
|
||||
m_capacity_end = tmp + realsize;
|
||||
|
||||
auto itmp = m_start;
|
||||
for (auto i : input) {
|
||||
*itmp = i;
|
||||
++itmp;
|
||||
}
|
||||
}
|
||||
|
||||
operator std::vector<bool>() {
|
||||
std::vector<bool> out;
|
||||
for (auto i = m_start; i != m_end; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
operator std::vector<bool>() const {
|
||||
std::vector<bool> out;
|
||||
for (auto i = m_start; i != m_end; ++i) {
|
||||
out.push_back(*i);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
vector(vector<bool> const& lol) : vector(std::vector<bool>(lol)) {}
|
||||
|
||||
vector() : vector(std::vector<bool>()) {}
|
||||
|
||||
~vector() {
|
||||
delete[] m_start.m_bitptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#elif defined(GEODE_IS_IOS)
|
||||
namespace gd {
|
||||
class GEODE_DLL string {
|
||||
public:
|
||||
string() {}
|
||||
string(char const* ok) : m_internal(ok) {}
|
||||
string(std::string ok) : m_internal(ok) {}
|
||||
operator std::string() {
|
||||
return m_internal;
|
||||
}
|
||||
operator std::string() const {
|
||||
return m_internal;
|
||||
}
|
||||
string(string const& ok) : m_internal(ok) {}
|
||||
string& operator=(char const* ok) {m_internal = ok; return *this;}
|
||||
string& operator=(string const& ok) {m_internal = ok; return *this;}
|
||||
~string() {}
|
||||
char const* c_str() const {return m_internal.c_str(); }
|
||||
protected:
|
||||
std::string m_internal;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class GEODE_DLL vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
operator std::vector<T>() {
|
||||
return m_internal;
|
||||
}
|
||||
operator std::vector<T>() const {
|
||||
return m_internal;
|
||||
}
|
||||
|
||||
vector(std::vector<T> input) : m_internal(input) {}
|
||||
|
||||
T& front() {
|
||||
return m_internal.front();
|
||||
}
|
||||
|
||||
vector(vector const& lol) : m_internal(lol) {}
|
||||
|
||||
vector() : m_internal() {}
|
||||
|
||||
~vector() {}
|
||||
protected:
|
||||
std::vector<T> m_internal;
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class GEODE_DLL map {
|
||||
protected:
|
||||
std::map<K, V> m_internal;
|
||||
public:
|
||||
operator std::map<K, V>() {
|
||||
return m_internal;
|
||||
}
|
||||
operator std::map<K, V>() const {
|
||||
return m_internal;
|
||||
}
|
||||
map(std::map<K, V> input) : m_internal(input) {}
|
||||
|
||||
map(map const& lol) : m_internal(lol) {}
|
||||
map() {}
|
||||
~map() {}
|
||||
};
|
||||
}
|
||||
#else
|
||||
namespace gd = std;
|
||||
#endif
|
96
loader/include/Geode/c++stl/msvcstl.hpp
Normal file
96
loader/include/Geode/c++stl/msvcstl.hpp
Normal file
|
@ -0,0 +1,96 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <Geode/platform/platform.hpp>
|
||||
// #include <Geode/binding/GDString.hpp>
|
||||
|
||||
#if defined(GEODE_IS_WINDOWS)
|
||||
|
||||
namespace gd {
|
||||
struct InternalString {
|
||||
union {
|
||||
char m_storage[16];
|
||||
char* m_pointer;
|
||||
};
|
||||
size_t m_length;
|
||||
size_t m_capacity;
|
||||
};
|
||||
|
||||
class GEODE_DLL string : protected GDString {
|
||||
private:
|
||||
InternalString m_data;
|
||||
|
||||
public:
|
||||
|
||||
template <class... Params>
|
||||
string(Params&&... params) {
|
||||
m_data.m_pointer = 0;
|
||||
m_data.m_length = 0;
|
||||
m_data.m_capacity = 15;
|
||||
|
||||
auto val = std::string(std::forward<Params>(params)...);
|
||||
(void)this->winAssign(val.c_str(), val.size());
|
||||
}
|
||||
|
||||
~string() {
|
||||
(void)this->winDtor();
|
||||
}
|
||||
|
||||
/*template <class... Params>
|
||||
decltype(auto) operator=(Params&&... params) -> decltype(this->operator=(std::forward<Params>(params)...)) {
|
||||
auto val = std::string(this->winCStr(), m_data.m_length);
|
||||
val.operator=(std::forward<Params>(params)...);
|
||||
(void)this->winAssign(val.c_str(), val.size());
|
||||
}*/
|
||||
|
||||
template <class... Params>
|
||||
string& operator=(Params&&... params) {
|
||||
auto val = std::string(this->winCStr(), m_data.m_length);
|
||||
val.operator=(std::forward<Params>(params)...);
|
||||
(void)this->winAssign(val.c_str(), val.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... Params>
|
||||
string& assign(Params&&... params) {
|
||||
auto val = std::string(this->winCStr(), m_data.m_length);
|
||||
val.assign(std::forward<Params>(params)...);
|
||||
(void)this->winAssign(val.c_str(), val.size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
char& at(size_t pos) {
|
||||
if (pos >= m_data.m_length) throw std::out_of_range("gd::string::at");
|
||||
}
|
||||
|
||||
char const& at(size_t pos) const {
|
||||
if (pos >= m_data.m_length) throw std::out_of_range("gd::string::at");
|
||||
}
|
||||
|
||||
char& operator[](size_t pos) {
|
||||
return this->winCStr()[pos];
|
||||
}
|
||||
|
||||
char const& operator[](size_t pos) const {
|
||||
return this->winCStr()[pos];
|
||||
}
|
||||
|
||||
char* data() {
|
||||
return this->winCStr();
|
||||
}
|
||||
|
||||
char const* data() const {
|
||||
return this->winCStr();
|
||||
}
|
||||
|
||||
char const* c_str() const {
|
||||
return this->winCStr();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,21 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include "Types.hpp"
|
||||
#include "Hook.hpp"
|
||||
#include <Geode/utils/types.hpp>
|
||||
#include "Setting.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
#include <Geode/utils/VersionInfo.hpp>
|
||||
#include <Geode/utils/json.hpp>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <type_traits>
|
||||
#include "Setting.hpp"
|
||||
#include <Geode/utils/types.hpp>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class InternalLoader;
|
||||
class InternalMod;
|
||||
|
||||
namespace geode {
|
||||
struct PlatformInfo;
|
||||
|
||||
|
@ -26,8 +28,8 @@ namespace geode {
|
|||
class Setting;
|
||||
|
||||
class Unknown;
|
||||
using unknownmemfn_t = void(Unknown::*)();
|
||||
using unknownfn_t = void(*)();
|
||||
using unknownmemfn_t = void (Unknown::*)();
|
||||
using unknownfn_t = void (*)();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,7 +37,7 @@ namespace geode {
|
|||
*/
|
||||
GEODE_API bool GEODE_CALL geode_implicit_load(geode::Mod*);
|
||||
|
||||
namespace geode {
|
||||
namespace geode {
|
||||
|
||||
struct Dependency {
|
||||
std::string m_id;
|
||||
|
@ -53,7 +55,7 @@ namespace geode {
|
|||
};
|
||||
|
||||
/**
|
||||
* Represents all the data gatherable
|
||||
* Represents all the data gatherable
|
||||
* from mod.json
|
||||
*/
|
||||
struct GEODE_DLL ModInfo {
|
||||
|
@ -62,13 +64,15 @@ namespace geode {
|
|||
*/
|
||||
ghc::filesystem::path m_path;
|
||||
/**
|
||||
* Name of the platform binary within
|
||||
* Name of the platform binary within
|
||||
* the mod zip
|
||||
*/
|
||||
// clang-format off
|
||||
std::string m_binaryName = GEODE_WINDOWS("mod.dll")
|
||||
GEODE_MACOS("mod.dylib")
|
||||
GEODE_IOS("mod.dylib")
|
||||
GEODE_ANDROID("mod.so");
|
||||
// clang-format on
|
||||
/**
|
||||
* Mod Version. Should follow semver.
|
||||
*/
|
||||
|
@ -103,12 +107,12 @@ namespace geode {
|
|||
*/
|
||||
std::string m_developer;
|
||||
/**
|
||||
* Short & concise description of the
|
||||
* Short & concise description of the
|
||||
* mod.
|
||||
*/
|
||||
std::optional<std::string> m_description;
|
||||
/**
|
||||
* Detailed description of the mod, writtenin Markdown (see
|
||||
* Detailed description of the mod, writtenin Markdown (see
|
||||
* <Geode/ui/MDTextArea.hpp>) for more info
|
||||
*/
|
||||
std::optional<std::string> m_details;
|
||||
|
@ -118,8 +122,8 @@ namespace geode {
|
|||
*/
|
||||
std::optional<std::string> m_changelog;
|
||||
/**
|
||||
* Support info for the mod; this means anything to show ways to
|
||||
* support the mod's development, like donations. Written in Markdown
|
||||
* Support info for the mod; this means anything to show ways to
|
||||
* support the mod's development, like donations. Written in Markdown
|
||||
* (see <Geode/ui/MDTextArea.hpp>) for more info
|
||||
*/
|
||||
std::optional<std::string> m_supportInfo;
|
||||
|
@ -170,8 +174,8 @@ namespace geode {
|
|||
|
||||
private:
|
||||
/**
|
||||
* Version is passed for backwards
|
||||
* compatibility if we update the mod.json
|
||||
* Version is passed for backwards
|
||||
* compatibility if we update the mod.json
|
||||
* format
|
||||
*/
|
||||
static Result<ModInfo> createFromSchemaV010(ModJson const& json);
|
||||
|
@ -179,10 +183,7 @@ namespace geode {
|
|||
Result<> addSpecialFiles(ghc::filesystem::path const& dir);
|
||||
Result<> addSpecialFiles(cocos2d::ZipFile& zip);
|
||||
|
||||
std::vector<std::pair<
|
||||
std::string,
|
||||
std::optional<std::string>*
|
||||
>> getSpecialFiles();
|
||||
std::vector<std::pair<std::string, std::optional<std::string>*>> getSpecialFiles();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -195,7 +196,7 @@ namespace geode {
|
|||
Mod* m_mod;
|
||||
|
||||
DataStore(Mod* m, nlohmann::json& j) : m_mod(m), m_store(j) {}
|
||||
|
||||
|
||||
friend class Mod;
|
||||
|
||||
public:
|
||||
|
@ -206,12 +207,11 @@ namespace geode {
|
|||
DataStore& operator=(nlohmann::json&);
|
||||
bool contains(std::string const&) const;
|
||||
operator nlohmann::json();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @class Mod
|
||||
* Represents a Mod ingame.
|
||||
* Represents a Mod ingame.
|
||||
* @abstract
|
||||
*/
|
||||
class GEODE_DLL Mod {
|
||||
|
@ -253,9 +253,9 @@ namespace geode {
|
|||
*/
|
||||
ghc::filesystem::path m_saveDirPath;
|
||||
/**
|
||||
* Pointers to mods that depend on
|
||||
* this Mod. Makes it possible to
|
||||
* enable / disable them automatically,
|
||||
* Pointers to mods that depend on
|
||||
* this Mod. Makes it possible to
|
||||
* enable / disable them automatically,
|
||||
* when their dependency is disabled.
|
||||
*/
|
||||
std::vector<Mod*> m_parentDependencies;
|
||||
|
@ -283,7 +283,7 @@ namespace geode {
|
|||
geode_save_data m_saveDataFunc = nullptr;
|
||||
geode_setting_updated m_settingUpdatedFunc = nullptr;
|
||||
/**
|
||||
* Whether temp/<mod id>/resources should be
|
||||
* Whether temp/<mod id>/resources should be
|
||||
* added to CCFileUtils search paths
|
||||
*/
|
||||
bool m_addResourcesToSearchPath = false;
|
||||
|
@ -312,9 +312,9 @@ namespace geode {
|
|||
|
||||
static bool validateID(std::string const& id);
|
||||
// no copying
|
||||
Mod(Mod const&) = delete;
|
||||
Mod(Mod const&) = delete;
|
||||
Mod operator=(Mod const&) = delete;
|
||||
|
||||
|
||||
/**
|
||||
* Protected constructor/destructor
|
||||
*/
|
||||
|
@ -328,10 +328,10 @@ namespace geode {
|
|||
friend struct ModInfo;
|
||||
friend class DataStore;
|
||||
|
||||
template<class = void>
|
||||
template <class = void>
|
||||
static inline GEODE_HIDDEN Mod* sharedMod = nullptr;
|
||||
|
||||
template<class = void>
|
||||
template <class = void>
|
||||
static inline GEODE_HIDDEN void setSharedMod(Mod* mod) {
|
||||
sharedMod<> = mod;
|
||||
}
|
||||
|
@ -344,17 +344,16 @@ namespace geode {
|
|||
std::string getDeveloper() const;
|
||||
std::optional<std::string> getDescription() const;
|
||||
std::optional<std::string> getDetails() const;
|
||||
[[deprecated("Use Mod::getPackagePath instead")]]
|
||||
std::string getPath() const;
|
||||
[[deprecated("Use Mod::getPackagePath instead")]] std::string getPath() const;
|
||||
ghc::filesystem::path getPackagePath() const;
|
||||
VersionInfo getVersion() const;
|
||||
bool isEnabled() const;
|
||||
bool isLoaded() const;
|
||||
bool supportsDisabling() const;
|
||||
bool supportsUnloading() const;
|
||||
bool wasSuccesfullyLoaded() const;
|
||||
bool isEnabled() const;
|
||||
bool isLoaded() const;
|
||||
bool supportsDisabling() const;
|
||||
bool supportsUnloading() const;
|
||||
bool wasSuccesfullyLoaded() const;
|
||||
std::string getLoadErrorInfo() const;
|
||||
ModInfo getModInfo() const;
|
||||
ModInfo getModInfo() const;
|
||||
ghc::filesystem::path getTempDir() const;
|
||||
ghc::filesystem::path getBinaryPath() const;
|
||||
/**
|
||||
|
@ -370,16 +369,16 @@ namespace geode {
|
|||
decltype(ModInfo::m_settings) getSettings() const;
|
||||
bool hasSetting(std::string const& key) const;
|
||||
std::shared_ptr<Setting> getSetting(std::string const& key) const;
|
||||
template<class T>
|
||||
|
||||
template <class T>
|
||||
T getSettingValue(std::string const& key) const {
|
||||
if (this->hasSetting(key)) {
|
||||
return geode::getBuiltInSettingValue<T>(
|
||||
this->getSetting(key)
|
||||
);
|
||||
return geode::getBuiltInSettingValue<T>(this->getSetting(key));
|
||||
}
|
||||
return T();
|
||||
}
|
||||
template<class T>
|
||||
|
||||
template <class T>
|
||||
bool setSettingValue(std::string const& key, T const& value) {
|
||||
if (this->hasSetting(key)) {
|
||||
geode::setBuiltInSettingValue<T>(this->getSetting(key), value);
|
||||
|
@ -393,7 +392,7 @@ namespace geode {
|
|||
* @returns nullptr if Interface is not initialized,
|
||||
* the mod pointer if it is initialized
|
||||
*/
|
||||
template<class = void>
|
||||
template <class = void>
|
||||
static inline GEODE_HIDDEN Mod* get() {
|
||||
return sharedMod<>;
|
||||
}
|
||||
|
@ -405,59 +404,59 @@ namespace geode {
|
|||
std::vector<Hook*> getHooks() const;
|
||||
|
||||
/**
|
||||
* Create a hook at an address. Call the original
|
||||
* function by calling the original function –
|
||||
* Create a hook at an address. Call the original
|
||||
* function by calling the original function –
|
||||
* no trampoline needed
|
||||
* @param address The absolute address of
|
||||
* @param address The absolute address of
|
||||
* the function to hook, i.e. gd_base + 0xXXXX
|
||||
* @param detour Pointer to your detour function
|
||||
* @returns Successful result containing the
|
||||
* Hook handle, errorful result with info on
|
||||
* @returns Successful result containing the
|
||||
* Hook handle, errorful result with info on
|
||||
* error
|
||||
*/
|
||||
template<auto Detour, template <class, class...> class Convention>
|
||||
template <auto Detour, template <class, class...> class Convention>
|
||||
Result<Hook*> addHook(void* address) {
|
||||
return this->addHook<Detour, Convention>("", address);
|
||||
}
|
||||
return this->addHook<Detour, Convention>("", address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hook at an address. Call the original
|
||||
* function by calling the original function –
|
||||
* no trampoline needed. Also takes a displayName
|
||||
* Create a hook at an address. Call the original
|
||||
* function by calling the original function –
|
||||
* no trampoline needed. Also takes a displayName
|
||||
* parameter to use for when visualizing the hook.
|
||||
* @param address The absolute address of
|
||||
* @param address The absolute address of
|
||||
* the function to hook, i.e. gd_base + 0xXXXX
|
||||
* @param detour Pointer to your detour function
|
||||
* @returns Successful result containing the
|
||||
* Hook handle, errorful result with info on
|
||||
* @returns Successful result containing the
|
||||
* Hook handle, errorful result with info on
|
||||
* error
|
||||
*/
|
||||
template<auto Detour, template <class, class...> class Convention>
|
||||
template <auto Detour, template <class, class...> class Convention>
|
||||
Result<Hook*> addHook(std::string const& displayName, void* address) {
|
||||
auto hook = Hook::create<Detour, Convention>((decltype(Detour))address, displayName, this);
|
||||
return this->addHook(hook);
|
||||
}
|
||||
|
||||
Result<Hook*> addHook(Hook* hook);
|
||||
auto hook =
|
||||
Hook::create<Detour, Convention>((decltype(Detour))address, displayName, this);
|
||||
return this->addHook(hook);
|
||||
}
|
||||
|
||||
Result<Hook*> addHook(Hook* hook);
|
||||
|
||||
/**
|
||||
* Enable a hook owned by this Mod
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> enableHook(Hook* hook);
|
||||
|
||||
/**
|
||||
* Disable a hook owned by this Mod
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> disableHook(Hook* hook);
|
||||
|
||||
/**
|
||||
* Remove a hook owned by this Mod
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> removeHook(Hook* hook);
|
||||
|
@ -466,52 +465,52 @@ namespace geode {
|
|||
* Write a patch at an address
|
||||
* @param address The address to write into
|
||||
* @param data The data to write there
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<Patch*> patch(void* address, byte_array data);
|
||||
|
||||
/**
|
||||
* Remove a patch owned by this Mod
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> unpatch(Patch* patch);
|
||||
|
||||
/**
|
||||
* Load this mod
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> load();
|
||||
|
||||
/**
|
||||
* Unload this mod
|
||||
* @warning May crash if the mod doesn't
|
||||
* @warning May crash if the mod doesn't
|
||||
* properly handle unloading!
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> unload();
|
||||
|
||||
/**
|
||||
* Enable this mod
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> enable();
|
||||
|
||||
|
||||
/**
|
||||
* Disable this mod if it supports doing so
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> disable();
|
||||
|
||||
/**
|
||||
* Disable & unload this mod (if supported),
|
||||
* Disable & unload this mod (if supported),
|
||||
* then delete the mod's .geode file.
|
||||
* @returns Successful result on success,
|
||||
* @returns Successful result on success,
|
||||
* errorful result with info on error
|
||||
*/
|
||||
Result<> uninstall();
|
||||
|
@ -530,39 +529,38 @@ namespace geode {
|
|||
*/
|
||||
Result<> resetDataStore();
|
||||
|
||||
|
||||
/**
|
||||
* Check whether or not this Mod
|
||||
* depends on another mod
|
||||
*/
|
||||
bool depends(std::string const& id) const;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether all the required
|
||||
* dependencies for this mod have
|
||||
* Check whether all the required
|
||||
* dependencies for this mod have
|
||||
* been loaded or not
|
||||
* @returns True if the mod has unresolved
|
||||
* @returns True if the mod has unresolved
|
||||
* dependencies, false if not.
|
||||
*/
|
||||
bool hasUnresolvedDependencies() const;
|
||||
/**
|
||||
* Update the state of each of the
|
||||
* dependencies. Depending on if the
|
||||
* mod has unresolved dependencies,
|
||||
* Update the state of each of the
|
||||
* dependencies. Depending on if the
|
||||
* mod has unresolved dependencies,
|
||||
* it will either be loaded or unloaded
|
||||
* @returns True if the mod has unresolved
|
||||
* @returns True if the mod has unresolved
|
||||
* dependencies, false if not.
|
||||
*/
|
||||
bool updateDependencyStates();
|
||||
/**
|
||||
* Get a list of all the unresolved
|
||||
* Get a list of all the unresolved
|
||||
* dependencies this mod has
|
||||
* @returns List of all the unresolved
|
||||
* @returns List of all the unresolved
|
||||
* dependencies
|
||||
*/
|
||||
std::vector<Dependency> getUnresolvedDependencies();
|
||||
|
||||
const char* expandSpriteName(const char* name);
|
||||
char const* expandSpriteName(char const* name);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -576,6 +574,6 @@ namespace geode {
|
|||
}
|
||||
}
|
||||
|
||||
inline const char* operator"" _spr(const char* str, size_t) {
|
||||
inline char const* operator"" _spr(char const* str, size_t) {
|
||||
return geode::Mod::get()->expandSpriteName(str);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace {
|
|||
struct derived##Parent {}; \
|
||||
Modify<derived<derived##Parent>, base> derived##Apply; \
|
||||
struct GEODE_HIDDEN derived##Intermediate : base { \
|
||||
geode::modifier::FieldIntermediate<base, \
|
||||
mutable geode::modifier::FieldIntermediate<base, \
|
||||
derived##Intermediate, \
|
||||
derived<derived##Parent> \
|
||||
> m_fields; \
|
||||
|
@ -45,7 +45,7 @@ struct derived;
|
|||
namespace { \
|
||||
Modify<derived, base> derived##Apply; \
|
||||
struct GEODE_HIDDEN derived##Intermediate : base { \
|
||||
geode::modifier::FieldIntermediate<base, \
|
||||
mutable geode::modifier::FieldIntermediate<base, \
|
||||
derived##Intermediate, \
|
||||
derived \
|
||||
> m_fields; \
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#include <about.hpp>
|
||||
#include <Geode/cocos/support/zip_support/ZipUtils.h>
|
||||
#include <Geode/loader/Hook.hpp>
|
||||
#include <Geode/loader/Loader.hpp>
|
||||
#include <Geode/loader/Log.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/loader/Setting.hpp>
|
||||
#include <Geode/utils/JsonValidation.hpp>
|
||||
#include <Geode/utils/conststring.hpp>
|
||||
#include <Geode/utils/file.hpp>
|
||||
#include <Geode/utils/JsonValidation.hpp>
|
||||
#include <Geode/utils/map.hpp>
|
||||
#include <Geode/utils/ranges.hpp>
|
||||
#include <Geode/utils/string.hpp>
|
||||
#include <Geode/utils/vector.hpp>
|
||||
#include <Geode/utils/ranges.hpp>
|
||||
#include <InternalMod.hpp>
|
||||
#include <../support/zip_support/ZipUtils.h>
|
||||
#include <about.hpp>
|
||||
|
||||
USE_GEODE_NAMESPACE();
|
||||
|
||||
|
@ -70,22 +70,20 @@ Result<> Mod::loadSettings() {
|
|||
if (auto sett = this->getSetting(key)) {
|
||||
// load its value
|
||||
if (!sett->load(value.json())) {
|
||||
return Err(
|
||||
"Unable to load value for setting \"" +
|
||||
key + "\""
|
||||
);
|
||||
return Err("Unable to load value for setting \"" + key + "\"");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log::log(
|
||||
Severity::Warning,
|
||||
this,
|
||||
"Encountered unknown setting \"{}\" while loading settings",
|
||||
Severity::Warning, this,
|
||||
"Encountered unknown setting \"{}\" while loading "
|
||||
"settings",
|
||||
key
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
} catch(std::exception& e) {
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
return Err(std::string("Unable to parse settings: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
@ -94,12 +92,14 @@ Result<> Mod::loadSettings() {
|
|||
auto dsPath = m_saveDirPath / "ds.json";
|
||||
if (!ghc::filesystem::exists(dsPath)) {
|
||||
m_dataStore = m_info.m_defaultDataStore;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
auto dsData = utils::file::readString(dsPath);
|
||||
if (!dsData) return dsData;
|
||||
try {
|
||||
m_dataStore = nlohmann::json::parse(dsData.value());
|
||||
} catch(std::exception& e) {
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
return Err(std::string("Unable to parse datastore: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
@ -151,8 +151,7 @@ Result<> Mod::createTempDir() {
|
|||
|
||||
if (!unzip.fileExists(m_info.m_binaryName)) {
|
||||
return Err<>(
|
||||
"Unable to find platform binary under the name \"" +
|
||||
m_info.m_binaryName + "\""
|
||||
"Unable to find platform binary under the name \"" + m_info.m_binaryName + "\""
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -162,7 +161,7 @@ Result<> Mod::createTempDir() {
|
|||
return Err<>("Unable to create temp directory for mods!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto tempPath = ghc::filesystem::path(tempDir) / m_info.m_id;
|
||||
if (!ghc::filesystem::exists(tempPath) && !ghc::filesystem::create_directories(tempPath)) {
|
||||
return Err<>("Unable to create temp directory");
|
||||
|
@ -172,11 +171,11 @@ Result<> Mod::createTempDir() {
|
|||
for (auto file : unzip.getAllFiles()) {
|
||||
auto path = ghc::filesystem::path(file);
|
||||
if (path.has_parent_path()) {
|
||||
if (
|
||||
!ghc::filesystem::exists(tempPath / path.parent_path()) &&
|
||||
!ghc::filesystem::create_directories(tempPath / path.parent_path())
|
||||
) {
|
||||
return Err<>("Unable to create directories \"" + path.parent_path().string() + "\"");
|
||||
if (!ghc::filesystem::exists(tempPath / path.parent_path()) &&
|
||||
!ghc::filesystem::create_directories(tempPath / path.parent_path())) {
|
||||
return Err<>(
|
||||
"Unable to create directories \"" + path.parent_path().string() + "\""
|
||||
);
|
||||
}
|
||||
}
|
||||
unsigned long size;
|
||||
|
@ -184,10 +183,7 @@ Result<> Mod::createTempDir() {
|
|||
if (!data || !size) {
|
||||
return Err<>("Unable to read \"" + std::string(file) + "\"");
|
||||
}
|
||||
auto wrt = utils::file::writeBinary(
|
||||
tempPath / file,
|
||||
byte_array(data, data + size)
|
||||
);
|
||||
auto wrt = utils::file::writeBinary(tempPath / file, byte_array(data, data + size));
|
||||
if (!wrt) return Err<>("Unable to write \"" + file + "\": " + wrt.error());
|
||||
}
|
||||
|
||||
|
@ -197,12 +193,14 @@ Result<> Mod::createTempDir() {
|
|||
}
|
||||
|
||||
Result<> Mod::load() {
|
||||
if (m_loaded) {
|
||||
if (m_loaded) {
|
||||
return Ok<>();
|
||||
}
|
||||
#define RETURN_LOAD_ERR(str) \
|
||||
{m_loadErrorInfo = str; \
|
||||
return Err<>(m_loadErrorInfo);}
|
||||
#define RETURN_LOAD_ERR(str) \
|
||||
{ \
|
||||
m_loadErrorInfo = str; \
|
||||
return Err<>(m_loadErrorInfo); \
|
||||
}
|
||||
|
||||
if (!m_tempDirName.string().size()) {
|
||||
auto err = this->createTempDir();
|
||||
|
@ -247,7 +245,7 @@ Result<> Mod::unload() {
|
|||
if (!m_info.m_supportsUnloading) {
|
||||
return Err<>("Mod does not support unloading");
|
||||
}
|
||||
|
||||
|
||||
if (m_saveDataFunc) {
|
||||
if (!m_saveDataFunc(m_saveDirPath.string().c_str())) {
|
||||
log::log(Severity::Error, this, "Mod save data function returned false");
|
||||
|
@ -286,7 +284,7 @@ Result<> Mod::enable() {
|
|||
if (!m_loaded) {
|
||||
return Err<>("Mod is not loaded");
|
||||
}
|
||||
|
||||
|
||||
if (m_enableFunc) {
|
||||
if (!m_enableFunc()) {
|
||||
return Err<>("Mod enable function returned false");
|
||||
|
@ -361,55 +359,58 @@ bool Mod::isUninstalled() const {
|
|||
|
||||
bool Dependency::isUnresolved() const {
|
||||
return m_required &&
|
||||
(m_state == ModResolveState::Unloaded ||
|
||||
m_state == ModResolveState::Unresolved ||
|
||||
m_state == ModResolveState::Disabled);
|
||||
(m_state == ModResolveState::Unloaded || m_state == ModResolveState::Unresolved ||
|
||||
m_state == ModResolveState::Disabled);
|
||||
}
|
||||
|
||||
bool Mod::updateDependencyStates() {
|
||||
bool hasUnresolved = false;
|
||||
for (auto & dep : m_info.m_dependencies) {
|
||||
if (!dep.m_mod) {
|
||||
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
||||
}
|
||||
if (dep.m_mod) {
|
||||
dep.m_mod->updateDependencyStates();
|
||||
for (auto& dep : m_info.m_dependencies) {
|
||||
if (!dep.m_mod) {
|
||||
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
||||
}
|
||||
if (dep.m_mod) {
|
||||
dep.m_mod->updateDependencyStates();
|
||||
|
||||
if (dep.m_mod->hasUnresolvedDependencies()) {
|
||||
dep.m_state = ModResolveState::Unresolved;
|
||||
} else {
|
||||
if (!dep.m_mod->m_resolved) {
|
||||
dep.m_mod->m_resolved = true;
|
||||
dep.m_state = ModResolveState::Resolved;
|
||||
if (dep.m_mod->hasUnresolvedDependencies()) {
|
||||
dep.m_state = ModResolveState::Unresolved;
|
||||
}
|
||||
else {
|
||||
if (!dep.m_mod->m_resolved) {
|
||||
dep.m_mod->m_resolved = true;
|
||||
dep.m_state = ModResolveState::Resolved;
|
||||
auto r = dep.m_mod->load();
|
||||
if (!r) {
|
||||
dep.m_state = ModResolveState::Unloaded;
|
||||
log::log(Severity::Error, dep.m_mod, "{}", r.error());
|
||||
}
|
||||
else {
|
||||
auto r = dep.m_mod->enable();
|
||||
if (!r) {
|
||||
dep.m_state = ModResolveState::Disabled;
|
||||
auto r = dep.m_mod->enable();
|
||||
if (!r) {
|
||||
dep.m_state = ModResolveState::Disabled;
|
||||
log::log(Severity::Error, dep.m_mod, "{}", r.error());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dep.m_mod->isEnabled()) {
|
||||
dep.m_state = ModResolveState::Loaded;
|
||||
} else {
|
||||
dep.m_state = ModResolveState::Disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dep.m_state = ModResolveState::Unloaded;
|
||||
}
|
||||
if (dep.isUnresolved()) {
|
||||
m_resolved = false;
|
||||
}
|
||||
else {
|
||||
if (dep.m_mod->isEnabled()) {
|
||||
dep.m_state = ModResolveState::Loaded;
|
||||
}
|
||||
else {
|
||||
dep.m_state = ModResolveState::Disabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
dep.m_state = ModResolveState::Unloaded;
|
||||
}
|
||||
if (dep.isUnresolved()) {
|
||||
m_resolved = false;
|
||||
(void)this->unload();
|
||||
hasUnresolved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasUnresolved && !m_resolved) {
|
||||
log::debug("All dependencies for {} found", m_info.m_id);
|
||||
m_resolved = true;
|
||||
|
@ -420,12 +421,13 @@ bool Mod::updateDependencyStates() {
|
|||
log::error("{} Error loading: {}", this, r.error());
|
||||
}
|
||||
else {
|
||||
auto r = this->enable();
|
||||
if (!r) {
|
||||
log::error("{} Error enabling: {}", this, r.error());
|
||||
}
|
||||
auto r = this->enable();
|
||||
if (!r) {
|
||||
log::error("{} Error enabling: {}", this, r.error());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
log::debug("Resolved {}, however not loading it as it is disabled", m_info.m_id);
|
||||
}
|
||||
}
|
||||
|
@ -433,21 +435,21 @@ bool Mod::updateDependencyStates() {
|
|||
}
|
||||
|
||||
bool Mod::hasUnresolvedDependencies() const {
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Dependency> Mod::getUnresolvedDependencies() {
|
||||
std::vector<Dependency> res;
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved()) {
|
||||
res.push_back(dep);
|
||||
}
|
||||
}
|
||||
for (auto const& dep : m_info.m_dependencies) {
|
||||
if (dep.isUnresolved()) {
|
||||
res.push_back(dep);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -532,14 +534,13 @@ std::vector<Hook*> Mod::getHooks() const {
|
|||
}
|
||||
|
||||
bool Mod::depends(std::string const& id) const {
|
||||
return utils::ranges::contains(
|
||||
m_info.m_dependencies,
|
||||
[id](Dependency const& t) { return t.m_id == id; }
|
||||
);
|
||||
return utils::ranges::contains(m_info.m_dependencies, [id](Dependency const& t) {
|
||||
return t.m_id == id;
|
||||
});
|
||||
}
|
||||
|
||||
const char* Mod::expandSpriteName(const char* name) {
|
||||
static std::unordered_map<std::string, const char*> expanded = {};
|
||||
char const* Mod::expandSpriteName(char const* name) {
|
||||
static std::unordered_map<std::string, char const*> expanded = {};
|
||||
if (expanded.count(name)) {
|
||||
return expanded[name];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue