mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-22 23:48:08 -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;
|
CCScale9Sprite() = mac 0x211330;
|
||||||
static cocos2d::extension::CCScale9Sprite* create(char const*) = mac 0x2130d0;
|
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) = 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*, cocos2d::CCRect) = mac 0x213380;
|
||||||
static cocos2d::extension::CCScale9Sprite* createWithSpriteFrameName(char const*) = mac 0x213460;
|
static cocos2d::extension::CCScale9Sprite* createWithSpriteFrameName(char const*) = mac 0x213460;
|
||||||
virtual ~CCScale9Sprite() = mac 0x211590;
|
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 {
|
class AchievementBar : cocos2d::CCNodeRGBA {
|
||||||
static AchievementBar* create(const char* title, const char* desc, const char* icon, bool quest) = mac 0x379f80, win 0x3b120, ios 0x1a4784;
|
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 applicationWillResignActive() = mac 0x3aab50, win 0x3cf20;
|
||||||
virtual void trySaveGame() = mac 0x3aaf10, win 0x3d5e0, ios 0x1a28f0;
|
virtual void trySaveGame() = mac 0x3aaf10, win 0x3d5e0, ios 0x1a28f0;
|
||||||
virtual void willSwitchToScene(cocos2d::CCScene*) = mac 0x3aaf40, win 0x3d690;
|
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;
|
bool musicTest() = win 0x3d580;
|
||||||
void pauseGame() = mac 0x3aab60, win 0x3d3e0;
|
void pauseGame() = mac 0x3aab60, win 0x3d3e0;
|
||||||
void resumeSound() = win 0x3d4d0;
|
void resumeSound() = win 0x3d4d0;
|
||||||
|
@ -814,7 +835,7 @@ class CreatorLayer : cocos2d::CCLayer {
|
||||||
void onBack(cocos2d::CCObject*) = win 0x4fae0;
|
void onBack(cocos2d::CCObject*) = win 0x4fae0;
|
||||||
void onChallenge(cocos2d::CCObject*) = win 0x4f1b0;
|
void onChallenge(cocos2d::CCObject*) = win 0x4f1b0;
|
||||||
void onLeaderboards(cocos2d::CCObject*) = win 0x4ed20;
|
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;
|
void onSavedLevels(cocos2d::CCObject*) = mac 0x142860;
|
||||||
virtual void sceneWillResume() = win 0x4fb50;
|
virtual void sceneWillResume() = win 0x4fb50;
|
||||||
virtual bool init() = mac 0x141c10, win 0x4de40;
|
virtual bool init() = mac 0x141c10, win 0x4de40;
|
||||||
|
@ -910,6 +931,7 @@ class DailyLevelPage : FLAlertLayer {
|
||||||
static DailyLevelPage* create(bool weekly) = win 0x6a860;
|
static DailyLevelPage* create(bool weekly) = win 0x6a860;
|
||||||
bool init(bool weekly) = win 0x6a900;
|
bool init(bool weekly) = win 0x6a900;
|
||||||
void updateTimers(float) = win 0x6bef0;
|
void updateTimers(float) = win 0x6bef0;
|
||||||
|
virtual void show() = mac 0x10a4b0, win 0x3f360;
|
||||||
|
|
||||||
PAD = win 0x21;
|
PAD = win 0x21;
|
||||||
bool m_weekly;
|
bool m_weekly;
|
||||||
|
@ -1021,7 +1043,7 @@ class EditButtonBar : cocos2d::CCNode {
|
||||||
}
|
}
|
||||||
void addButton(CCMenuItemSpriteExtra* btn, bool reload) {
|
void addButton(CCMenuItemSpriteExtra* btn, bool reload) {
|
||||||
if (this->m_buttonArray)
|
if (this->m_buttonArray)
|
||||||
this->m_buttonArray->addObject(static_cast<cocos2d::CCObject*>(btn));
|
this->m_buttonArray->addObject(btn);
|
||||||
if (reload)
|
if (reload)
|
||||||
this->reloadItemsInNormalSize();
|
this->reloadItemsInNormalSize();
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1062,7 @@ class EditLevelLayer : cocos2d::CCLayer, FLAlertLayerProtocol, TextInputDelegate
|
||||||
static void scene(GJGameLevel* level) {
|
static void scene(GJGameLevel* level) {
|
||||||
auto scene = cocos2d::CCScene::create();
|
auto scene = cocos2d::CCScene::create();
|
||||||
|
|
||||||
scene->addChild(static_cast<cocos2d::CCNode*>(EditLevelLayer::create(level)));
|
scene->addChild(EditLevelLayer::create(level));
|
||||||
|
|
||||||
cocos2d::CCDirector::sharedDirector()->replaceScene(
|
cocos2d::CCDirector::sharedDirector()->replaceScene(
|
||||||
cocos2d::CCTransitionFade::create(.5f, scene)
|
cocos2d::CCTransitionFade::create(.5f, scene)
|
||||||
|
@ -4826,6 +4848,7 @@ class SelectArtLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
class SetGroupIDLayer : FLAlertLayer, TextInputDelegate {
|
class SetGroupIDLayer : FLAlertLayer, TextInputDelegate {
|
||||||
|
bool init(GameObject* object, cocos2d::CCArray* objects) = mac 0x1947c0, win 0x22b670;
|
||||||
void onNextGroupID1(cocos2d::CCObject*) = mac 0x1967a0, win 0x22d790;
|
void onNextGroupID1(cocos2d::CCObject*) = mac 0x1967a0, win 0x22d790;
|
||||||
void textChanged(CCTextInputNode*) = mac 0x197af0, win 0x22d610;
|
void textChanged(CCTextInputNode*) = mac 0x197af0, win 0x22d610;
|
||||||
void updateGroupIDLabel() = mac 0x197260, win 0x22e450;
|
void updateGroupIDLabel() = mac 0x197260, win 0x22e450;
|
||||||
|
|
|
@ -1,513 +1,2 @@
|
||||||
#pragma once
|
#include "gnustl.hpp"
|
||||||
|
// #include "msvcstl.hpp"
|
||||||
#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
|
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <Geode/DefaultInclude.hpp>
|
|
||||||
#include "Types.hpp"
|
|
||||||
#include "Hook.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/Result.hpp>
|
||||||
#include <Geode/utils/VersionInfo.hpp>
|
#include <Geode/utils/VersionInfo.hpp>
|
||||||
#include <Geode/utils/json.hpp>
|
#include <Geode/utils/json.hpp>
|
||||||
#include <string_view>
|
#include <Geode/utils/types.hpp>
|
||||||
#include <vector>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <type_traits>
|
|
||||||
#include "Setting.hpp"
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class InternalLoader;
|
class InternalLoader;
|
||||||
class InternalMod;
|
class InternalMod;
|
||||||
|
|
||||||
namespace geode {
|
namespace geode {
|
||||||
struct PlatformInfo;
|
struct PlatformInfo;
|
||||||
|
|
||||||
|
@ -26,8 +28,8 @@ namespace geode {
|
||||||
class Setting;
|
class Setting;
|
||||||
|
|
||||||
class Unknown;
|
class Unknown;
|
||||||
using unknownmemfn_t = void(Unknown::*)();
|
using unknownmemfn_t = void (Unknown::*)();
|
||||||
using unknownfn_t = void(*)();
|
using unknownfn_t = void (*)();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +37,7 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
GEODE_API bool GEODE_CALL geode_implicit_load(geode::Mod*);
|
GEODE_API bool GEODE_CALL geode_implicit_load(geode::Mod*);
|
||||||
|
|
||||||
namespace geode {
|
namespace geode {
|
||||||
|
|
||||||
struct Dependency {
|
struct Dependency {
|
||||||
std::string m_id;
|
std::string m_id;
|
||||||
|
@ -53,7 +55,7 @@ namespace geode {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents all the data gatherable
|
* Represents all the data gatherable
|
||||||
* from mod.json
|
* from mod.json
|
||||||
*/
|
*/
|
||||||
struct GEODE_DLL ModInfo {
|
struct GEODE_DLL ModInfo {
|
||||||
|
@ -62,13 +64,15 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
ghc::filesystem::path m_path;
|
ghc::filesystem::path m_path;
|
||||||
/**
|
/**
|
||||||
* Name of the platform binary within
|
* Name of the platform binary within
|
||||||
* the mod zip
|
* the mod zip
|
||||||
*/
|
*/
|
||||||
|
// clang-format off
|
||||||
std::string m_binaryName = GEODE_WINDOWS("mod.dll")
|
std::string m_binaryName = GEODE_WINDOWS("mod.dll")
|
||||||
GEODE_MACOS("mod.dylib")
|
GEODE_MACOS("mod.dylib")
|
||||||
GEODE_IOS("mod.dylib")
|
GEODE_IOS("mod.dylib")
|
||||||
GEODE_ANDROID("mod.so");
|
GEODE_ANDROID("mod.so");
|
||||||
|
// clang-format on
|
||||||
/**
|
/**
|
||||||
* Mod Version. Should follow semver.
|
* Mod Version. Should follow semver.
|
||||||
*/
|
*/
|
||||||
|
@ -103,12 +107,12 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
std::string m_developer;
|
std::string m_developer;
|
||||||
/**
|
/**
|
||||||
* Short & concise description of the
|
* Short & concise description of the
|
||||||
* mod.
|
* mod.
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> m_description;
|
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
|
* <Geode/ui/MDTextArea.hpp>) for more info
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> m_details;
|
std::optional<std::string> m_details;
|
||||||
|
@ -118,8 +122,8 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> m_changelog;
|
std::optional<std::string> m_changelog;
|
||||||
/**
|
/**
|
||||||
* Support info for the mod; this means anything to show ways to
|
* Support info for the mod; this means anything to show ways to
|
||||||
* support the mod's development, like donations. Written in Markdown
|
* support the mod's development, like donations. Written in Markdown
|
||||||
* (see <Geode/ui/MDTextArea.hpp>) for more info
|
* (see <Geode/ui/MDTextArea.hpp>) for more info
|
||||||
*/
|
*/
|
||||||
std::optional<std::string> m_supportInfo;
|
std::optional<std::string> m_supportInfo;
|
||||||
|
@ -170,8 +174,8 @@ namespace geode {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* Version is passed for backwards
|
* Version is passed for backwards
|
||||||
* compatibility if we update the mod.json
|
* compatibility if we update the mod.json
|
||||||
* format
|
* format
|
||||||
*/
|
*/
|
||||||
static Result<ModInfo> createFromSchemaV010(ModJson const& json);
|
static Result<ModInfo> createFromSchemaV010(ModJson const& json);
|
||||||
|
@ -179,10 +183,7 @@ namespace geode {
|
||||||
Result<> addSpecialFiles(ghc::filesystem::path const& dir);
|
Result<> addSpecialFiles(ghc::filesystem::path const& dir);
|
||||||
Result<> addSpecialFiles(cocos2d::ZipFile& zip);
|
Result<> addSpecialFiles(cocos2d::ZipFile& zip);
|
||||||
|
|
||||||
std::vector<std::pair<
|
std::vector<std::pair<std::string, std::optional<std::string>*>> getSpecialFiles();
|
||||||
std::string,
|
|
||||||
std::optional<std::string>*
|
|
||||||
>> getSpecialFiles();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,7 +196,7 @@ namespace geode {
|
||||||
Mod* m_mod;
|
Mod* m_mod;
|
||||||
|
|
||||||
DataStore(Mod* m, nlohmann::json& j) : m_mod(m), m_store(j) {}
|
DataStore(Mod* m, nlohmann::json& j) : m_mod(m), m_store(j) {}
|
||||||
|
|
||||||
friend class Mod;
|
friend class Mod;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -206,12 +207,11 @@ namespace geode {
|
||||||
DataStore& operator=(nlohmann::json&);
|
DataStore& operator=(nlohmann::json&);
|
||||||
bool contains(std::string const&) const;
|
bool contains(std::string const&) const;
|
||||||
operator nlohmann::json();
|
operator nlohmann::json();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Mod
|
* @class Mod
|
||||||
* Represents a Mod ingame.
|
* Represents a Mod ingame.
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
class GEODE_DLL Mod {
|
class GEODE_DLL Mod {
|
||||||
|
@ -253,9 +253,9 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
ghc::filesystem::path m_saveDirPath;
|
ghc::filesystem::path m_saveDirPath;
|
||||||
/**
|
/**
|
||||||
* Pointers to mods that depend on
|
* Pointers to mods that depend on
|
||||||
* this Mod. Makes it possible to
|
* this Mod. Makes it possible to
|
||||||
* enable / disable them automatically,
|
* enable / disable them automatically,
|
||||||
* when their dependency is disabled.
|
* when their dependency is disabled.
|
||||||
*/
|
*/
|
||||||
std::vector<Mod*> m_parentDependencies;
|
std::vector<Mod*> m_parentDependencies;
|
||||||
|
@ -283,7 +283,7 @@ namespace geode {
|
||||||
geode_save_data m_saveDataFunc = nullptr;
|
geode_save_data m_saveDataFunc = nullptr;
|
||||||
geode_setting_updated m_settingUpdatedFunc = 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
|
* added to CCFileUtils search paths
|
||||||
*/
|
*/
|
||||||
bool m_addResourcesToSearchPath = false;
|
bool m_addResourcesToSearchPath = false;
|
||||||
|
@ -312,9 +312,9 @@ namespace geode {
|
||||||
|
|
||||||
static bool validateID(std::string const& id);
|
static bool validateID(std::string const& id);
|
||||||
// no copying
|
// no copying
|
||||||
Mod(Mod const&) = delete;
|
Mod(Mod const&) = delete;
|
||||||
Mod operator=(Mod const&) = delete;
|
Mod operator=(Mod const&) = delete;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protected constructor/destructor
|
* Protected constructor/destructor
|
||||||
*/
|
*/
|
||||||
|
@ -328,10 +328,10 @@ namespace geode {
|
||||||
friend struct ModInfo;
|
friend struct ModInfo;
|
||||||
friend class DataStore;
|
friend class DataStore;
|
||||||
|
|
||||||
template<class = void>
|
template <class = void>
|
||||||
static inline GEODE_HIDDEN Mod* sharedMod = nullptr;
|
static inline GEODE_HIDDEN Mod* sharedMod = nullptr;
|
||||||
|
|
||||||
template<class = void>
|
template <class = void>
|
||||||
static inline GEODE_HIDDEN void setSharedMod(Mod* mod) {
|
static inline GEODE_HIDDEN void setSharedMod(Mod* mod) {
|
||||||
sharedMod<> = mod;
|
sharedMod<> = mod;
|
||||||
}
|
}
|
||||||
|
@ -344,17 +344,16 @@ namespace geode {
|
||||||
std::string getDeveloper() const;
|
std::string getDeveloper() const;
|
||||||
std::optional<std::string> getDescription() const;
|
std::optional<std::string> getDescription() const;
|
||||||
std::optional<std::string> getDetails() const;
|
std::optional<std::string> getDetails() const;
|
||||||
[[deprecated("Use Mod::getPackagePath instead")]]
|
[[deprecated("Use Mod::getPackagePath instead")]] std::string getPath() const;
|
||||||
std::string getPath() const;
|
|
||||||
ghc::filesystem::path getPackagePath() const;
|
ghc::filesystem::path getPackagePath() const;
|
||||||
VersionInfo getVersion() const;
|
VersionInfo getVersion() const;
|
||||||
bool isEnabled() const;
|
bool isEnabled() const;
|
||||||
bool isLoaded() const;
|
bool isLoaded() const;
|
||||||
bool supportsDisabling() const;
|
bool supportsDisabling() const;
|
||||||
bool supportsUnloading() const;
|
bool supportsUnloading() const;
|
||||||
bool wasSuccesfullyLoaded() const;
|
bool wasSuccesfullyLoaded() const;
|
||||||
std::string getLoadErrorInfo() const;
|
std::string getLoadErrorInfo() const;
|
||||||
ModInfo getModInfo() const;
|
ModInfo getModInfo() const;
|
||||||
ghc::filesystem::path getTempDir() const;
|
ghc::filesystem::path getTempDir() const;
|
||||||
ghc::filesystem::path getBinaryPath() const;
|
ghc::filesystem::path getBinaryPath() const;
|
||||||
/**
|
/**
|
||||||
|
@ -370,16 +369,16 @@ namespace geode {
|
||||||
decltype(ModInfo::m_settings) getSettings() const;
|
decltype(ModInfo::m_settings) getSettings() const;
|
||||||
bool hasSetting(std::string const& key) const;
|
bool hasSetting(std::string const& key) const;
|
||||||
std::shared_ptr<Setting> getSetting(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 {
|
T getSettingValue(std::string const& key) const {
|
||||||
if (this->hasSetting(key)) {
|
if (this->hasSetting(key)) {
|
||||||
return geode::getBuiltInSettingValue<T>(
|
return geode::getBuiltInSettingValue<T>(this->getSetting(key));
|
||||||
this->getSetting(key)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
template<class T>
|
|
||||||
|
template <class T>
|
||||||
bool setSettingValue(std::string const& key, T const& value) {
|
bool setSettingValue(std::string const& key, T const& value) {
|
||||||
if (this->hasSetting(key)) {
|
if (this->hasSetting(key)) {
|
||||||
geode::setBuiltInSettingValue<T>(this->getSetting(key), value);
|
geode::setBuiltInSettingValue<T>(this->getSetting(key), value);
|
||||||
|
@ -393,7 +392,7 @@ namespace geode {
|
||||||
* @returns nullptr if Interface is not initialized,
|
* @returns nullptr if Interface is not initialized,
|
||||||
* the mod pointer if it is initialized
|
* the mod pointer if it is initialized
|
||||||
*/
|
*/
|
||||||
template<class = void>
|
template <class = void>
|
||||||
static inline GEODE_HIDDEN Mod* get() {
|
static inline GEODE_HIDDEN Mod* get() {
|
||||||
return sharedMod<>;
|
return sharedMod<>;
|
||||||
}
|
}
|
||||||
|
@ -405,59 +404,59 @@ namespace geode {
|
||||||
std::vector<Hook*> getHooks() const;
|
std::vector<Hook*> getHooks() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a hook at an address. Call the original
|
* Create a hook at an address. Call the original
|
||||||
* function by calling the original function –
|
* function by calling the original function –
|
||||||
* no trampoline needed
|
* no trampoline needed
|
||||||
* @param address The absolute address of
|
* @param address The absolute address of
|
||||||
* the function to hook, i.e. gd_base + 0xXXXX
|
* the function to hook, i.e. gd_base + 0xXXXX
|
||||||
* @param detour Pointer to your detour function
|
* @param detour Pointer to your detour function
|
||||||
* @returns Successful result containing the
|
* @returns Successful result containing the
|
||||||
* Hook handle, errorful result with info on
|
* Hook handle, errorful result with info on
|
||||||
* error
|
* error
|
||||||
*/
|
*/
|
||||||
template<auto Detour, template <class, class...> class Convention>
|
template <auto Detour, template <class, class...> class Convention>
|
||||||
Result<Hook*> addHook(void* address) {
|
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
|
* Create a hook at an address. Call the original
|
||||||
* function by calling the original function –
|
* function by calling the original function –
|
||||||
* no trampoline needed. Also takes a displayName
|
* no trampoline needed. Also takes a displayName
|
||||||
* parameter to use for when visualizing the hook.
|
* 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
|
* the function to hook, i.e. gd_base + 0xXXXX
|
||||||
* @param detour Pointer to your detour function
|
* @param detour Pointer to your detour function
|
||||||
* @returns Successful result containing the
|
* @returns Successful result containing the
|
||||||
* Hook handle, errorful result with info on
|
* Hook handle, errorful result with info on
|
||||||
* error
|
* 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) {
|
Result<Hook*> addHook(std::string const& displayName, void* address) {
|
||||||
auto hook = Hook::create<Detour, Convention>((decltype(Detour))address, displayName, this);
|
auto hook =
|
||||||
return this->addHook(hook);
|
Hook::create<Detour, Convention>((decltype(Detour))address, displayName, this);
|
||||||
}
|
return this->addHook(hook);
|
||||||
|
}
|
||||||
Result<Hook*> addHook(Hook* hook);
|
|
||||||
|
|
||||||
|
Result<Hook*> addHook(Hook* hook);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable a hook owned by this Mod
|
* Enable a hook owned by this Mod
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> enableHook(Hook* hook);
|
Result<> enableHook(Hook* hook);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable a hook owned by this Mod
|
* Disable a hook owned by this Mod
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> disableHook(Hook* hook);
|
Result<> disableHook(Hook* hook);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a hook owned by this Mod
|
* Remove a hook owned by this Mod
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> removeHook(Hook* hook);
|
Result<> removeHook(Hook* hook);
|
||||||
|
@ -466,52 +465,52 @@ namespace geode {
|
||||||
* Write a patch at an address
|
* Write a patch at an address
|
||||||
* @param address The address to write into
|
* @param address The address to write into
|
||||||
* @param data The data to write there
|
* @param data The data to write there
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<Patch*> patch(void* address, byte_array data);
|
Result<Patch*> patch(void* address, byte_array data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a patch owned by this Mod
|
* Remove a patch owned by this Mod
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> unpatch(Patch* patch);
|
Result<> unpatch(Patch* patch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load this mod
|
* Load this mod
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> load();
|
Result<> load();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unload this mod
|
* Unload this mod
|
||||||
* @warning May crash if the mod doesn't
|
* @warning May crash if the mod doesn't
|
||||||
* properly handle unloading!
|
* properly handle unloading!
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> unload();
|
Result<> unload();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable this mod
|
* Enable this mod
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> enable();
|
Result<> enable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable this mod if it supports doing so
|
* Disable this mod if it supports doing so
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> disable();
|
Result<> disable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable & unload this mod (if supported),
|
* Disable & unload this mod (if supported),
|
||||||
* then delete the mod's .geode file.
|
* then delete the mod's .geode file.
|
||||||
* @returns Successful result on success,
|
* @returns Successful result on success,
|
||||||
* errorful result with info on error
|
* errorful result with info on error
|
||||||
*/
|
*/
|
||||||
Result<> uninstall();
|
Result<> uninstall();
|
||||||
|
@ -530,39 +529,38 @@ namespace geode {
|
||||||
*/
|
*/
|
||||||
Result<> resetDataStore();
|
Result<> resetDataStore();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether or not this Mod
|
* Check whether or not this Mod
|
||||||
* depends on another mod
|
* depends on another mod
|
||||||
*/
|
*/
|
||||||
bool depends(std::string const& id) const;
|
bool depends(std::string const& id) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether all the required
|
* Check whether all the required
|
||||||
* dependencies for this mod have
|
* dependencies for this mod have
|
||||||
* been loaded or not
|
* been loaded or not
|
||||||
* @returns True if the mod has unresolved
|
* @returns True if the mod has unresolved
|
||||||
* dependencies, false if not.
|
* dependencies, false if not.
|
||||||
*/
|
*/
|
||||||
bool hasUnresolvedDependencies() const;
|
bool hasUnresolvedDependencies() const;
|
||||||
/**
|
/**
|
||||||
* Update the state of each of the
|
* Update the state of each of the
|
||||||
* dependencies. Depending on if the
|
* dependencies. Depending on if the
|
||||||
* mod has unresolved dependencies,
|
* mod has unresolved dependencies,
|
||||||
* it will either be loaded or unloaded
|
* 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.
|
* dependencies, false if not.
|
||||||
*/
|
*/
|
||||||
bool updateDependencyStates();
|
bool updateDependencyStates();
|
||||||
/**
|
/**
|
||||||
* Get a list of all the unresolved
|
* Get a list of all the unresolved
|
||||||
* dependencies this mod has
|
* dependencies this mod has
|
||||||
* @returns List of all the unresolved
|
* @returns List of all the unresolved
|
||||||
* dependencies
|
* dependencies
|
||||||
*/
|
*/
|
||||||
std::vector<Dependency> getUnresolvedDependencies();
|
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);
|
return geode::Mod::get()->expandSpriteName(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ namespace {
|
||||||
struct derived##Parent {}; \
|
struct derived##Parent {}; \
|
||||||
Modify<derived<derived##Parent>, base> derived##Apply; \
|
Modify<derived<derived##Parent>, base> derived##Apply; \
|
||||||
struct GEODE_HIDDEN derived##Intermediate : base { \
|
struct GEODE_HIDDEN derived##Intermediate : base { \
|
||||||
geode::modifier::FieldIntermediate<base, \
|
mutable geode::modifier::FieldIntermediate<base, \
|
||||||
derived##Intermediate, \
|
derived##Intermediate, \
|
||||||
derived<derived##Parent> \
|
derived<derived##Parent> \
|
||||||
> m_fields; \
|
> m_fields; \
|
||||||
|
@ -45,7 +45,7 @@ struct derived;
|
||||||
namespace { \
|
namespace { \
|
||||||
Modify<derived, base> derived##Apply; \
|
Modify<derived, base> derived##Apply; \
|
||||||
struct GEODE_HIDDEN derived##Intermediate : base { \
|
struct GEODE_HIDDEN derived##Intermediate : base { \
|
||||||
geode::modifier::FieldIntermediate<base, \
|
mutable geode::modifier::FieldIntermediate<base, \
|
||||||
derived##Intermediate, \
|
derived##Intermediate, \
|
||||||
derived \
|
derived \
|
||||||
> m_fields; \
|
> 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/Hook.hpp>
|
||||||
#include <Geode/loader/Loader.hpp>
|
#include <Geode/loader/Loader.hpp>
|
||||||
#include <Geode/loader/Log.hpp>
|
#include <Geode/loader/Log.hpp>
|
||||||
#include <Geode/loader/Mod.hpp>
|
#include <Geode/loader/Mod.hpp>
|
||||||
#include <Geode/loader/Setting.hpp>
|
#include <Geode/loader/Setting.hpp>
|
||||||
|
#include <Geode/utils/JsonValidation.hpp>
|
||||||
#include <Geode/utils/conststring.hpp>
|
#include <Geode/utils/conststring.hpp>
|
||||||
#include <Geode/utils/file.hpp>
|
#include <Geode/utils/file.hpp>
|
||||||
#include <Geode/utils/JsonValidation.hpp>
|
|
||||||
#include <Geode/utils/map.hpp>
|
#include <Geode/utils/map.hpp>
|
||||||
|
#include <Geode/utils/ranges.hpp>
|
||||||
#include <Geode/utils/string.hpp>
|
#include <Geode/utils/string.hpp>
|
||||||
#include <Geode/utils/vector.hpp>
|
#include <Geode/utils/vector.hpp>
|
||||||
#include <Geode/utils/ranges.hpp>
|
|
||||||
#include <InternalMod.hpp>
|
#include <InternalMod.hpp>
|
||||||
#include <../support/zip_support/ZipUtils.h>
|
#include <about.hpp>
|
||||||
|
|
||||||
USE_GEODE_NAMESPACE();
|
USE_GEODE_NAMESPACE();
|
||||||
|
|
||||||
|
@ -70,22 +70,20 @@ Result<> Mod::loadSettings() {
|
||||||
if (auto sett = this->getSetting(key)) {
|
if (auto sett = this->getSetting(key)) {
|
||||||
// load its value
|
// load its value
|
||||||
if (!sett->load(value.json())) {
|
if (!sett->load(value.json())) {
|
||||||
return Err(
|
return Err("Unable to load value for setting \"" + key + "\"");
|
||||||
"Unable to load value for setting \"" +
|
|
||||||
key + "\""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log::log(
|
log::log(
|
||||||
Severity::Warning,
|
Severity::Warning, this,
|
||||||
this,
|
"Encountered unknown setting \"{}\" while loading "
|
||||||
"Encountered unknown setting \"{}\" while loading settings",
|
"settings",
|
||||||
key
|
key
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch(std::exception& e) {
|
catch (std::exception& e) {
|
||||||
return Err(std::string("Unable to parse settings: ") + e.what());
|
return Err(std::string("Unable to parse settings: ") + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,12 +92,14 @@ Result<> Mod::loadSettings() {
|
||||||
auto dsPath = m_saveDirPath / "ds.json";
|
auto dsPath = m_saveDirPath / "ds.json";
|
||||||
if (!ghc::filesystem::exists(dsPath)) {
|
if (!ghc::filesystem::exists(dsPath)) {
|
||||||
m_dataStore = m_info.m_defaultDataStore;
|
m_dataStore = m_info.m_defaultDataStore;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
auto dsData = utils::file::readString(dsPath);
|
auto dsData = utils::file::readString(dsPath);
|
||||||
if (!dsData) return dsData;
|
if (!dsData) return dsData;
|
||||||
try {
|
try {
|
||||||
m_dataStore = nlohmann::json::parse(dsData.value());
|
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());
|
return Err(std::string("Unable to parse datastore: ") + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,8 +151,7 @@ Result<> Mod::createTempDir() {
|
||||||
|
|
||||||
if (!unzip.fileExists(m_info.m_binaryName)) {
|
if (!unzip.fileExists(m_info.m_binaryName)) {
|
||||||
return Err<>(
|
return Err<>(
|
||||||
"Unable to find platform binary under the name \"" +
|
"Unable to find platform binary under the name \"" + m_info.m_binaryName + "\""
|
||||||
m_info.m_binaryName + "\""
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +161,7 @@ Result<> Mod::createTempDir() {
|
||||||
return Err<>("Unable to create temp directory for mods!");
|
return Err<>("Unable to create temp directory for mods!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto tempPath = ghc::filesystem::path(tempDir) / m_info.m_id;
|
auto tempPath = ghc::filesystem::path(tempDir) / m_info.m_id;
|
||||||
if (!ghc::filesystem::exists(tempPath) && !ghc::filesystem::create_directories(tempPath)) {
|
if (!ghc::filesystem::exists(tempPath) && !ghc::filesystem::create_directories(tempPath)) {
|
||||||
return Err<>("Unable to create temp directory");
|
return Err<>("Unable to create temp directory");
|
||||||
|
@ -172,11 +171,11 @@ Result<> Mod::createTempDir() {
|
||||||
for (auto file : unzip.getAllFiles()) {
|
for (auto file : unzip.getAllFiles()) {
|
||||||
auto path = ghc::filesystem::path(file);
|
auto path = ghc::filesystem::path(file);
|
||||||
if (path.has_parent_path()) {
|
if (path.has_parent_path()) {
|
||||||
if (
|
if (!ghc::filesystem::exists(tempPath / path.parent_path()) &&
|
||||||
!ghc::filesystem::exists(tempPath / path.parent_path()) &&
|
!ghc::filesystem::create_directories(tempPath / path.parent_path())) {
|
||||||
!ghc::filesystem::create_directories(tempPath / path.parent_path())
|
return Err<>(
|
||||||
) {
|
"Unable to create directories \"" + path.parent_path().string() + "\""
|
||||||
return Err<>("Unable to create directories \"" + path.parent_path().string() + "\"");
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
@ -184,10 +183,7 @@ Result<> Mod::createTempDir() {
|
||||||
if (!data || !size) {
|
if (!data || !size) {
|
||||||
return Err<>("Unable to read \"" + std::string(file) + "\"");
|
return Err<>("Unable to read \"" + std::string(file) + "\"");
|
||||||
}
|
}
|
||||||
auto wrt = utils::file::writeBinary(
|
auto wrt = utils::file::writeBinary(tempPath / file, byte_array(data, data + size));
|
||||||
tempPath / file,
|
|
||||||
byte_array(data, data + size)
|
|
||||||
);
|
|
||||||
if (!wrt) return Err<>("Unable to write \"" + file + "\": " + wrt.error());
|
if (!wrt) return Err<>("Unable to write \"" + file + "\": " + wrt.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,12 +193,14 @@ Result<> Mod::createTempDir() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<> Mod::load() {
|
Result<> Mod::load() {
|
||||||
if (m_loaded) {
|
if (m_loaded) {
|
||||||
return Ok<>();
|
return Ok<>();
|
||||||
}
|
}
|
||||||
#define RETURN_LOAD_ERR(str) \
|
#define RETURN_LOAD_ERR(str) \
|
||||||
{m_loadErrorInfo = str; \
|
{ \
|
||||||
return Err<>(m_loadErrorInfo);}
|
m_loadErrorInfo = str; \
|
||||||
|
return Err<>(m_loadErrorInfo); \
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_tempDirName.string().size()) {
|
if (!m_tempDirName.string().size()) {
|
||||||
auto err = this->createTempDir();
|
auto err = this->createTempDir();
|
||||||
|
@ -247,7 +245,7 @@ Result<> Mod::unload() {
|
||||||
if (!m_info.m_supportsUnloading) {
|
if (!m_info.m_supportsUnloading) {
|
||||||
return Err<>("Mod does not support unloading");
|
return Err<>("Mod does not support unloading");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_saveDataFunc) {
|
if (m_saveDataFunc) {
|
||||||
if (!m_saveDataFunc(m_saveDirPath.string().c_str())) {
|
if (!m_saveDataFunc(m_saveDirPath.string().c_str())) {
|
||||||
log::log(Severity::Error, this, "Mod save data function returned false");
|
log::log(Severity::Error, this, "Mod save data function returned false");
|
||||||
|
@ -286,7 +284,7 @@ Result<> Mod::enable() {
|
||||||
if (!m_loaded) {
|
if (!m_loaded) {
|
||||||
return Err<>("Mod is not loaded");
|
return Err<>("Mod is not loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_enableFunc) {
|
if (m_enableFunc) {
|
||||||
if (!m_enableFunc()) {
|
if (!m_enableFunc()) {
|
||||||
return Err<>("Mod enable function returned false");
|
return Err<>("Mod enable function returned false");
|
||||||
|
@ -361,55 +359,58 @@ bool Mod::isUninstalled() const {
|
||||||
|
|
||||||
bool Dependency::isUnresolved() const {
|
bool Dependency::isUnresolved() const {
|
||||||
return m_required &&
|
return m_required &&
|
||||||
(m_state == ModResolveState::Unloaded ||
|
(m_state == ModResolveState::Unloaded || m_state == ModResolveState::Unresolved ||
|
||||||
m_state == ModResolveState::Unresolved ||
|
m_state == ModResolveState::Disabled);
|
||||||
m_state == ModResolveState::Disabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mod::updateDependencyStates() {
|
bool Mod::updateDependencyStates() {
|
||||||
bool hasUnresolved = false;
|
bool hasUnresolved = false;
|
||||||
for (auto & dep : m_info.m_dependencies) {
|
for (auto& dep : m_info.m_dependencies) {
|
||||||
if (!dep.m_mod) {
|
if (!dep.m_mod) {
|
||||||
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
dep.m_mod = Loader::get()->getLoadedMod(dep.m_id);
|
||||||
}
|
}
|
||||||
if (dep.m_mod) {
|
if (dep.m_mod) {
|
||||||
dep.m_mod->updateDependencyStates();
|
dep.m_mod->updateDependencyStates();
|
||||||
|
|
||||||
if (dep.m_mod->hasUnresolvedDependencies()) {
|
if (dep.m_mod->hasUnresolvedDependencies()) {
|
||||||
dep.m_state = ModResolveState::Unresolved;
|
dep.m_state = ModResolveState::Unresolved;
|
||||||
} else {
|
}
|
||||||
if (!dep.m_mod->m_resolved) {
|
else {
|
||||||
dep.m_mod->m_resolved = true;
|
if (!dep.m_mod->m_resolved) {
|
||||||
dep.m_state = ModResolveState::Resolved;
|
dep.m_mod->m_resolved = true;
|
||||||
|
dep.m_state = ModResolveState::Resolved;
|
||||||
auto r = dep.m_mod->load();
|
auto r = dep.m_mod->load();
|
||||||
if (!r) {
|
if (!r) {
|
||||||
dep.m_state = ModResolveState::Unloaded;
|
dep.m_state = ModResolveState::Unloaded;
|
||||||
log::log(Severity::Error, dep.m_mod, "{}", r.error());
|
log::log(Severity::Error, dep.m_mod, "{}", r.error());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto r = dep.m_mod->enable();
|
auto r = dep.m_mod->enable();
|
||||||
if (!r) {
|
if (!r) {
|
||||||
dep.m_state = ModResolveState::Disabled;
|
dep.m_state = ModResolveState::Disabled;
|
||||||
log::log(Severity::Error, dep.m_mod, "{}", r.error());
|
log::log(Severity::Error, dep.m_mod, "{}", r.error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (dep.m_mod->isEnabled()) {
|
else {
|
||||||
dep.m_state = ModResolveState::Loaded;
|
if (dep.m_mod->isEnabled()) {
|
||||||
} else {
|
dep.m_state = ModResolveState::Loaded;
|
||||||
dep.m_state = ModResolveState::Disabled;
|
}
|
||||||
}
|
else {
|
||||||
}
|
dep.m_state = ModResolveState::Disabled;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
dep.m_state = ModResolveState::Unloaded;
|
}
|
||||||
}
|
}
|
||||||
if (dep.isUnresolved()) {
|
else {
|
||||||
m_resolved = false;
|
dep.m_state = ModResolveState::Unloaded;
|
||||||
|
}
|
||||||
|
if (dep.isUnresolved()) {
|
||||||
|
m_resolved = false;
|
||||||
(void)this->unload();
|
(void)this->unload();
|
||||||
hasUnresolved = true;
|
hasUnresolved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasUnresolved && !m_resolved) {
|
if (!hasUnresolved && !m_resolved) {
|
||||||
log::debug("All dependencies for {} found", m_info.m_id);
|
log::debug("All dependencies for {} found", m_info.m_id);
|
||||||
m_resolved = true;
|
m_resolved = true;
|
||||||
|
@ -420,12 +421,13 @@ bool Mod::updateDependencyStates() {
|
||||||
log::error("{} Error loading: {}", this, r.error());
|
log::error("{} Error loading: {}", this, r.error());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto r = this->enable();
|
auto r = this->enable();
|
||||||
if (!r) {
|
if (!r) {
|
||||||
log::error("{} Error enabling: {}", this, r.error());
|
log::error("{} Error enabling: {}", this, r.error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
log::debug("Resolved {}, however not loading it as it is disabled", m_info.m_id);
|
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 {
|
bool Mod::hasUnresolvedDependencies() const {
|
||||||
for (auto const& dep : m_info.m_dependencies) {
|
for (auto const& dep : m_info.m_dependencies) {
|
||||||
if (dep.isUnresolved()) {
|
if (dep.isUnresolved()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Dependency> Mod::getUnresolvedDependencies() {
|
std::vector<Dependency> Mod::getUnresolvedDependencies() {
|
||||||
std::vector<Dependency> res;
|
std::vector<Dependency> res;
|
||||||
for (auto const& dep : m_info.m_dependencies) {
|
for (auto const& dep : m_info.m_dependencies) {
|
||||||
if (dep.isUnresolved()) {
|
if (dep.isUnresolved()) {
|
||||||
res.push_back(dep);
|
res.push_back(dep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,14 +534,13 @@ std::vector<Hook*> Mod::getHooks() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mod::depends(std::string const& id) const {
|
bool Mod::depends(std::string const& id) const {
|
||||||
return utils::ranges::contains(
|
return utils::ranges::contains(m_info.m_dependencies, [id](Dependency const& t) {
|
||||||
m_info.m_dependencies,
|
return t.m_id == id;
|
||||||
[id](Dependency const& t) { return t.m_id == id; }
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Mod::expandSpriteName(const char* name) {
|
char const* Mod::expandSpriteName(char const* name) {
|
||||||
static std::unordered_map<std::string, const char*> expanded = {};
|
static std::unordered_map<std::string, char const*> expanded = {};
|
||||||
if (expanded.count(name)) {
|
if (expanded.count(name)) {
|
||||||
return expanded[name];
|
return expanded[name];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue