mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-23 21:04:14 -04:00
Merge branch 'main' of https://github.com/geode-sdk/geode into copy-mods
This commit is contained in:
commit
69a480b341
107 changed files with 15200 additions and 569 deletions
CHANGELOG.mdCMakeLists.txtVERSION
installer/windows/Language Files
loader
include/Geode
c++stl
gnustl.hpp
gnustl
alloc_traits.hallocator.hc++allocator.hppc++config-arm64.hc++config-armeabi-v7a.hc++config.hexception_defines.h
ext
functional_hash.hhash_bytes.hhash_specialization.hpphashtable.hhashtable_policy.hmemoryfwd.hnew_allocator.hptr_traits.hrange_access.hstl_function.htype_traits.hunordered_map.hunordered_map.hppunordered_set.hunordered_set.hppcocos
base_nodes
cocoa
draw_nodes
label_nodes
platform/win32
robtop/special_nodes
loader
ui
utils
launcher/windows
resources
src
53
CHANGELOG.md
53
CHANGELOG.md
|
@ -1,5 +1,49 @@
|
|||
# Geode Changelog
|
||||
|
||||
## v3.9.0
|
||||
* Many changes to the settings ui (#1108)
|
||||
* Fuzzy search is now more reasonable
|
||||
* Add `CCNode::getChildByType` utility method, replacing the `getChildOfType` util (0089d13, c8aa2e3, 5f70080)
|
||||
* Add `geode::utils::string::caseInsensitiveCompare` (f3d38a7)
|
||||
* Now local mods are ordered correctly
|
||||
* Add `CCCallFuncExt` util, which accepts lambdas and such (d1053b1, 1d31576)
|
||||
* Add missing `m_nExtraKerning` to `CCLabelBMFont` (#1088)
|
||||
* Truncate numbers in `numToAbbreviatedString`, no longer rounding up (82e703b)
|
||||
* Fix string settings not having their character filters applied (6d0b583)
|
||||
* Error on `numFromString` when string has left over data (d4ca28c)
|
||||
* Change positioning of MenuLayer `top-right-menu` menu (6d2557b)
|
||||
* Add `SceneManager::getPersistedNodes` (5009caa)
|
||||
* Fix android `std::unordered_map` copy constructor (67f59e7)
|
||||
* Fix crash on Linux when piping output to terminal (8ecb1c5)
|
||||
* Fix crash when geode menu is disabled (b69f810)
|
||||
* Fix infinite recursion in `WeakRef` hashing (d68e358)
|
||||
|
||||
## v3.8.1
|
||||
* Fix CCLightning header
|
||||
* Fix server query default value (8be97b7)
|
||||
* Fix importance resolving in disabled mods (d40ba6d)
|
||||
|
||||
## v3.8.0
|
||||
* Add Modtober integration! For more about Modtober, join [the GDP Discord server](https://discord.gg/gd-programming-646101505417674758) (964624b)
|
||||
* Add `Popup::CloseEvent` (6270e1c)
|
||||
* Add `openSettingsPopup` overload that returns the created `Popup` (dc8d271)
|
||||
* Fix `CCNode::querySelector` logspamming (b53759f)
|
||||
* Fix `followThunkFunction` following through into hook handlers (ad26357)
|
||||
|
||||
## v3.7.1
|
||||
* Fix crash with saving older custom settings (c3e7f23)
|
||||
* Add missing CCDrawNode::drawRect overload (145adb2)
|
||||
|
||||
## v3.7.0
|
||||
* Add persistent directory for mods to save data that won't be deleted when the mod/Geode is uninstalled (68ab475)
|
||||
* Fix touch priority issues in the settings popup (b3d5474)
|
||||
* Fix settings with custom types not being saved & loaded properly (f0b6a70)
|
||||
|
||||
## v3.6.1
|
||||
* Fix modrm rip relative instruction displacement saving the clobbered register (ddfe8e2)
|
||||
* Fix `DataSaved` and `DataLoaded` events (8615bbd, 43adb35)
|
||||
* Fix file settings mixed separators (1281c76)
|
||||
|
||||
## v3.6.0
|
||||
* Major rework of the entire settings system with lots of new features; see the [docs page](https://docs.geode-sdk.org/mods/settings) for more
|
||||
* Rework JSON validation; now uses the `JsonExpectedValue` class with the `checkJson` helper (89d1a51)
|
||||
|
@ -17,9 +61,16 @@
|
|||
* Fix issues with file dialogs on Windows (62b6241, 971e3fb)
|
||||
* Fix PCH issues (aedd986)
|
||||
* Mod incompatibilities may now be platform-specific (9f1c70a)
|
||||
* Show appropriate popup for unavailable mods (6944f80, 30dc70c)
|
||||
* Add support for description as a default value on file settings (75186f6)
|
||||
* Remove early ub related to console (54ff48c)
|
||||
* Temporary workaround for Wine crash due to console (dc170d7)
|
||||
* Check also for incompatibilities with newly installed mods when downloading (9115091)
|
||||
* Make cocos geometry classes constexpr (db8a6c8)
|
||||
* Fix rip displacement issues when hooking some functions on Windows (175dc27)
|
||||
|
||||
## v3.5.0
|
||||
* Move CCLighting to cocos headers (#1036)
|
||||
* Move CCLightning to cocos headers (#1036)
|
||||
* Add new `gd::string` constructor (bae22b4)
|
||||
* Use `getChildren` instead of member in `getChildByID` (fe730ed)
|
||||
* Fix sprite order in `CCMenuItemExt::createToggler` (d729a12, 59a0ade)
|
||||
|
|
|
@ -193,7 +193,12 @@ if (NOT DEFINED GEODE_GD_VERSION)
|
|||
set(GEODE_COMP_GD_VERSION 22060)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} INTERFACE GEODE_GD_VERSION=${GEODE_GD_VERSION} GEODE_COMP_GD_VERSION=${GEODE_COMP_GD_VERSION})
|
||||
target_compile_definitions(
|
||||
${PROJECT_NAME} INTERFACE
|
||||
GEODE_GD_VERSION=${GEODE_GD_VERSION}
|
||||
GEODE_COMP_GD_VERSION=${GEODE_COMP_GD_VERSION}
|
||||
GEODE_GD_VERSION_STRING="${GEODE_GD_VERSION}"
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
# This allows you to compile in debug mode
|
||||
|
@ -212,6 +217,11 @@ if (WIN32)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# force an error on a missing return type, as this is unfortunately a common mistake people make
|
||||
target_compile_options(${PROJECT_NAME} INTERFACE -Werror=return-type)
|
||||
endif()
|
||||
|
||||
# if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
# set_property(TARGET ${PROJECT_NAME} PROPERTY LINKER_TYPE LLD)
|
||||
# target_link_options(${PROJECT_NAME} INTERFACE -fuse-ld=lld)
|
||||
|
@ -256,7 +266,7 @@ if (DEFINED GEODE_TULIPHOOK_REPO_PATH)
|
|||
message(STATUS "Using ${GEODE_TULIPHOOK_REPO_PATH} for TulipHook")
|
||||
add_subdirectory(${GEODE_TULIPHOOK_REPO_PATH} ${GEODE_TULIPHOOK_REPO_PATH}/build)
|
||||
else()
|
||||
CPMAddPackage("gh:geode-sdk/TulipHook#c8a445c")
|
||||
CPMAddPackage("gh:geode-sdk/TulipHook#d1d9559")
|
||||
endif()
|
||||
set(CMAKE_WARN_DEPRECATED ON CACHE BOOL "" FORCE)
|
||||
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
3.6.0
|
||||
3.9.0
|
||||
|
|
|
@ -8,8 +8,8 @@ ${LangFileString} MUI_UNTEXT_WELCOME_INFO_TEXT "Le programme d'installation vous
|
|||
; installer
|
||||
|
||||
${LangFileString} GEODE_TEXT_GD_MISSING "$\r$\n$\r$\nGeometry Dash n'est pas installé sur ce chemin !"
|
||||
${LangFileString} GEODE_TEXT_GD_OLD "$\r$\n$\r$\nYour version of Geometry Dash is too old for this version of Geode!"
|
||||
${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "This path has other mods installed!$\r$\nThey will be overwritten by Geode. (the dll trademark)"
|
||||
${LangFileString} GEODE_TEXT_GD_OLD "$\r$\n$\r$\nVotre version de Geometry Dash est trop ancienne pour cette version de Geode !"
|
||||
${LangFileString} GEODE_TEXT_MOD_LOADER_ALREADY_INSTALLED "Ce chemin a d'autres mods installés !$\r$\nIls seront écrasés par Geode. (the dll trademark)"
|
||||
|
||||
; uninstaller
|
||||
|
||||
|
|
|
@ -15,6 +15,12 @@ namespace geode::base {
|
|||
#if defined(GEODE_IS_ANDROID)
|
||||
|
||||
#include "gnustl-map.hpp"
|
||||
#include "gnustl/unordered_map.hpp"
|
||||
#include "gnustl/unordered_set.hpp"
|
||||
#include "gnustl/hash_specialization.hpp"
|
||||
#undef _GLIBCXX_RELEASE
|
||||
#undef __GLIBCXX__
|
||||
#undef _GLIBCXX_USE_DUAL_ABI
|
||||
|
||||
namespace gd {
|
||||
using namespace geode::stl;
|
||||
|
@ -686,11 +692,11 @@ namespace gd {
|
|||
template <class V>
|
||||
using set = void*[6];
|
||||
|
||||
template <class K, class V>
|
||||
using unordered_map = void*[7];
|
||||
template <class Key, class Tp, class Hash = geode::stl::hash<Key>, class Pred = geode::stl::equal_to<Key>, class Alloc = std::allocator<std::pair<const Key, Tp>>>
|
||||
using unordered_map = geode::stl::unordered_map<Key, Tp, Hash, Pred, Alloc>;
|
||||
|
||||
template <class V>
|
||||
using unordered_set = void*[7];
|
||||
template <class Value, class Hash = geode::stl::hash<Value>, class Pred = geode::stl::equal_to<Value>, class Alloc = std::allocator<Value>>
|
||||
using unordered_set = geode::stl::unordered_set<Value, Hash, Pred, Alloc>;
|
||||
};
|
||||
|
||||
#elif defined(GEODE_IS_IOS)
|
||||
|
|
531
loader/include/Geode/c++stl/gnustl/alloc_traits.h
Normal file
531
loader/include/Geode/c++stl/gnustl/alloc_traits.h
Normal file
|
@ -0,0 +1,531 @@
|
|||
// Allocator traits -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/alloc_traits.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{memory}
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
#include "memoryfwd.h"
|
||||
#include "ptr_traits.h"
|
||||
#include "type_traits.h"
|
||||
#include "ext/numeric_traits.h"
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
template<typename _Alloc, typename _Tp>
|
||||
class __alloctr_rebind_helper
|
||||
{
|
||||
template<typename _Alloc2, typename _Tp2>
|
||||
static constexpr std::true_type
|
||||
_S_chk(typename _Alloc2::template rebind<_Tp2>::other*);
|
||||
|
||||
template<typename, typename>
|
||||
static constexpr std::false_type
|
||||
_S_chk(...);
|
||||
|
||||
public:
|
||||
using __type = decltype(_S_chk<_Alloc, _Tp>(nullptr));
|
||||
};
|
||||
|
||||
template<typename _Alloc, typename _Tp,
|
||||
bool = __alloctr_rebind_helper<_Alloc, _Tp>::__type::value>
|
||||
struct __alloctr_rebind;
|
||||
|
||||
template<typename _Alloc, typename _Tp>
|
||||
struct __alloctr_rebind<_Alloc, _Tp, true>
|
||||
{
|
||||
typedef typename _Alloc::template rebind<_Tp>::other __type;
|
||||
};
|
||||
|
||||
template<template<typename, typename...> class _Alloc, typename _Tp,
|
||||
typename _Up, typename... _Args>
|
||||
struct __alloctr_rebind<_Alloc<_Up, _Args...>, _Tp, false>
|
||||
{
|
||||
typedef _Alloc<_Tp, _Args...> __type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Uniform interface to all allocator types.
|
||||
* @ingroup allocators
|
||||
*/
|
||||
template<typename _Alloc>
|
||||
struct allocator_traits
|
||||
{
|
||||
/// The allocator type
|
||||
typedef _Alloc allocator_type;
|
||||
/// The allocated type
|
||||
typedef typename _Alloc::value_type value_type;
|
||||
|
||||
#define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \
|
||||
private: \
|
||||
template<typename _Tp> \
|
||||
static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \
|
||||
static _ALT _S_##_NTYPE##_helper(...); \
|
||||
typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \
|
||||
public:
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(pointer, value_type*)
|
||||
|
||||
/**
|
||||
* @brief The allocator's pointer type.
|
||||
*
|
||||
* @c Alloc::pointer if that type exists, otherwise @c value_type*
|
||||
*/
|
||||
typedef __pointer pointer;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_pointer,
|
||||
typename pointer_traits<pointer>::template rebind<const value_type>)
|
||||
|
||||
/**
|
||||
* @brief The allocator's const pointer type.
|
||||
*
|
||||
* @c Alloc::const_pointer if that type exists, otherwise
|
||||
* <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
|
||||
*/
|
||||
typedef __const_pointer const_pointer;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(void_pointer,
|
||||
typename pointer_traits<pointer>::template rebind<void>)
|
||||
|
||||
/**
|
||||
* @brief The allocator's void pointer type.
|
||||
*
|
||||
* @c Alloc::void_pointer if that type exists, otherwise
|
||||
* <tt> pointer_traits<pointer>::rebind<void> </tt>
|
||||
*/
|
||||
typedef __void_pointer void_pointer;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(const_void_pointer,
|
||||
typename pointer_traits<pointer>::template rebind<const void>)
|
||||
|
||||
/**
|
||||
* @brief The allocator's const void pointer type.
|
||||
*
|
||||
* @c Alloc::const_void_pointer if that type exists, otherwise
|
||||
* <tt> pointer_traits<pointer>::rebind<const void> </tt>
|
||||
*/
|
||||
typedef __const_void_pointer const_void_pointer;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(difference_type,
|
||||
typename pointer_traits<pointer>::difference_type)
|
||||
|
||||
/**
|
||||
* @brief The allocator's difference type
|
||||
*
|
||||
* @c Alloc::difference_type if that type exists, otherwise
|
||||
* <tt> pointer_traits<pointer>::difference_type </tt>
|
||||
*/
|
||||
typedef __difference_type difference_type;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(size_type,
|
||||
typename std::make_unsigned<difference_type>::type)
|
||||
|
||||
/**
|
||||
* @brief The allocator's size type
|
||||
*
|
||||
* @c Alloc::size_type if that type exists, otherwise
|
||||
* <tt> make_unsigned<difference_type>::type </tt>
|
||||
*/
|
||||
typedef __size_type size_type;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_copy_assignment,
|
||||
std::false_type)
|
||||
|
||||
/**
|
||||
* @brief How the allocator is propagated on copy assignment
|
||||
*
|
||||
* @c Alloc::propagate_on_container_copy_assignment if that type exists,
|
||||
* otherwise @c false_type
|
||||
*/
|
||||
typedef __propagate_on_container_copy_assignment
|
||||
propagate_on_container_copy_assignment;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_move_assignment,
|
||||
std::false_type)
|
||||
|
||||
/**
|
||||
* @brief How the allocator is propagated on move assignment
|
||||
*
|
||||
* @c Alloc::propagate_on_container_move_assignment if that type exists,
|
||||
* otherwise @c false_type
|
||||
*/
|
||||
typedef __propagate_on_container_move_assignment
|
||||
propagate_on_container_move_assignment;
|
||||
|
||||
_GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap,
|
||||
std::false_type)
|
||||
|
||||
/**
|
||||
* @brief How the allocator is propagated on swap
|
||||
*
|
||||
* @c Alloc::propagate_on_container_swap if that type exists,
|
||||
* otherwise @c false_type
|
||||
*/
|
||||
typedef __propagate_on_container_swap propagate_on_container_swap;
|
||||
|
||||
#undef _GLIBCXX_ALLOC_TR_NESTED_TYPE
|
||||
|
||||
template<typename _Tp>
|
||||
using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;
|
||||
template<typename _Tp>
|
||||
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
|
||||
|
||||
private:
|
||||
template<typename _Alloc2>
|
||||
struct __allocate_helper
|
||||
{
|
||||
template<typename _Alloc3,
|
||||
typename = decltype(std::declval<_Alloc3*>()->allocate(
|
||||
std::declval<size_type>(),
|
||||
std::declval<const_void_pointer>()))>
|
||||
static std::true_type __test(int);
|
||||
|
||||
template<typename>
|
||||
static std::false_type __test(...);
|
||||
|
||||
using type = decltype(__test<_Alloc>(0));
|
||||
};
|
||||
|
||||
template<typename _Alloc2>
|
||||
using __has_allocate = typename __allocate_helper<_Alloc2>::type;
|
||||
|
||||
template<typename _Alloc2,
|
||||
typename = _Require<__has_allocate<_Alloc2>>>
|
||||
static pointer
|
||||
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint)
|
||||
{ return __a.allocate(__n, __hint); }
|
||||
|
||||
template<typename _Alloc2, typename _UnusedHint,
|
||||
typename = _Require<__not_<__has_allocate<_Alloc2>>>>
|
||||
static pointer
|
||||
_S_allocate(_Alloc2& __a, size_type __n, _UnusedHint)
|
||||
{ return __a.allocate(__n); }
|
||||
|
||||
template<typename _Tp, typename... _Args>
|
||||
struct __construct_helper
|
||||
{
|
||||
template<typename _Alloc2,
|
||||
typename = decltype(std::declval<_Alloc2*>()->construct(
|
||||
std::declval<_Tp*>(), std::declval<_Args>()...))>
|
||||
static std::true_type __test(int);
|
||||
|
||||
template<typename>
|
||||
static std::false_type __test(...);
|
||||
|
||||
using type = decltype(__test<_Alloc>(0));
|
||||
};
|
||||
|
||||
template<typename _Tp, typename... _Args>
|
||||
using __has_construct
|
||||
= typename __construct_helper<_Tp, _Args...>::type;
|
||||
|
||||
template<typename _Tp, typename... _Args>
|
||||
static _Require<__has_construct<_Tp, _Args...>>
|
||||
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
|
||||
{ __a.construct(__p, std::forward<_Args>(__args)...); }
|
||||
|
||||
template<typename _Tp, typename... _Args>
|
||||
static
|
||||
_Require<std::conjunction<__not_<__has_construct<_Tp, _Args...>>,
|
||||
std::is_constructible<_Tp, _Args...>>>
|
||||
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
|
||||
{ ::new((void*)__p) _Tp(std::forward<_Args>(__args)...); }
|
||||
|
||||
template<typename _Tp>
|
||||
struct __destroy_helper
|
||||
{
|
||||
template<typename _Alloc2,
|
||||
typename = decltype(std::declval<_Alloc2*>()->destroy(
|
||||
std::declval<_Tp*>()))>
|
||||
static std::true_type __test(int);
|
||||
|
||||
template<typename>
|
||||
static std::false_type __test(...);
|
||||
|
||||
using type = decltype(__test<_Alloc>(0));
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
using __has_destroy = typename __destroy_helper<_Tp>::type;
|
||||
|
||||
template<typename _Tp>
|
||||
static _Require<__has_destroy<_Tp>>
|
||||
_S_destroy(_Alloc& __a, _Tp* __p)
|
||||
{ __a.destroy(__p); }
|
||||
|
||||
template<typename _Tp>
|
||||
static _Require<__not_<__has_destroy<_Tp>>>
|
||||
_S_destroy(_Alloc&, _Tp* __p)
|
||||
{ __p->~_Tp(); }
|
||||
|
||||
template<typename _Alloc2>
|
||||
struct __maxsize_helper
|
||||
{
|
||||
template<typename _Alloc3,
|
||||
typename = decltype(std::declval<_Alloc3*>()->max_size())>
|
||||
static std::true_type __test(int);
|
||||
|
||||
template<typename>
|
||||
static std::false_type __test(...);
|
||||
|
||||
using type = decltype(__test<_Alloc2>(0));
|
||||
};
|
||||
|
||||
template<typename _Alloc2>
|
||||
using __has_max_size = typename __maxsize_helper<_Alloc2>::type;
|
||||
|
||||
template<typename _Alloc2,
|
||||
typename = _Require<__has_max_size<_Alloc2>>>
|
||||
static size_type
|
||||
_S_max_size(_Alloc2& __a, int)
|
||||
{ return __a.max_size(); }
|
||||
|
||||
template<typename _Alloc2,
|
||||
typename = _Require<__not_<__has_max_size<_Alloc2>>>>
|
||||
static size_type
|
||||
_S_max_size(_Alloc2&, ...)
|
||||
{ return __gnu_cxx::__numeric_traits<size_type>::__max; }
|
||||
|
||||
template<typename _Alloc2>
|
||||
struct __select_helper
|
||||
{
|
||||
template<typename _Alloc3, typename
|
||||
= decltype(std::declval<_Alloc3*>()
|
||||
->select_on_container_copy_construction())>
|
||||
static std::true_type __test(int);
|
||||
|
||||
template<typename>
|
||||
static std::false_type __test(...);
|
||||
|
||||
using type = decltype(__test<_Alloc2>(0));
|
||||
};
|
||||
|
||||
template<typename _Alloc2>
|
||||
using __has_soccc = typename __select_helper<_Alloc2>::type;
|
||||
|
||||
template<typename _Alloc2,
|
||||
typename = _Require<__has_soccc<_Alloc2>>>
|
||||
static _Alloc2
|
||||
_S_select(_Alloc2& __a, int)
|
||||
{ return __a.select_on_container_copy_construction(); }
|
||||
|
||||
template<typename _Alloc2,
|
||||
typename = _Require<__not_<__has_soccc<_Alloc2>>>>
|
||||
static _Alloc2
|
||||
_S_select(_Alloc2& __a, ...)
|
||||
{ return __a; }
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Allocate memory.
|
||||
* @param __a An allocator.
|
||||
* @param __n The number of objects to allocate space for.
|
||||
*
|
||||
* Calls @c a.allocate(n)
|
||||
*/
|
||||
static pointer
|
||||
allocate(_Alloc& __a, size_type __n)
|
||||
{ return __a.allocate(__n); }
|
||||
|
||||
/**
|
||||
* @brief Allocate memory.
|
||||
* @param __a An allocator.
|
||||
* @param __n The number of objects to allocate space for.
|
||||
* @param __hint Aid to locality.
|
||||
* @return Memory of suitable size and alignment for @a n objects
|
||||
* of type @c value_type
|
||||
*
|
||||
* Returns <tt> a.allocate(n, hint) </tt> if that expression is
|
||||
* well-formed, otherwise returns @c a.allocate(n)
|
||||
*/
|
||||
static pointer
|
||||
allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
|
||||
{ return _S_allocate(__a, __n, __hint); }
|
||||
|
||||
/**
|
||||
* @brief Deallocate memory.
|
||||
* @param __a An allocator.
|
||||
* @param __p Pointer to the memory to deallocate.
|
||||
* @param __n The number of objects space was allocated for.
|
||||
*
|
||||
* Calls <tt> a.deallocate(p, n) </tt>
|
||||
*/
|
||||
static void deallocate(_Alloc& __a, pointer __p, size_type __n)
|
||||
{ __a.deallocate(__p, __n); }
|
||||
|
||||
/**
|
||||
* @brief Construct an object of type @a _Tp
|
||||
* @param __a An allocator.
|
||||
* @param __p Pointer to memory of suitable size and alignment for Tp
|
||||
* @param __args Constructor arguments.
|
||||
*
|
||||
* Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
|
||||
* if that expression is well-formed, otherwise uses placement-new
|
||||
* to construct an object of type @a _Tp at location @a __p from the
|
||||
* arguments @a __args...
|
||||
*/
|
||||
template<typename _Tp, typename... _Args>
|
||||
static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
|
||||
-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
|
||||
{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
|
||||
|
||||
/**
|
||||
* @brief Destroy an object of type @a _Tp
|
||||
* @param __a An allocator.
|
||||
* @param __p Pointer to the object to destroy
|
||||
*
|
||||
* Calls @c __a.destroy(__p) if that expression is well-formed,
|
||||
* otherwise calls @c __p->~_Tp()
|
||||
*/
|
||||
template <class _Tp>
|
||||
static void destroy(_Alloc& __a, _Tp* __p)
|
||||
{ _S_destroy(__a, __p); }
|
||||
|
||||
/**
|
||||
* @brief The maximum supported allocation size
|
||||
* @param __a An allocator.
|
||||
* @return @c __a.max_size() or @c numeric_limits<size_type>::max()
|
||||
*
|
||||
* Returns @c __a.max_size() if that expression is well-formed,
|
||||
* otherwise returns @c numeric_limits<size_type>::max()
|
||||
*/
|
||||
static size_type max_size(const _Alloc& __a) noexcept
|
||||
{ return _S_max_size(__a, 0); }
|
||||
|
||||
/**
|
||||
* @brief Obtain an allocator to use when copying a container.
|
||||
* @param __rhs An allocator.
|
||||
* @return @c __rhs.select_on_container_copy_construction() or @a __rhs
|
||||
*
|
||||
* Returns @c __rhs.select_on_container_copy_construction() if that
|
||||
* expression is well-formed, otherwise returns @a __rhs
|
||||
*/
|
||||
static _Alloc
|
||||
select_on_container_copy_construction(const _Alloc& __rhs)
|
||||
{ return _S_select(__rhs, 0); }
|
||||
};
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void
|
||||
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, std::true_type)
|
||||
{ __one = __two; }
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void
|
||||
__do_alloc_on_copy(_Alloc&, const _Alloc&, std::false_type)
|
||||
{ }
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __alloc_on_copy(_Alloc& __one, const _Alloc& __two)
|
||||
{
|
||||
typedef allocator_traits<_Alloc> __traits;
|
||||
typedef typename __traits::propagate_on_container_copy_assignment __pocca;
|
||||
__do_alloc_on_copy(__one, __two, __pocca());
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
inline _Alloc __alloc_on_copy(const _Alloc& __a)
|
||||
{
|
||||
typedef allocator_traits<_Alloc> __traits;
|
||||
return __traits::select_on_container_copy_construction(__a);
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, std::true_type)
|
||||
{ __one = std::move(__two); }
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __do_alloc_on_move(_Alloc&, _Alloc&, std::false_type)
|
||||
{ }
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __alloc_on_move(_Alloc& __one, _Alloc& __two)
|
||||
{
|
||||
typedef allocator_traits<_Alloc> __traits;
|
||||
typedef typename __traits::propagate_on_container_move_assignment __pocma;
|
||||
__do_alloc_on_move(__one, __two, __pocma());
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, std::true_type)
|
||||
{
|
||||
using std::swap;
|
||||
swap(__one, __two);
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __do_alloc_on_swap(_Alloc&, _Alloc&, std::false_type)
|
||||
{ }
|
||||
|
||||
template<typename _Alloc>
|
||||
inline void __alloc_on_swap(_Alloc& __one, _Alloc& __two)
|
||||
{
|
||||
typedef allocator_traits<_Alloc> __traits;
|
||||
typedef typename __traits::propagate_on_container_swap __pocs;
|
||||
__do_alloc_on_swap(__one, __two, __pocs());
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
class __is_copy_insertable_impl
|
||||
{
|
||||
typedef allocator_traits<_Alloc> _Traits;
|
||||
|
||||
template<typename _Up, typename
|
||||
= decltype(_Traits::construct(std::declval<_Alloc&>(),
|
||||
std::declval<_Up*>(),
|
||||
std::declval<const _Up&>()))>
|
||||
static std::true_type
|
||||
_M_select(int);
|
||||
|
||||
template<typename _Up>
|
||||
static std::false_type
|
||||
_M_select(...);
|
||||
|
||||
public:
|
||||
typedef decltype(_M_select<typename _Alloc::value_type>(0)) type;
|
||||
};
|
||||
|
||||
// true if _Alloc::value_type is CopyInsertable into containers using _Alloc
|
||||
template<typename _Alloc>
|
||||
struct __is_copy_insertable
|
||||
: __is_copy_insertable_impl<_Alloc>::type
|
||||
{ };
|
||||
|
||||
// std::allocator<_Tp> just requires CopyConstructible
|
||||
template<typename _Tp>
|
||||
struct __is_copy_insertable<allocator<_Tp>>
|
||||
: std::is_copy_constructible<_Tp>
|
||||
{ };
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif
|
220
loader/include/Geode/c++stl/gnustl/allocator.h
Normal file
220
loader/include/Geode/c++stl/gnustl/allocator.h
Normal file
|
@ -0,0 +1,220 @@
|
|||
// Allocators -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-1997
|
||||
* Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Silicon Graphics makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/** @file bits/allocator.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{memory}
|
||||
*/
|
||||
|
||||
#ifndef _ALLOCATOR_H
|
||||
#define _ALLOCATOR_H 1
|
||||
|
||||
#include "c++allocator.hpp" // Define the base class to std::allocator.
|
||||
#include "memoryfwd.h"
|
||||
#if __cplusplus >= 201103L
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/**
|
||||
* @addtogroup allocators
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// allocator<void> specialization.
|
||||
template<>
|
||||
class allocator<void>
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef void* pointer;
|
||||
typedef const void* const_pointer;
|
||||
typedef void value_type;
|
||||
|
||||
template<typename _Tp1>
|
||||
struct rebind
|
||||
{ typedef allocator<_Tp1> other; };
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2103. std::allocator propagate_on_container_move_assignment
|
||||
typedef std::true_type propagate_on_container_move_assignment;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The @a standard allocator, as per [20.4].
|
||||
*
|
||||
* See http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt04ch11.html
|
||||
* for further details.
|
||||
*
|
||||
* @tparam _Tp Type of allocated object.
|
||||
*/
|
||||
template<typename _Tp>
|
||||
class allocator: public __allocator_base<_Tp>
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef _Tp* pointer;
|
||||
typedef const _Tp* const_pointer;
|
||||
typedef _Tp& reference;
|
||||
typedef const _Tp& const_reference;
|
||||
typedef _Tp value_type;
|
||||
|
||||
template<typename _Tp1>
|
||||
struct rebind
|
||||
{ typedef allocator<_Tp1> other; };
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2103. std::allocator propagate_on_container_move_assignment
|
||||
typedef std::true_type propagate_on_container_move_assignment;
|
||||
#endif
|
||||
|
||||
allocator() throw() { }
|
||||
|
||||
allocator(const allocator& __a) throw()
|
||||
: __allocator_base<_Tp>(__a) { }
|
||||
|
||||
template<typename _Tp1>
|
||||
allocator(const allocator<_Tp1>&) throw() { }
|
||||
|
||||
~allocator() throw() { }
|
||||
|
||||
// Inherit everything else.
|
||||
};
|
||||
|
||||
template<typename _T1, typename _T2>
|
||||
inline bool
|
||||
operator==(const allocator<_T1>&, const allocator<_T2>&)
|
||||
{ return true; }
|
||||
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
operator==(const allocator<_Tp>&, const allocator<_Tp>&)
|
||||
{ return true; }
|
||||
|
||||
template<typename _T1, typename _T2>
|
||||
inline bool
|
||||
operator!=(const allocator<_T1>&, const allocator<_T2>&)
|
||||
{ return false; }
|
||||
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
operator!=(const allocator<_Tp>&, const allocator<_Tp>&)
|
||||
{ return false; }
|
||||
|
||||
/// @} group allocator
|
||||
|
||||
// Inhibit implicit instantiations for required instantiations,
|
||||
// which are defined via explicit instantiations elsewhere.
|
||||
#if _GLIBCXX_EXTERN_TEMPLATE
|
||||
extern template class allocator<char>;
|
||||
extern template class allocator<wchar_t>;
|
||||
#endif
|
||||
|
||||
// Undefine.
|
||||
#undef __allocator_base
|
||||
|
||||
// To implement Option 3 of DR 431.
|
||||
template<typename _Alloc, bool = __is_empty(_Alloc)>
|
||||
struct __alloc_swap
|
||||
{ static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
|
||||
|
||||
template<typename _Alloc>
|
||||
struct __alloc_swap<_Alloc, false>
|
||||
{
|
||||
static void
|
||||
_S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
|
||||
{
|
||||
// Precondition: swappable allocators.
|
||||
if (__one != __two)
|
||||
swap(__one, __two);
|
||||
}
|
||||
};
|
||||
|
||||
// Optimize for stateless allocators.
|
||||
template<typename _Alloc, bool = __is_empty(_Alloc)>
|
||||
struct __alloc_neq
|
||||
{
|
||||
static bool
|
||||
_S_do_it(const _Alloc&, const _Alloc&)
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template<typename _Alloc>
|
||||
struct __alloc_neq<_Alloc, false>
|
||||
{
|
||||
static bool
|
||||
_S_do_it(const _Alloc& __one, const _Alloc& __two)
|
||||
{ return __one != __two; }
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Tp, bool
|
||||
= std::disjunction<std::is_copy_constructible<typename _Tp::value_type>,
|
||||
std::is_nothrow_move_constructible<typename _Tp::value_type>>::value>
|
||||
struct __shrink_to_fit_aux
|
||||
{ static bool _S_do_it(_Tp&) noexcept { return false; } };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __shrink_to_fit_aux<_Tp, true>
|
||||
{
|
||||
static bool
|
||||
_S_do_it(_Tp& __c) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
_Tp(__make_move_if_noexcept_iterator(__c.begin()),
|
||||
__make_move_if_noexcept_iterator(__c.end()),
|
||||
__c.get_allocator()).swap(__c);
|
||||
return true;
|
||||
}
|
||||
catch(...)
|
||||
{ return false; }
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif
|
54
loader/include/Geode/c++stl/gnustl/c++allocator.hpp
Normal file
54
loader/include/Geode/c++stl/gnustl/c++allocator.hpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Base to std::allocator -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/c++allocator.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{memory}
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_CXX_ALLOCATOR_H
|
||||
#define _GLIBCXX_CXX_ALLOCATOR_H 1
|
||||
|
||||
#include "ext/new_allocator.h"
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
namespace geode::stl {
|
||||
/**
|
||||
* @brief An alias to the base class for std::allocator.
|
||||
* @ingroup allocators
|
||||
*
|
||||
* Used to set the std::allocator base class to
|
||||
* __gnu_cxx::new_allocator.
|
||||
*
|
||||
* @tparam _Tp Type of allocated object.
|
||||
*/
|
||||
template<typename _Tp>
|
||||
using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
|
||||
}
|
||||
#else
|
||||
// Define new_allocator as the base class to std::allocator.
|
||||
# define __allocator_base __gnu_cxx::new_allocator
|
||||
#endif
|
||||
|
||||
#endif
|
1680
loader/include/Geode/c++stl/gnustl/c++config-arm64.h
Normal file
1680
loader/include/Geode/c++stl/gnustl/c++config-arm64.h
Normal file
File diff suppressed because it is too large
Load diff
1680
loader/include/Geode/c++stl/gnustl/c++config-armeabi-v7a.h
Normal file
1680
loader/include/Geode/c++stl/gnustl/c++config-armeabi-v7a.h
Normal file
File diff suppressed because it is too large
Load diff
14
loader/include/Geode/c++stl/gnustl/c++config.h
Normal file
14
loader/include/Geode/c++stl/gnustl/c++config.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#if UINTPTR_MAX > 0xffffffff
|
||||
# include "c++config-arm64.h"
|
||||
#else
|
||||
# include "c++config-armeabi-v7a.h"
|
||||
#endif
|
||||
|
||||
// i put this here cuz it's used all over the place
|
||||
namespace geode::stl {
|
||||
template <typename T> using __not_ = std::integral_constant<bool, !T::value>;
|
||||
}
|
45
loader/include/Geode/c++stl/gnustl/exception_defines.h
Normal file
45
loader/include/Geode/c++stl/gnustl/exception_defines.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
// -fno-exceptions Support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/exception_defines.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{exception}
|
||||
*/
|
||||
|
||||
#ifndef _EXCEPTION_DEFINES_H
|
||||
#define _EXCEPTION_DEFINES_H 1
|
||||
|
||||
#ifndef __EXCEPTIONS
|
||||
// Iff -fno-exceptions, transform error handling code to work without it.
|
||||
# define __try if (true)
|
||||
# define __catch(X) if (false)
|
||||
# define __throw_exception_again
|
||||
#else
|
||||
// Else proceed normally.
|
||||
# define __try try
|
||||
# define __catch(X) catch(X)
|
||||
# define __throw_exception_again throw
|
||||
#endif
|
||||
|
||||
#endif
|
111
loader/include/Geode/c++stl/gnustl/ext/aligned_buffer.h
Normal file
111
loader/include/Geode/c++stl/gnustl/ext/aligned_buffer.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Aligned memory buffer -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2013-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file ext/aligned_buffer.h
|
||||
* This file is a GNU extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <type_traits>
|
||||
#else
|
||||
# include <bits/c++0x_warning.h>
|
||||
#endif
|
||||
|
||||
namespace __gnu_cxx {
|
||||
// A utility type containing a POD object that can hold an object of type
|
||||
// _Tp initialized via placement new or allocator_traits::construct.
|
||||
// Intended for use as a data member subobject, use __aligned_buffer for
|
||||
// complete objects.
|
||||
template<typename _Tp>
|
||||
struct __aligned_membuf
|
||||
{
|
||||
// Target macro ADJUST_FIELD_ALIGN can produce different alignment for
|
||||
// types when used as class members. __aligned_membuf is intended
|
||||
// for use as a class member, so align the buffer as for a class member.
|
||||
struct _Tp2 { _Tp _M_t; };
|
||||
|
||||
alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)];
|
||||
|
||||
__aligned_membuf() = default;
|
||||
|
||||
// Can be used to avoid value-initialization zeroing _M_storage.
|
||||
__aligned_membuf(std::nullptr_t) { }
|
||||
|
||||
void*
|
||||
_M_addr() noexcept
|
||||
{ return static_cast<void*>(&_M_storage); }
|
||||
|
||||
const void*
|
||||
_M_addr() const noexcept
|
||||
{ return static_cast<const void*>(&_M_storage); }
|
||||
|
||||
_Tp*
|
||||
_M_ptr() noexcept
|
||||
{ return static_cast<_Tp*>(_M_addr()); }
|
||||
|
||||
const _Tp*
|
||||
_M_ptr() const noexcept
|
||||
{ return static_cast<const _Tp*>(_M_addr()); }
|
||||
};
|
||||
|
||||
// Similar to __aligned_membuf but aligned for complete objects, not members.
|
||||
// This type is used in <forward_list>, <future>, <bits/shared_ptr_base.h>
|
||||
// and <bits/hashtable_policy.h>, but ideally they would use __aligned_membuf
|
||||
// instead, as it has smaller size for some types on some targets.
|
||||
// This type is still used to avoid an ABI change.
|
||||
template<typename _Tp>
|
||||
struct __aligned_buffer
|
||||
: std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>
|
||||
{
|
||||
typename
|
||||
std::aligned_storage<sizeof(_Tp), std::alignment_of<_Tp>::value>::type
|
||||
_M_storage;
|
||||
|
||||
void*
|
||||
_M_addr() noexcept
|
||||
{
|
||||
return static_cast<void*>(&_M_storage);
|
||||
}
|
||||
|
||||
const void*
|
||||
_M_addr() const noexcept
|
||||
{
|
||||
return static_cast<const void*>(&_M_storage);
|
||||
}
|
||||
|
||||
_Tp*
|
||||
_M_ptr() noexcept
|
||||
{ return static_cast<_Tp*>(_M_addr()); }
|
||||
|
||||
const _Tp*
|
||||
_M_ptr() const noexcept
|
||||
{ return static_cast<const _Tp*>(_M_addr()); }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
211
loader/include/Geode/c++stl/gnustl/ext/alloc_traits.h
Normal file
211
loader/include/Geode/c++stl/gnustl/ext/alloc_traits.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
// Allocator traits -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file ext/alloc_traits.h
|
||||
* This file is a GNU extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include "../alloc_traits.h"
|
||||
#else
|
||||
# include <bits/allocator.h> // for __alloc_swap
|
||||
#endif
|
||||
#include "../c++config.h"
|
||||
|
||||
namespace __gnu_cxx {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Alloc>
|
||||
struct __allocator_always_compares_equal : std::false_type { };
|
||||
|
||||
template<typename _Tp>
|
||||
struct __allocator_always_compares_equal<std::allocator<_Tp>>
|
||||
: std::true_type { };
|
||||
|
||||
template<typename, typename> struct array_allocator;
|
||||
|
||||
template<typename _Tp, typename _Array>
|
||||
struct __allocator_always_compares_equal<array_allocator<_Tp, _Array>>
|
||||
: std::true_type { };
|
||||
|
||||
template<typename> struct bitmap_allocator;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __allocator_always_compares_equal<bitmap_allocator<_Tp>>
|
||||
: std::true_type { };
|
||||
|
||||
template<typename> struct malloc_allocator;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __allocator_always_compares_equal<malloc_allocator<_Tp>>
|
||||
: std::true_type { };
|
||||
|
||||
template<typename> struct mt_allocator;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __allocator_always_compares_equal<mt_allocator<_Tp>>
|
||||
: std::true_type { };
|
||||
|
||||
template<typename> struct new_allocator;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __allocator_always_compares_equal<new_allocator<_Tp>>
|
||||
: std::true_type { };
|
||||
|
||||
template<typename> struct pool_allocator;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __allocator_always_compares_equal<pool_allocator<_Tp>>
|
||||
: std::true_type { };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Uniform interface to C++98 and C++0x allocators.
|
||||
* @ingroup allocators
|
||||
*/
|
||||
template<typename _Alloc>
|
||||
struct __alloc_traits
|
||||
#if __cplusplus >= 201103L
|
||||
: std::allocator_traits<_Alloc>
|
||||
#endif
|
||||
{
|
||||
typedef _Alloc allocator_type;
|
||||
#if __cplusplus >= 201103L
|
||||
typedef std::allocator_traits<_Alloc> _Base_type;
|
||||
typedef typename _Base_type::value_type value_type;
|
||||
typedef typename _Base_type::pointer pointer;
|
||||
typedef typename _Base_type::const_pointer const_pointer;
|
||||
typedef typename _Base_type::size_type size_type;
|
||||
typedef typename _Base_type::difference_type difference_type;
|
||||
// C++11 allocators do not define reference or const_reference
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
using _Base_type::allocate;
|
||||
using _Base_type::deallocate;
|
||||
using _Base_type::construct;
|
||||
using _Base_type::destroy;
|
||||
using _Base_type::max_size;
|
||||
|
||||
private:
|
||||
template<typename _Ptr>
|
||||
using __is_custom_pointer
|
||||
= std::conjunction<std::is_same<pointer, _Ptr>,
|
||||
geode::stl::__not_<std::is_pointer<_Ptr>>>;
|
||||
|
||||
public:
|
||||
// overload construct for non-standard pointer types
|
||||
template<typename _Ptr, typename... _Args>
|
||||
static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
|
||||
construct(_Alloc& __a, _Ptr __p, _Args&&... __args)
|
||||
{
|
||||
_Base_type::construct(__a, std::addressof(*__p),
|
||||
std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
// overload destroy for non-standard pointer types
|
||||
template<typename _Ptr>
|
||||
static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type
|
||||
destroy(_Alloc& __a, _Ptr __p)
|
||||
{ _Base_type::destroy(__a, std::addressof(*__p)); }
|
||||
|
||||
static _Alloc _S_select_on_copy(const _Alloc& __a)
|
||||
{ return _Base_type::select_on_container_copy_construction(__a); }
|
||||
|
||||
static void _S_on_swap(_Alloc& __a, _Alloc& __b)
|
||||
{ __alloc_on_swap(__a, __b); }
|
||||
|
||||
static constexpr bool _S_propagate_on_copy_assign()
|
||||
{ return _Base_type::propagate_on_container_copy_assignment::value; }
|
||||
|
||||
static constexpr bool _S_propagate_on_move_assign()
|
||||
{ return _Base_type::propagate_on_container_move_assignment::value; }
|
||||
|
||||
static constexpr bool _S_propagate_on_swap()
|
||||
{ return _Base_type::propagate_on_container_swap::value; }
|
||||
|
||||
static constexpr bool _S_always_equal()
|
||||
{ return __allocator_always_compares_equal<_Alloc>::value; }
|
||||
|
||||
static constexpr bool _S_nothrow_move()
|
||||
{ return _S_propagate_on_move_assign() || _S_always_equal(); }
|
||||
|
||||
static constexpr bool _S_nothrow_swap()
|
||||
{
|
||||
using std::swap;
|
||||
return !_S_propagate_on_swap()
|
||||
|| noexcept(swap(std::declval<_Alloc&>(), std::declval<_Alloc&>()));
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
struct rebind
|
||||
{ typedef typename _Base_type::template rebind_alloc<_Tp> other; };
|
||||
#else
|
||||
|
||||
typedef typename _Alloc::pointer pointer;
|
||||
typedef typename _Alloc::const_pointer const_pointer;
|
||||
typedef typename _Alloc::value_type value_type;
|
||||
typedef typename _Alloc::reference reference;
|
||||
typedef typename _Alloc::const_reference const_reference;
|
||||
typedef typename _Alloc::size_type size_type;
|
||||
typedef typename _Alloc::difference_type difference_type;
|
||||
|
||||
static pointer
|
||||
allocate(_Alloc& __a, size_type __n)
|
||||
{ return __a.allocate(__n); }
|
||||
|
||||
static void deallocate(_Alloc& __a, pointer __p, size_type __n)
|
||||
{ __a.deallocate(__p, __n); }
|
||||
|
||||
template<typename _Tp>
|
||||
static void construct(_Alloc& __a, pointer __p, const _Tp& __arg)
|
||||
{ __a.construct(__p, __arg); }
|
||||
|
||||
static void destroy(_Alloc& __a, pointer __p)
|
||||
{ __a.destroy(__p); }
|
||||
|
||||
static size_type max_size(const _Alloc& __a)
|
||||
{ return __a.max_size(); }
|
||||
|
||||
static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; }
|
||||
|
||||
static void _S_on_swap(_Alloc& __a, _Alloc& __b)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 431. Swapping containers with unequal allocators.
|
||||
std::__alloc_swap<_Alloc>::_S_do_it(__a, __b);
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
struct rebind
|
||||
{ typedef typename _Alloc::template rebind<_Tp>::other other; };
|
||||
#endif
|
||||
};
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
155
loader/include/Geode/c++stl/gnustl/ext/new_allocator.h
Normal file
155
loader/include/Geode/c++stl/gnustl/ext/new_allocator.h
Normal file
|
@ -0,0 +1,155 @@
|
|||
// Allocator that wraps operator new -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file ext/new_allocator.h
|
||||
* This file is a GNU extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _NEW_ALLOCATOR_H
|
||||
#define _NEW_ALLOCATOR_H 1
|
||||
|
||||
#include "../c++config.h"
|
||||
#include <new>
|
||||
#if __cplusplus >= 201103L
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
|
||||
/**
|
||||
* @brief An allocator that uses global new, as per [20.4].
|
||||
* @ingroup allocators
|
||||
*
|
||||
* This is precisely the allocator defined in the C++ Standard.
|
||||
* - all allocation calls operator new
|
||||
* - all deallocation calls operator delete
|
||||
*
|
||||
* @tparam _Tp Type of allocated object.
|
||||
*/
|
||||
template<typename _Tp>
|
||||
class new_allocator
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef _Tp* pointer;
|
||||
typedef const _Tp* const_pointer;
|
||||
typedef _Tp& reference;
|
||||
typedef const _Tp& const_reference;
|
||||
typedef _Tp value_type;
|
||||
|
||||
template<typename _Tp1>
|
||||
struct rebind
|
||||
{ typedef new_allocator<_Tp1> other; };
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2103. propagate_on_container_move_assignment
|
||||
typedef std::true_type propagate_on_container_move_assignment;
|
||||
#endif
|
||||
|
||||
new_allocator() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
template<typename _Tp1>
|
||||
new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
~new_allocator() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
pointer
|
||||
address(reference __x) const _GLIBCXX_NOEXCEPT
|
||||
{ return std::addressof(__x); }
|
||||
|
||||
const_pointer
|
||||
address(const_reference __x) const _GLIBCXX_NOEXCEPT
|
||||
{ return std::addressof(__x); }
|
||||
|
||||
// NB: __n is permitted to be 0. The C++ standard says nothing
|
||||
// about what the return value is when __n == 0.
|
||||
pointer
|
||||
allocate(size_type __n, const void* = 0)
|
||||
{
|
||||
if (__n > this->max_size())
|
||||
std::__throw_bad_alloc();
|
||||
|
||||
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
|
||||
}
|
||||
|
||||
#ifdef __GXX_DELETE_WITH_SIZE__
|
||||
// __p is not permitted to be a null pointer.
|
||||
void
|
||||
deallocate(pointer __p, size_type __t)
|
||||
{ ::operator delete(__p, __t * sizeof(_Tp)); }
|
||||
#else
|
||||
// __p is not permitted to be a null pointer.
|
||||
void
|
||||
deallocate(pointer __p, size_type)
|
||||
{ ::operator delete(__p); }
|
||||
#endif
|
||||
|
||||
size_type
|
||||
max_size() const _GLIBCXX_USE_NOEXCEPT
|
||||
{ return size_t(-1) / sizeof(_Tp); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Up, typename... _Args>
|
||||
void
|
||||
construct(_Up* __p, _Args&&... __args)
|
||||
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
|
||||
|
||||
template<typename _Up>
|
||||
void
|
||||
destroy(_Up* __p) { __p->~_Up(); }
|
||||
#else
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 402. wrong new expression in [some_] allocator::construct
|
||||
void
|
||||
construct(pointer __p, const _Tp& __val)
|
||||
{ ::new((void *)__p) _Tp(__val); }
|
||||
|
||||
void
|
||||
destroy(pointer __p) { __p->~_Tp(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
|
||||
{ return true; }
|
||||
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
|
||||
{ return false; }
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif
|
135
loader/include/Geode/c++stl/gnustl/ext/numeric_traits.h
Normal file
135
loader/include/Geode/c++stl/gnustl/ext/numeric_traits.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the terms
|
||||
// of the GNU General Public License as published by the Free Software
|
||||
// Foundation; either version 3, or (at your option) any later
|
||||
// version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file ext/numeric_traits.h
|
||||
* This file is a GNU extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include <type_traits>
|
||||
#include "../c++config.h"
|
||||
|
||||
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// Compile time constants for builtin types.
|
||||
// Sadly std::numeric_limits member functions cannot be used for this.
|
||||
#define __glibcxx_signed(_Tp) ((_Tp)(-1) < 0)
|
||||
#define __glibcxx_digits(_Tp) \
|
||||
(sizeof(_Tp) * __CHAR_BIT__ - __glibcxx_signed(_Tp))
|
||||
|
||||
#define __glibcxx_min(_Tp) \
|
||||
(__glibcxx_signed(_Tp) ? (_Tp)1 << __glibcxx_digits(_Tp) : (_Tp)0)
|
||||
|
||||
#define __glibcxx_max(_Tp) \
|
||||
(__glibcxx_signed(_Tp) ? \
|
||||
(((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0)
|
||||
|
||||
template<typename _Value>
|
||||
struct __numeric_traits_integer
|
||||
{
|
||||
// Only integers for initialization of member constant.
|
||||
static const _Value __min = __glibcxx_min(_Value);
|
||||
static const _Value __max = __glibcxx_max(_Value);
|
||||
|
||||
// NB: these two also available in std::numeric_limits as compile
|
||||
// time constants, but <limits> is big and we avoid including it.
|
||||
static const bool __is_signed = __glibcxx_signed(_Value);
|
||||
static const int __digits = __glibcxx_digits(_Value);
|
||||
};
|
||||
|
||||
template<typename _Value>
|
||||
const _Value __numeric_traits_integer<_Value>::__min;
|
||||
|
||||
template<typename _Value>
|
||||
const _Value __numeric_traits_integer<_Value>::__max;
|
||||
|
||||
template<typename _Value>
|
||||
const bool __numeric_traits_integer<_Value>::__is_signed;
|
||||
|
||||
template<typename _Value>
|
||||
const int __numeric_traits_integer<_Value>::__digits;
|
||||
|
||||
#undef __glibcxx_signed
|
||||
#undef __glibcxx_digits
|
||||
#undef __glibcxx_min
|
||||
#undef __glibcxx_max
|
||||
|
||||
#define __glibcxx_floating(_Tp, _Fval, _Dval, _LDval) \
|
||||
(std::is_same<_Tp, float>::__value ? _Fval \
|
||||
: std::is_same<_Tp, double>::__value ? _Dval : _LDval)
|
||||
|
||||
#define __glibcxx_max_digits10(_Tp) \
|
||||
(2 + __glibcxx_floating(_Tp, __FLT_MANT_DIG__, __DBL_MANT_DIG__, \
|
||||
__LDBL_MANT_DIG__) * 643L / 2136)
|
||||
|
||||
#define __glibcxx_digits10(_Tp) \
|
||||
__glibcxx_floating(_Tp, __FLT_DIG__, __DBL_DIG__, __LDBL_DIG__)
|
||||
|
||||
#define __glibcxx_max_exponent10(_Tp) \
|
||||
__glibcxx_floating(_Tp, __FLT_MAX_10_EXP__, __DBL_MAX_10_EXP__, \
|
||||
__LDBL_MAX_10_EXP__)
|
||||
|
||||
template<typename _Value>
|
||||
struct __numeric_traits_floating
|
||||
{
|
||||
// Only floating point types. See N1822.
|
||||
static const int __max_digits10 = __glibcxx_max_digits10(_Value);
|
||||
|
||||
// See above comment...
|
||||
static const bool __is_signed = true;
|
||||
static const int __digits10 = __glibcxx_digits10(_Value);
|
||||
static const int __max_exponent10 = __glibcxx_max_exponent10(_Value);
|
||||
};
|
||||
|
||||
template<typename _Value>
|
||||
const int __numeric_traits_floating<_Value>::__max_digits10;
|
||||
|
||||
template<typename _Value>
|
||||
const bool __numeric_traits_floating<_Value>::__is_signed;
|
||||
|
||||
template<typename _Value>
|
||||
const int __numeric_traits_floating<_Value>::__digits10;
|
||||
|
||||
template<typename _Value>
|
||||
const int __numeric_traits_floating<_Value>::__max_exponent10;
|
||||
|
||||
template<typename _Value>
|
||||
struct __numeric_traits
|
||||
: public std::conditional<std::is_integral<_Value>::__value,
|
||||
__numeric_traits_integer<_Value>,
|
||||
__numeric_traits_floating<_Value> >::__type
|
||||
{ };
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#undef __glibcxx_floating
|
||||
#undef __glibcxx_max_digits10
|
||||
#undef __glibcxx_digits10
|
||||
#undef __glibcxx_max_exponent10
|
211
loader/include/Geode/c++stl/gnustl/functional_hash.h
Normal file
211
loader/include/Geode/c++stl/gnustl/functional_hash.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
// functional_hash.h header -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/functional_hash.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{functional}
|
||||
*/
|
||||
|
||||
#ifndef _FUNCTIONAL_HASH_H
|
||||
#define _FUNCTIONAL_HASH_H 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include "hash_bytes.h"
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/** @defgroup hashes Hashes
|
||||
* @ingroup functors
|
||||
*
|
||||
* Hashing functors taking a variable type and returning a @c std::size_t.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
template<typename _Result, typename _Arg>
|
||||
struct __hash_base
|
||||
{
|
||||
typedef _Result result_type;
|
||||
typedef _Arg argument_type;
|
||||
};
|
||||
|
||||
/// Primary class template hash.
|
||||
template<typename _Tp>
|
||||
struct hash;
|
||||
|
||||
/// Partial specializations for pointer types.
|
||||
template<typename _Tp>
|
||||
struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
|
||||
{
|
||||
size_t
|
||||
operator()(_Tp* __p) const noexcept
|
||||
{ return reinterpret_cast<size_t>(__p); }
|
||||
};
|
||||
|
||||
// Explicit specializations for integer types.
|
||||
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
|
||||
template<> \
|
||||
struct hash<_Tp> : public __hash_base<size_t, _Tp> \
|
||||
{ \
|
||||
size_t \
|
||||
operator()(_Tp __val) const noexcept \
|
||||
{ return static_cast<size_t>(__val); } \
|
||||
};
|
||||
|
||||
/// Explicit specialization for bool.
|
||||
_Cxx_hashtable_define_trivial_hash(bool)
|
||||
|
||||
/// Explicit specialization for char.
|
||||
_Cxx_hashtable_define_trivial_hash(char)
|
||||
|
||||
/// Explicit specialization for signed char.
|
||||
_Cxx_hashtable_define_trivial_hash(signed char)
|
||||
|
||||
/// Explicit specialization for unsigned char.
|
||||
_Cxx_hashtable_define_trivial_hash(unsigned char)
|
||||
|
||||
/// Explicit specialization for wchar_t.
|
||||
_Cxx_hashtable_define_trivial_hash(wchar_t)
|
||||
|
||||
/// Explicit specialization for char16_t.
|
||||
_Cxx_hashtable_define_trivial_hash(char16_t)
|
||||
|
||||
/// Explicit specialization for char32_t.
|
||||
_Cxx_hashtable_define_trivial_hash(char32_t)
|
||||
|
||||
/// Explicit specialization for short.
|
||||
_Cxx_hashtable_define_trivial_hash(short)
|
||||
|
||||
/// Explicit specialization for int.
|
||||
_Cxx_hashtable_define_trivial_hash(int)
|
||||
|
||||
/// Explicit specialization for long.
|
||||
_Cxx_hashtable_define_trivial_hash(long)
|
||||
|
||||
/// Explicit specialization for long long.
|
||||
_Cxx_hashtable_define_trivial_hash(long long)
|
||||
|
||||
/// Explicit specialization for unsigned short.
|
||||
_Cxx_hashtable_define_trivial_hash(unsigned short)
|
||||
|
||||
/// Explicit specialization for unsigned int.
|
||||
_Cxx_hashtable_define_trivial_hash(unsigned int)
|
||||
|
||||
/// Explicit specialization for unsigned long.
|
||||
_Cxx_hashtable_define_trivial_hash(unsigned long)
|
||||
|
||||
/// Explicit specialization for unsigned long long.
|
||||
_Cxx_hashtable_define_trivial_hash(unsigned long long)
|
||||
|
||||
#undef _Cxx_hashtable_define_trivial_hash
|
||||
|
||||
struct _Hash_impl
|
||||
{
|
||||
static size_t
|
||||
hash(const void* __ptr, size_t __clength,
|
||||
size_t __seed = static_cast<size_t>(0xc70f6907UL))
|
||||
{ return _Hash_bytes(__ptr, __clength, __seed); }
|
||||
|
||||
template<typename _Tp>
|
||||
static size_t
|
||||
hash(const _Tp& __val)
|
||||
{ return hash(&__val, sizeof(__val)); }
|
||||
|
||||
template<typename _Tp>
|
||||
static size_t
|
||||
__hash_combine(const _Tp& __val, size_t __hash)
|
||||
{ return hash(&__val, sizeof(__val), __hash); }
|
||||
};
|
||||
|
||||
struct _Fnv_hash_impl
|
||||
{
|
||||
static size_t
|
||||
hash(const void* __ptr, size_t __clength,
|
||||
size_t __seed = static_cast<size_t>(2166136261UL))
|
||||
{ return _Fnv_hash_bytes(__ptr, __clength, __seed); }
|
||||
|
||||
template<typename _Tp>
|
||||
static size_t
|
||||
hash(const _Tp& __val)
|
||||
{ return hash(&__val, sizeof(__val)); }
|
||||
|
||||
template<typename _Tp>
|
||||
static size_t
|
||||
__hash_combine(const _Tp& __val, size_t __hash)
|
||||
{ return hash(&__val, sizeof(__val), __hash); }
|
||||
};
|
||||
|
||||
/// Specialization for float.
|
||||
template<>
|
||||
struct hash<float> : public __hash_base<size_t, float>
|
||||
{
|
||||
size_t
|
||||
operator()(float __val) const noexcept
|
||||
{
|
||||
// 0 and -0 both hash to zero.
|
||||
return __val != 0.0f ? _Hash_impl::hash(__val) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// Specialization for double.
|
||||
template<>
|
||||
struct hash<double> : public __hash_base<size_t, double>
|
||||
{
|
||||
size_t
|
||||
operator()(double __val) const noexcept
|
||||
{
|
||||
// 0 and -0 both hash to zero.
|
||||
return __val != 0.0 ? _Hash_impl::hash(__val) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// Specialization for long double.
|
||||
template<>
|
||||
struct hash<long double>
|
||||
: public __hash_base<size_t, long double>
|
||||
{
|
||||
_GLIBCXX_PURE size_t
|
||||
operator()(long double __val) const noexcept;
|
||||
};
|
||||
|
||||
// @} group hashes
|
||||
|
||||
// Hint about performance of hash functor. If not fast the hash based
|
||||
// containers will cache the hash code.
|
||||
// Default behavior is to consider that hasher are fast unless specified
|
||||
// otherwise.
|
||||
template<typename _Hash>
|
||||
struct __is_fast_hash : public std::true_type
|
||||
{ };
|
||||
|
||||
template<>
|
||||
struct __is_fast_hash<hash<long double>> : public std::false_type
|
||||
{ };
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif // _FUNCTIONAL_HASH_H
|
58
loader/include/Geode/c++stl/gnustl/hash_bytes.h
Normal file
58
loader/include/Geode/c++stl/gnustl/hash_bytes.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
// Declarations for hash functions. -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2010-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/hash_bytes.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{functional}
|
||||
*/
|
||||
|
||||
#ifndef _HASH_BYTES_H
|
||||
#define _HASH_BYTES_H 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include "c++config.h"
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
// Hash function implementation for the nontrivial specialization.
|
||||
// All of them are based on a primitive that hashes a pointer to a
|
||||
// byte array. The actual hash algorithm is not guaranteed to stay
|
||||
// the same from release to release -- it may be updated or tuned to
|
||||
// improve hash quality or speed.
|
||||
size_t
|
||||
_Hash_bytes(const void* __ptr, size_t __len, size_t __seed);
|
||||
|
||||
// A similar hash primitive, using the FNV hash algorithm. This
|
||||
// algorithm is guaranteed to stay the same from release to release.
|
||||
// (although it might not produce the same values on different
|
||||
// machines.)
|
||||
size_t
|
||||
_Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed);
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif
|
11
loader/include/Geode/c++stl/gnustl/hash_specialization.hpp
Normal file
11
loader/include/Geode/c++stl/gnustl/hash_specialization.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include "functional_hash.h"
|
||||
|
||||
namespace geode::stl {
|
||||
template <>
|
||||
struct hash<gd::string> : public __hash_base<size_t, gd::string> {
|
||||
size_t operator()(const gd::string& s) const noexcept {
|
||||
return _Hash_impl::hash(s.data(), s.size());
|
||||
}
|
||||
};
|
||||
}
|
2124
loader/include/Geode/c++stl/gnustl/hashtable.h
Normal file
2124
loader/include/Geode/c++stl/gnustl/hashtable.h
Normal file
File diff suppressed because it is too large
Load diff
2163
loader/include/Geode/c++stl/gnustl/hashtable_policy.h
Normal file
2163
loader/include/Geode/c++stl/gnustl/hashtable_policy.h
Normal file
File diff suppressed because it is too large
Load diff
77
loader/include/Geode/c++stl/gnustl/memoryfwd.h
Normal file
77
loader/include/Geode/c++stl/gnustl/memoryfwd.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
// <memory> Forward declarations -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-1997
|
||||
* Silicon Graphics Computer Systems, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Silicon Graphics makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
/** @file bits/memoryfwd.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{memory}
|
||||
*/
|
||||
|
||||
#ifndef _MEMORYFWD_H
|
||||
#define _MEMORYFWD_H 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include "c++config.h"
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/**
|
||||
* @defgroup allocators Allocators
|
||||
* @ingroup memory
|
||||
*
|
||||
* Classes encapsulating memory operations.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
template<typename>
|
||||
class allocator;
|
||||
|
||||
template<>
|
||||
class allocator<void>;
|
||||
|
||||
/// Declare uses_allocator so it can be specialized in \<queue\> etc.
|
||||
template<typename, typename>
|
||||
struct uses_allocator;
|
||||
|
||||
/// @} group memory
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif
|
157
loader/include/Geode/c++stl/gnustl/new_allocator.h
Normal file
157
loader/include/Geode/c++stl/gnustl/new_allocator.h
Normal file
|
@ -0,0 +1,157 @@
|
|||
// Allocator that wraps operator new -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file ext/new_allocator.h
|
||||
* This file is a GNU extension to the Standard C++ Library.
|
||||
*/
|
||||
|
||||
#ifndef _NEW_ALLOCATOR_H
|
||||
#define _NEW_ALLOCATOR_H 1
|
||||
|
||||
#include "c++config.h"
|
||||
#include <new>
|
||||
#include <bits/functexcept.h>
|
||||
#include <bits/move.h>
|
||||
#if __cplusplus >= 201103L
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
using std::size_t;
|
||||
using std::ptrdiff_t;
|
||||
|
||||
/**
|
||||
* @brief An allocator that uses global new, as per [20.4].
|
||||
* @ingroup allocators
|
||||
*
|
||||
* This is precisely the allocator defined in the C++ Standard.
|
||||
* - all allocation calls operator new
|
||||
* - all deallocation calls operator delete
|
||||
*
|
||||
* @tparam _Tp Type of allocated object.
|
||||
*/
|
||||
template<typename _Tp>
|
||||
class new_allocator
|
||||
{
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef _Tp* pointer;
|
||||
typedef const _Tp* const_pointer;
|
||||
typedef _Tp& reference;
|
||||
typedef const _Tp& const_reference;
|
||||
typedef _Tp value_type;
|
||||
|
||||
template<typename _Tp1>
|
||||
struct rebind
|
||||
{ typedef new_allocator<_Tp1> other; };
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 2103. propagate_on_container_move_assignment
|
||||
typedef std::true_type propagate_on_container_move_assignment;
|
||||
#endif
|
||||
|
||||
new_allocator() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
template<typename _Tp1>
|
||||
new_allocator(const new_allocator<_Tp1>&) _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
~new_allocator() _GLIBCXX_USE_NOEXCEPT { }
|
||||
|
||||
pointer
|
||||
address(reference __x) const _GLIBCXX_NOEXCEPT
|
||||
{ return std::__addressof(__x); }
|
||||
|
||||
const_pointer
|
||||
address(const_reference __x) const _GLIBCXX_NOEXCEPT
|
||||
{ return std::__addressof(__x); }
|
||||
|
||||
// NB: __n is permitted to be 0. The C++ standard says nothing
|
||||
// about what the return value is when __n == 0.
|
||||
pointer
|
||||
allocate(size_type __n, const void* = 0)
|
||||
{
|
||||
if (__n > this->max_size())
|
||||
std::__throw_bad_alloc();
|
||||
|
||||
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
|
||||
}
|
||||
|
||||
#ifdef __GXX_DELETE_WITH_SIZE__
|
||||
// __p is not permitted to be a null pointer.
|
||||
void
|
||||
deallocate(pointer __p, size_type __t)
|
||||
{ ::operator delete(__p, __t * sizeof(_Tp)); }
|
||||
#else
|
||||
// __p is not permitted to be a null pointer.
|
||||
void
|
||||
deallocate(pointer __p, size_type)
|
||||
{ ::operator delete(__p); }
|
||||
#endif
|
||||
|
||||
size_type
|
||||
max_size() const _GLIBCXX_USE_NOEXCEPT
|
||||
{ return size_t(-1) / sizeof(_Tp); }
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
template<typename _Up, typename... _Args>
|
||||
void
|
||||
construct(_Up* __p, _Args&&... __args)
|
||||
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
|
||||
|
||||
template<typename _Up>
|
||||
void
|
||||
destroy(_Up* __p) { __p->~_Up(); }
|
||||
#else
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 402. wrong new expression in [some_] allocator::construct
|
||||
void
|
||||
construct(pointer __p, const _Tp& __val)
|
||||
{ ::new((void *)__p) _Tp(__val); }
|
||||
|
||||
void
|
||||
destroy(pointer __p) { __p->~_Tp(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
operator==(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
|
||||
{ return true; }
|
||||
|
||||
template<typename _Tp>
|
||||
inline bool
|
||||
operator!=(const new_allocator<_Tp>&, const new_allocator<_Tp>&)
|
||||
{ return false; }
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif
|
184
loader/include/Geode/c++stl/gnustl/ptr_traits.h
Normal file
184
loader/include/Geode/c++stl/gnustl/ptr_traits.h
Normal file
|
@ -0,0 +1,184 @@
|
|||
// Pointer Traits -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/ptr_traits.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{memory}
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include "c++config.h"
|
||||
|
||||
#include <type_traits>
|
||||
#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
|
||||
template<typename _Tp, typename = std::void_t<>> \
|
||||
struct __has_##_NTYPE \
|
||||
: std::false_type \
|
||||
{ }; \
|
||||
template<typename _Tp> \
|
||||
struct __has_##_NTYPE<_Tp, std::void_t<typename _Tp::_NTYPE>> \
|
||||
: std::true_type \
|
||||
{ };
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
_GLIBCXX_HAS_NESTED_TYPE(element_type)
|
||||
_GLIBCXX_HAS_NESTED_TYPE(difference_type)
|
||||
|
||||
template<typename _Tp, bool = __has_element_type<_Tp>::value>
|
||||
struct __ptrtr_elt_type;
|
||||
|
||||
template<typename _Tp>
|
||||
struct __ptrtr_elt_type<_Tp, true>
|
||||
{
|
||||
typedef typename _Tp::element_type __type;
|
||||
};
|
||||
|
||||
template<template<typename, typename...> class _SomePtr, typename _Tp,
|
||||
typename... _Args>
|
||||
struct __ptrtr_elt_type<_SomePtr<_Tp, _Args...>, false>
|
||||
{
|
||||
typedef _Tp __type;
|
||||
};
|
||||
|
||||
template<typename _Tp, bool = __has_difference_type<_Tp>::value>
|
||||
struct __ptrtr_diff_type
|
||||
{
|
||||
typedef typename _Tp::difference_type __type;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __ptrtr_diff_type<_Tp, false>
|
||||
{
|
||||
typedef ptrdiff_t __type;
|
||||
};
|
||||
|
||||
template<typename _Ptr, typename _Up>
|
||||
class __ptrtr_rebind_helper
|
||||
{
|
||||
template<typename _Ptr2, typename _Up2>
|
||||
static constexpr std::true_type
|
||||
_S_chk(typename _Ptr2::template rebind<_Up2>*);
|
||||
|
||||
template<typename, typename>
|
||||
static constexpr std::false_type
|
||||
_S_chk(...);
|
||||
|
||||
public:
|
||||
using __type = decltype(_S_chk<_Ptr, _Up>(nullptr));
|
||||
};
|
||||
|
||||
template<typename _Tp, typename _Up,
|
||||
bool = __ptrtr_rebind_helper<_Tp, _Up>::__type::value>
|
||||
struct __ptrtr_rebind;
|
||||
|
||||
template<typename _Tp, typename _Up>
|
||||
struct __ptrtr_rebind<_Tp, _Up, true>
|
||||
{
|
||||
typedef typename _Tp::template rebind<_Up> __type;
|
||||
};
|
||||
|
||||
template<template<typename, typename...> class _SomePtr, typename _Up,
|
||||
typename _Tp, typename... _Args>
|
||||
struct __ptrtr_rebind<_SomePtr<_Tp, _Args...>, _Up, false>
|
||||
{
|
||||
typedef _SomePtr<_Up, _Args...> __type;
|
||||
};
|
||||
|
||||
template<typename _Tp, typename = typename std::remove_cv<_Tp>::type>
|
||||
struct __ptrtr_not_void
|
||||
{
|
||||
typedef _Tp __type;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __ptrtr_not_void<_Tp, void>
|
||||
{
|
||||
struct __type { };
|
||||
};
|
||||
|
||||
template<typename _Ptr>
|
||||
class __ptrtr_pointer_to
|
||||
{
|
||||
typedef typename __ptrtr_elt_type<_Ptr>::__type __orig_type;
|
||||
typedef typename __ptrtr_not_void<__orig_type>::__type __element_type;
|
||||
|
||||
public:
|
||||
static _Ptr pointer_to(__element_type& __e)
|
||||
{ return _Ptr::pointer_to(__e); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Uniform interface to all pointer-like types
|
||||
* @ingroup pointer_abstractions
|
||||
*/
|
||||
template<typename _Ptr>
|
||||
struct pointer_traits : __ptrtr_pointer_to<_Ptr>
|
||||
{
|
||||
/// The pointer type
|
||||
typedef _Ptr pointer;
|
||||
/// The type pointed to
|
||||
typedef typename __ptrtr_elt_type<_Ptr>::__type element_type;
|
||||
/// Type used to represent the difference between two pointers
|
||||
typedef typename __ptrtr_diff_type<_Ptr>::__type difference_type;
|
||||
|
||||
template<typename _Up>
|
||||
using rebind = typename __ptrtr_rebind<_Ptr, _Up>::__type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Partial specialization for built-in pointers.
|
||||
* @ingroup pointer_abstractions
|
||||
*/
|
||||
template<typename _Tp>
|
||||
struct pointer_traits<_Tp*>
|
||||
{
|
||||
/// The pointer type
|
||||
typedef _Tp* pointer;
|
||||
/// The type pointed to
|
||||
typedef _Tp element_type;
|
||||
/// Type used to represent the difference between two pointers
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
template<typename _Up>
|
||||
using rebind = _Up*;
|
||||
|
||||
/**
|
||||
* @brief Obtain a pointer to an object
|
||||
* @param __r A reference to an object of type @c element_type
|
||||
* @return @c addressof(__r)
|
||||
*/
|
||||
static pointer
|
||||
pointer_to(typename __ptrtr_not_void<element_type>::__type& __r) noexcept
|
||||
{ return std::addressof(__r); }
|
||||
};
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
103
loader/include/Geode/c++stl/gnustl/range_access.h
Normal file
103
loader/include/Geode/c++stl/gnustl/range_access.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
// <range_access.h> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2010-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file bits/range_access.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{iterator}
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
|
||||
#include "c++config.h"
|
||||
|
||||
namespace geode::stl {
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/**
|
||||
* @brief Return an iterator pointing to the first element of
|
||||
* the container.
|
||||
* @param __cont Container.
|
||||
*/
|
||||
template<class _Container>
|
||||
inline auto
|
||||
begin(_Container& __cont) -> decltype(__cont.begin())
|
||||
{ return __cont.begin(); }
|
||||
|
||||
/**
|
||||
* @brief Return an iterator pointing to the first element of
|
||||
* the const container.
|
||||
* @param __cont Container.
|
||||
*/
|
||||
template<class _Container>
|
||||
inline auto
|
||||
begin(const _Container& __cont) -> decltype(__cont.begin())
|
||||
{ return __cont.begin(); }
|
||||
|
||||
/**
|
||||
* @brief Return an iterator pointing to one past the last element of
|
||||
* the container.
|
||||
* @param __cont Container.
|
||||
*/
|
||||
template<class _Container>
|
||||
inline auto
|
||||
end(_Container& __cont) -> decltype(__cont.end())
|
||||
{ return __cont.end(); }
|
||||
|
||||
/**
|
||||
* @brief Return an iterator pointing to one past the last element of
|
||||
* the const container.
|
||||
* @param __cont Container.
|
||||
*/
|
||||
template<class _Container>
|
||||
inline auto
|
||||
end(const _Container& __cont) -> decltype(__cont.end())
|
||||
{ return __cont.end(); }
|
||||
|
||||
/**
|
||||
* @brief Return an iterator pointing to the first element of the array.
|
||||
* @param __arr Array.
|
||||
*/
|
||||
template<class _Tp, size_t _Nm>
|
||||
inline _Tp*
|
||||
begin(_Tp (&__arr)[_Nm])
|
||||
{ return __arr; }
|
||||
|
||||
/**
|
||||
* @brief Return an iterator pointing to one past the last element
|
||||
* of the array.
|
||||
* @param __arr Array.
|
||||
*/
|
||||
template<class _Tp, size_t _Nm>
|
||||
inline _Tp*
|
||||
end(_Tp (&__arr)[_Nm])
|
||||
{ return __arr + _Nm; }
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif // C++11
|
1078
loader/include/Geode/c++stl/gnustl/stl_function.h
Normal file
1078
loader/include/Geode/c++stl/gnustl/stl_function.h
Normal file
File diff suppressed because it is too large
Load diff
9
loader/include/Geode/c++stl/gnustl/type_traits.h
Normal file
9
loader/include/Geode/c++stl/gnustl/type_traits.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "c++config.h"
|
||||
|
||||
namespace geode::stl {
|
||||
// Helper for SFINAE constraints
|
||||
template<typename... _Cond>
|
||||
using _Require = std::enable_if_t<std::conjunction<_Cond...>::value>;
|
||||
}
|
1478
loader/include/Geode/c++stl/gnustl/unordered_map.h
Normal file
1478
loader/include/Geode/c++stl/gnustl/unordered_map.h
Normal file
File diff suppressed because it is too large
Load diff
48
loader/include/Geode/c++stl/gnustl/unordered_map.hpp
Normal file
48
loader/include/Geode/c++stl/gnustl/unordered_map.hpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
// <unordered_map> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file include/unordered_map
|
||||
* This is a Standard C++ Library header.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
# error not c++11
|
||||
#else
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
#include <tuple>
|
||||
#include "allocator.h"
|
||||
#include "ext/alloc_traits.h"
|
||||
#include "ext/aligned_buffer.h"
|
||||
#include "stl_function.h" // equal_to, _Identity, _Select1st
|
||||
#include "functional_hash.h"
|
||||
#include "hashtable.h"
|
||||
#include "unordered_map.h"
|
||||
#include "range_access.h"
|
||||
|
||||
#endif // C++11
|
1354
loader/include/Geode/c++stl/gnustl/unordered_set.h
Normal file
1354
loader/include/Geode/c++stl/gnustl/unordered_set.h
Normal file
File diff suppressed because it is too large
Load diff
53
loader/include/Geode/c++stl/gnustl/unordered_set.hpp
Normal file
53
loader/include/Geode/c++stl/gnustl/unordered_set.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
// <unordered_set> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2014 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// Under Section 7 of GPL version 3, you are granted additional
|
||||
// permissions described in the GCC Runtime Library Exception, version
|
||||
// 3.1, as published by the Free Software Foundation.
|
||||
|
||||
// You should have received a copy of the GNU General Public License and
|
||||
// a copy of the GCC Runtime Library Exception along with this program;
|
||||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** @file include/unordered_set
|
||||
* This is a Standard C++ Library header.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_UNORDERED_SET
|
||||
#define _GLIBCXX_UNORDERED_SET 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
# error "not c++11"
|
||||
#else
|
||||
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <initializer_list>
|
||||
#include <tuple>
|
||||
#include "allocator.h"
|
||||
#include "ext/alloc_traits.h"
|
||||
#include "ext/aligned_buffer.h"
|
||||
#include "stl_function.h" // equal_to, _Identity, _Select1st
|
||||
#include "functional_hash.h"
|
||||
#include "hashtable.h"
|
||||
#include "unordered_set.h"
|
||||
#include "range_access.h"
|
||||
|
||||
#endif // C++11
|
||||
|
||||
#endif // _GLIBCXX_UNORDERED_SET
|
41
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
41
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
|
@ -39,6 +39,7 @@
|
|||
#include "../include/CCProtocols.h"
|
||||
#include "Layout.hpp"
|
||||
#include "../../loader/Event.hpp"
|
||||
#include <Geode/utils/casts.hpp>
|
||||
|
||||
#ifndef GEODE_IS_MEMBER_TEST
|
||||
#include <matjson.hpp>
|
||||
|
@ -1115,7 +1116,7 @@ public:
|
|||
geode::utils::MiniFunction<typename Filter::Callback> callback,
|
||||
Args&&... args
|
||||
) {
|
||||
return this->template addEventListener<Filter, Args...>(
|
||||
return this->addEventListener<Filter, Args...>(
|
||||
"", callback, std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
@ -1123,6 +1124,44 @@ public:
|
|||
GEODE_DLL void removeEventListener(std::string const& id);
|
||||
GEODE_DLL geode::EventListenerProtocol* getEventListener(std::string const& id);
|
||||
GEODE_DLL size_t getEventListenerCount();
|
||||
|
||||
/**
|
||||
* Get nth child that is a given type. Checks bounds.
|
||||
* @returns Child at index cast to the given type,
|
||||
* or nullptr if index exceeds bounds
|
||||
*/
|
||||
template <class T = CCNode>
|
||||
T* getChildByType(int index) {
|
||||
size_t indexCounter = 0;
|
||||
if (this->getChildrenCount() == 0) return nullptr;
|
||||
// start from end for negative index
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
for (size_t i = this->getChildrenCount() - 1; i >= 0; i--) {
|
||||
auto obj = geode::cast::typeinfo_cast<T*>(this->getChildren()->objectAtIndex(i));
|
||||
if (obj != nullptr) {
|
||||
if (indexCounter == index) {
|
||||
return obj;
|
||||
}
|
||||
++indexCounter;
|
||||
}
|
||||
if (i == 0) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < this->getChildrenCount(); i++) {
|
||||
auto obj = geode::cast::typeinfo_cast<T*>(this->getChildren()->objectAtIndex(i));
|
||||
if (obj != nullptr) {
|
||||
if (indexCounter == index) {
|
||||
return obj;
|
||||
}
|
||||
++indexCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @{
|
||||
/// @name Shader Program
|
||||
|
|
|
@ -181,6 +181,7 @@ public:
|
|||
* @lua NA
|
||||
*/
|
||||
CCDictionary();
|
||||
GEODE_CUSTOM_CONSTRUCTOR_COCOS(CCDictionary, CCObject);
|
||||
|
||||
/**
|
||||
* The destructor of CCDictionary
|
||||
|
|
170
loader/include/Geode/cocos/cocoa/CCGeometry.h
vendored
170
loader/include/Geode/cocos/cocoa/CCGeometry.h
vendored
|
@ -55,64 +55,64 @@ public:
|
|||
float y;
|
||||
// alk modifications: all defined
|
||||
|
||||
inline CCPoint() : x(0), y(0) {}
|
||||
inline CCPoint(float x, float y) : x(x), y(y) {}
|
||||
inline constexpr CCPoint() : x(0), y(0) {}
|
||||
inline constexpr CCPoint(float x, float y) : x(x), y(y) {}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint(const CCPoint& other) : x(other.x), y(other.y) {}
|
||||
inline constexpr CCPoint(const CCPoint& other) : x(other.x), y(other.y) {}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint(const CCSize& size);
|
||||
inline constexpr CCPoint(const CCSize& size);
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint& operator= (const CCPoint& other) {
|
||||
inline constexpr CCPoint& operator= (const CCPoint& other) {
|
||||
setPoint(other.x, other.y);
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint& operator= (const CCSize& size);
|
||||
inline constexpr CCPoint& operator= (const CCSize& size);
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint operator+(const CCPoint& right) const {
|
||||
inline constexpr CCPoint operator+(const CCPoint& right) const {
|
||||
return CCPoint(this->x + right.x, this->y + right.y);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint operator-(const CCPoint& right) const {
|
||||
inline constexpr CCPoint operator-(const CCPoint& right) const {
|
||||
return CCPoint(this->x - right.x, this->y - right.y);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint operator-() const {
|
||||
inline constexpr CCPoint operator-() const {
|
||||
return CCPoint(-x, -y);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint operator*(float a) const {
|
||||
inline constexpr CCPoint operator*(float a) const {
|
||||
return CCPoint(this->x * a, this->y * a);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCPoint operator/(float a) const {
|
||||
inline constexpr CCPoint operator/(float a) const {
|
||||
return CCPoint(this->x / a, this->y / a);
|
||||
}
|
||||
|
||||
|
||||
// camila modification
|
||||
inline CCPoint operator*(const CCPoint& right) const {
|
||||
inline constexpr CCPoint operator*(const CCPoint& right) const {
|
||||
return CCPoint(x * right.x, y * right.y);
|
||||
}
|
||||
inline CCPoint operator/(const CCPoint& right) const {
|
||||
inline constexpr CCPoint operator/(const CCPoint& right) const {
|
||||
return CCPoint(x / right.x, y / right.y);
|
||||
}
|
||||
//314
|
||||
|
@ -120,20 +120,20 @@ public:
|
|||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline void setPoint(float x, float y) {
|
||||
inline constexpr void setPoint(float x, float y) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
}
|
||||
|
||||
inline bool equals(const CCPoint& target) const {
|
||||
return (fabs(this->x - target.x) < FLT_EPSILON) && (fabs(this->y - target.y) < FLT_EPSILON);
|
||||
inline constexpr bool equals(const CCPoint& target) const {
|
||||
return this->fuzzyEquals(target, FLT_EPSILON);
|
||||
}
|
||||
|
||||
/** @returns if points have fuzzy equality which means equal with some degree of variance.
|
||||
* @since v2.1.4
|
||||
* @lua NA
|
||||
*/
|
||||
inline bool fuzzyEquals(const CCPoint& b, float var) const {
|
||||
inline constexpr bool fuzzyEquals(const CCPoint& b, float var) const {
|
||||
if(x - var <= b.x && b.x <= x + var)
|
||||
if(y - var <= b.y && b.y <= y + var)
|
||||
return true;
|
||||
|
@ -154,7 +154,7 @@ public:
|
|||
* @since v2.1.4
|
||||
* @lua NA
|
||||
*/
|
||||
inline float getLengthSq() const {
|
||||
inline constexpr float getLengthSq() const {
|
||||
return dot(*this); //x*x + y*y;
|
||||
};
|
||||
|
||||
|
@ -162,7 +162,7 @@ public:
|
|||
@return float
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline float getDistanceSq(const CCPoint& other) const {
|
||||
inline constexpr float getDistanceSq(const CCPoint& other) const {
|
||||
return (*this - other).getLengthSq();
|
||||
};
|
||||
|
||||
|
@ -196,7 +196,7 @@ public:
|
|||
@return float
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline float dot(const CCPoint& other) const {
|
||||
inline constexpr float dot(const CCPoint& other) const {
|
||||
return x*other.x + y*other.y;
|
||||
};
|
||||
|
||||
|
@ -204,7 +204,7 @@ public:
|
|||
@return float
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline float cross(const CCPoint& other) const {
|
||||
inline constexpr float cross(const CCPoint& other) const {
|
||||
return x*other.y - y*other.x;
|
||||
};
|
||||
|
||||
|
@ -212,7 +212,7 @@ public:
|
|||
@return CCPoint
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline CCPoint getPerp() const {
|
||||
inline constexpr CCPoint getPerp() const {
|
||||
return CCPoint(-y, x);
|
||||
};
|
||||
|
||||
|
@ -220,7 +220,7 @@ public:
|
|||
@return CCPoint
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline CCPoint getRPerp() const {
|
||||
inline constexpr CCPoint getRPerp() const {
|
||||
return CCPoint(y, -x);
|
||||
};
|
||||
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
@return CCPoint
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline CCPoint project(const CCPoint& other) const {
|
||||
inline constexpr CCPoint project(const CCPoint& other) const {
|
||||
return other * (dot(other)/other.dot(other));
|
||||
};
|
||||
|
||||
|
@ -237,7 +237,7 @@ public:
|
|||
and a length of this.getLength() * other.getLength().
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline CCPoint rotate(const CCPoint& other) const {
|
||||
inline constexpr CCPoint rotate(const CCPoint& other) const {
|
||||
return CCPoint(x*other.x - y*other.y, x*other.y + y*other.x);
|
||||
};
|
||||
|
||||
|
@ -246,7 +246,7 @@ public:
|
|||
and a length of this.getLength() * other.getLength().
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline CCPoint unrotate(const CCPoint& other) const {
|
||||
inline constexpr CCPoint unrotate(const CCPoint& other) const {
|
||||
return CCPoint(x*other.x + y*other.y, y*other.x - x*other.y);
|
||||
};
|
||||
|
||||
|
@ -268,7 +268,7 @@ public:
|
|||
otherwise a value between a..b
|
||||
@since v2.1.4
|
||||
*/
|
||||
inline CCPoint lerp(const CCPoint& other, float alpha) const {
|
||||
inline constexpr CCPoint lerp(const CCPoint& other, float alpha) const {
|
||||
return *this * (1.f - alpha) + other * alpha;
|
||||
};
|
||||
|
||||
|
@ -287,11 +287,21 @@ public:
|
|||
return CCPoint(cosf(a), sinf(a));
|
||||
}
|
||||
|
||||
void add(int, float);
|
||||
float at(int);
|
||||
bool isZero() const;
|
||||
void set(int, float);
|
||||
void swap();
|
||||
constexpr void add(int idx, float val) {
|
||||
idx == 0 ? x += val : y += val;
|
||||
}
|
||||
constexpr float at(int idx) {
|
||||
return idx == 0 ? x : y;
|
||||
}
|
||||
constexpr bool isZero() const {
|
||||
return x == 0.f && y == 0.f;
|
||||
}
|
||||
constexpr void set(int idx, float val) {
|
||||
idx == 0 ? x = val : y = val;
|
||||
}
|
||||
constexpr void swap() {
|
||||
std::swap(x, y);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
@ -306,86 +316,104 @@ public:
|
|||
float height;
|
||||
|
||||
public:
|
||||
inline CCSize() : width(0), height(0) {}
|
||||
inline CCSize(float width, float height) : width(width), height(height) {}
|
||||
inline constexpr CCSize() : width(0), height(0) {}
|
||||
inline constexpr CCSize(float width, float height) : width(width), height(height) {}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize(const CCSize& other) : width(other.width), height(other.height) {}
|
||||
inline constexpr CCSize(const CCSize& other) : width(other.width), height(other.height) {}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize(const CCPoint& point) : width(point.x), height(point.y) {}
|
||||
inline constexpr CCSize(const CCPoint& point) : width(point.x), height(point.y) {}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize& operator= (const CCSize& other) {
|
||||
inline constexpr CCSize& operator= (const CCSize& other) {
|
||||
setSize(other.width, other.height);
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize& operator= (const CCPoint& point) {
|
||||
inline constexpr CCSize& operator= (const CCPoint& point) {
|
||||
setSize(point.x, point.y);
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize operator+(const CCSize& right) const {
|
||||
inline constexpr CCSize operator+(const CCSize& right) const {
|
||||
return CCSize(this->width + right.width, this->height + right.height);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize operator-(const CCSize& right) const {
|
||||
inline constexpr CCSize operator-(const CCSize& right) const {
|
||||
return CCSize(this->width - right.width, this->height - right.height);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize operator*(float a) const {
|
||||
inline constexpr CCSize operator*(float a) const {
|
||||
return CCSize(this->width * a, this->height * a);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCSize operator/(float a) const {
|
||||
inline constexpr CCSize operator/(float a) const {
|
||||
return CCSize(this->width / a, this->height / a);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline void setSize(float width, float height) {
|
||||
inline constexpr void setSize(float width, float height) {
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline bool equals(const CCSize& target) const {
|
||||
return (fabs(this->width - target.width) < FLT_EPSILON) && (fabs(this->height - target.height) < FLT_EPSILON);
|
||||
inline constexpr bool equals(const CCSize& target) const {
|
||||
return this->fuzzyEquals(target, FLT_EPSILON);
|
||||
}
|
||||
|
||||
inline constexpr bool fuzzyEquals(const CCSize& b, float var) const {
|
||||
if(width - var <= b.width && b.width <= width + var)
|
||||
if(height - var <= b.height && b.height <= height + var)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Get the aspect ratio of this CCSize
|
||||
* @note Geode addition
|
||||
*/
|
||||
inline float aspect() const {
|
||||
inline constexpr float aspect() const {
|
||||
return this->width / this->height;
|
||||
}
|
||||
|
||||
void add(int, float);
|
||||
float at(int);
|
||||
void set(int, float);
|
||||
|
||||
constexpr void add(int idx, float val) {
|
||||
idx == 0 ? width += val : height += val;
|
||||
}
|
||||
constexpr float at(int idx) {
|
||||
return idx == 0 ? width : height;
|
||||
}
|
||||
constexpr bool isZero() const {
|
||||
return width == 0.f && height == 0.f;
|
||||
}
|
||||
constexpr void set(int idx, float val) {
|
||||
idx == 0 ? width = val : height = val;
|
||||
}
|
||||
constexpr void swap() {
|
||||
std::swap(width, height);
|
||||
}
|
||||
};
|
||||
|
||||
// alk cont
|
||||
|
||||
CCPoint::CCPoint(const CCSize& size) : x(size.width), y(size.height) {}
|
||||
constexpr CCPoint::CCPoint(const CCSize& size) : x(size.width), y(size.height) {}
|
||||
|
||||
CCPoint& CCPoint::operator= (const CCSize& size) {
|
||||
constexpr CCPoint& CCPoint::operator= (const CCSize& size) {
|
||||
setPoint(size.width, size.height);
|
||||
return *this;
|
||||
}
|
||||
|
@ -402,29 +430,29 @@ public:
|
|||
CCSize size;
|
||||
|
||||
public:
|
||||
inline CCRect() {
|
||||
inline constexpr CCRect() {
|
||||
setRect(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
inline CCRect(float x, float y, float width, float height) {
|
||||
inline constexpr CCRect(float x, float y, float width, float height) {
|
||||
setRect(x, y, width, height);
|
||||
}
|
||||
inline CCRect(CCPoint const& a, CCPoint const& b) {
|
||||
inline constexpr CCRect(CCPoint const& a, CCPoint const& b) {
|
||||
setRect(a.x, a.y, b.x, b.y);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCRect(const CCRect& other) {
|
||||
inline constexpr CCRect(const CCRect& other) {
|
||||
setRect(other.origin.x, other.origin.y, other.size.width, other.size.height);
|
||||
}
|
||||
/**
|
||||
* @lua NA
|
||||
*/
|
||||
inline CCRect& operator= (const CCRect& other) {
|
||||
inline constexpr CCRect& operator= (const CCRect& other) {
|
||||
setRect(other.origin.x, other.origin.y, other.size.width, other.size.height);
|
||||
return *this;
|
||||
}
|
||||
inline void setRect(float x, float y, float width, float height) {
|
||||
inline constexpr void setRect(float x, float y, float width, float height) {
|
||||
// CGRect can support width<0 or height<0
|
||||
// CCAssert(width >= 0.0f && height >= 0.0f, "width and height of Rect must not less than 0.");
|
||||
|
||||
|
@ -435,28 +463,28 @@ public:
|
|||
size.height = height;
|
||||
}
|
||||
|
||||
inline float getMinX() const {
|
||||
inline constexpr float getMinX() const {
|
||||
return origin.x;
|
||||
} /// return the leftmost x-value of current rect
|
||||
inline float getMidX() const {
|
||||
inline constexpr float getMidX() const {
|
||||
return (float)(origin.x + size.width / 2.0);
|
||||
} /// return the midpoint x-value of current rect
|
||||
inline float getMaxX() const {
|
||||
inline constexpr float getMaxX() const {
|
||||
return (float)(origin.x + size.width);
|
||||
} /// return the rightmost x-value of current rect
|
||||
inline float getMinY() const {
|
||||
inline constexpr float getMinY() const {
|
||||
return origin.y;
|
||||
} /// return the bottommost y-value of current rect
|
||||
inline float getMidY() const {
|
||||
inline constexpr float getMidY() const {
|
||||
return (float)(origin.y + size.height / 2.0);
|
||||
} /// return the midpoint y-value of current rect
|
||||
inline float getMaxY() const {
|
||||
inline constexpr float getMaxY() const {
|
||||
return origin.y + size.height;
|
||||
} /// return the topmost y-value of current rect
|
||||
inline bool equals(const CCRect& rect) const {
|
||||
inline constexpr bool equals(const CCRect& rect) const {
|
||||
return (origin.equals(rect.origin) && size.equals(rect.size));
|
||||
}
|
||||
inline bool containsPoint(const CCPoint& point) const {
|
||||
inline constexpr bool containsPoint(const CCPoint& point) const {
|
||||
bool bRet = false;
|
||||
|
||||
if (point.x >= getMinX() && point.x <= getMaxX()
|
||||
|
@ -468,7 +496,7 @@ public:
|
|||
return bRet;
|
||||
}
|
||||
|
||||
inline bool intersectsRect(const CCRect& rect) const {
|
||||
inline constexpr bool intersectsRect(const CCRect& rect) const {
|
||||
// lmao
|
||||
return !( getMaxX() < rect.getMinX() ||
|
||||
rect.getMaxX() < getMinX() ||
|
||||
|
@ -476,8 +504,12 @@ public:
|
|||
rect.getMaxY() < getMinY());
|
||||
}
|
||||
|
||||
float getMax(int);
|
||||
float getMin(int);
|
||||
constexpr float getMax(int idx) {
|
||||
return idx == 0 ? getMaxX() : getMaxY();
|
||||
}
|
||||
constexpr float getMin(int idx) {
|
||||
return idx == 0 ? getMinX() : getMinY();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
void drawPreciseCubicBezier(cocos2d::CCPoint const&, cocos2d::CCPoint const&, cocos2d::CCPoint const&, cocos2d::CCPoint const&, unsigned int, cocos2d::_ccColor4F const&);
|
||||
bool drawLines(cocos2d::CCPoint*, unsigned int, float, cocos2d::_ccColor4F const&);
|
||||
bool drawRect(cocos2d::CCPoint const&, cocos2d::CCPoint const&, cocos2d::_ccColor4F const&, float, cocos2d::_ccColor4F const&);
|
||||
bool drawRect(cocos2d::CCRect const&, cocos2d::_ccColor4F const&, float, cocos2d::_ccColor4F const&);
|
||||
void disableDrawArea();
|
||||
void enableDrawArea(cocos2d::CCRect& rect);
|
||||
#else
|
||||
|
|
|
@ -274,9 +274,9 @@ public:
|
|||
void limitLabelWidth(float width, float defaultScale, float minScale);
|
||||
|
||||
// @note RobTop Addition
|
||||
int getExtraKerning() const;
|
||||
inline int getExtraKerning() const { return m_nExtraKerning; }
|
||||
// @note RobTop Addition
|
||||
void setExtraKerning(int);
|
||||
inline void setExtraKerning(int extraKerning) { m_nExtraKerning = extraKerning; }
|
||||
|
||||
// @note RobTop Addition
|
||||
bool getIsBatched() const;
|
||||
|
@ -337,7 +337,7 @@ protected:
|
|||
// @note RobTop Addition
|
||||
CCTexture2D* m_pSomeTexture;
|
||||
// @note RobTop Addition
|
||||
void* m_pUnknown; // 2.2 addition, might be positioned somewhere else
|
||||
int m_nExtraKerning;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -71,13 +71,7 @@ THE SOFTWARE.
|
|||
#include "./compat/stdint.h"
|
||||
#endif
|
||||
|
||||
#define _WINSOCKAPI_
|
||||
// Structure timeval has define in winsock.h, include windows.h for it.
|
||||
#include <Windows.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
|
||||
// #include <WinSock2.h>
|
||||
struct timeval;
|
||||
|
||||
NS_CC_BEGIN
|
||||
|
||||
|
@ -91,11 +85,5 @@ int CC_DLL gettimeofday(struct timeval *, struct timezone *);
|
|||
|
||||
NS_CC_END
|
||||
|
||||
#else
|
||||
|
||||
#include <winsock.h>
|
||||
|
||||
#endif // __MINGW32__
|
||||
|
||||
#endif // __CC_STD_C_H__
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ class CCLightning : public CCNode, public CCRGBAProtocol {
|
|||
public:
|
||||
CCLightning();
|
||||
virtual ~CCLightning();
|
||||
GEODE_CUTOFF_CONSTRUCTOR_GD(CCLightning, CCNode);
|
||||
|
||||
static CCLightning* lightningWithStrikePoint(CCPoint strikePoint, CCPoint strikePoint2, float duration);
|
||||
static CCLightning* lightningWithStrikePoint(CCPoint strikePoint);
|
||||
|
@ -67,4 +68,4 @@ protected:
|
|||
|
||||
NS_CC_END
|
||||
|
||||
#endif //__CCLIGHTNING_H__
|
||||
#endif //__CCLIGHTNING_H__
|
||||
|
|
|
@ -56,4 +56,9 @@ namespace geode::dirs {
|
|||
* Directory where crashlogs are stored
|
||||
*/
|
||||
GEODE_DLL std::filesystem::path getCrashlogsDir();
|
||||
/**
|
||||
* Directory where mods' persistent files lie
|
||||
* This directory is not deleted even when Geode is uninstalled
|
||||
*/
|
||||
GEODE_DLL std::filesystem::path getModPersistentDir();
|
||||
}
|
||||
|
|
|
@ -172,6 +172,11 @@ namespace geode {
|
|||
* Get the mod's config directory path
|
||||
*/
|
||||
std::filesystem::path getConfigDir(bool create = true) const;
|
||||
/**
|
||||
* Get the mod's persistent directory path
|
||||
* This directory is not deleted even when Geode/mod is uninstalled
|
||||
*/
|
||||
std::filesystem::path getPersistentDir(bool create = true) const;
|
||||
|
||||
/**
|
||||
* Returns true if this mod has any settings
|
||||
|
|
|
@ -4,12 +4,16 @@
|
|||
#include "SettingV3.hpp"
|
||||
|
||||
namespace geode {
|
||||
class Mod;
|
||||
class SettingV3;
|
||||
|
||||
class GEODE_DLL ModSettingsManager final {
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> m_impl;
|
||||
|
||||
friend class ::geode::SettingV3;
|
||||
friend class ::geode::Mod;
|
||||
|
||||
void markRestartRequired();
|
||||
|
||||
|
@ -36,9 +40,22 @@ namespace geode {
|
|||
* The format of the savedata will be an object with the keys being
|
||||
* setting IDs and then the values the values of the saved settings
|
||||
* @note If saving a setting fails, it will log a warning to the console
|
||||
* @warning This will overwrite the whole `json` parameter - be sure to
|
||||
* pass the full settings savedata to `load()` so you can be sure that
|
||||
* unregistered custom settings' saved values don't disappear!
|
||||
* @todo in v4: make this return the value instead lol
|
||||
*/
|
||||
void save(matjson::Value& json);
|
||||
|
||||
/**
|
||||
* Get the savedata for settings, aka the JSON object that contains all
|
||||
* the settings' saved states that was loaded up from disk and will be
|
||||
* saved to disk
|
||||
* @warning Modifying this will modify the value of the settings - use
|
||||
* carefully!
|
||||
*/
|
||||
matjson::Value& getSaveData();
|
||||
|
||||
Result<> registerCustomSettingType(std::string_view type, SettingGenerator generator);
|
||||
// todo in v4: remove this
|
||||
Result<> registerLegacyCustomSetting(std::string_view key, std::unique_ptr<SettingValue>&& ptr);
|
||||
|
|
|
@ -324,8 +324,8 @@ namespace geode {
|
|||
}
|
||||
|
||||
bool load(matjson::Value const& json) override {
|
||||
if (json.template is<T>()) {
|
||||
m_impl->value = json.template as<T>();
|
||||
if (json.is<T>()) {
|
||||
m_impl->value = json.as<T>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace geode {
|
|||
public:
|
||||
static ListBorders* create();
|
||||
|
||||
void setSpriteFrames(const char* topAndBottom, const char* sides, float topPadding = 7.5f);
|
||||
void setSpriteFrames(const char* topAndBottom, const char* sides, float horizontalPadding = 7.5f);
|
||||
void setSprites(
|
||||
cocos2d::extension::CCScale9Sprite* top,
|
||||
cocos2d::extension::CCScale9Sprite* bottom,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../loader/Mod.hpp"
|
||||
#include <Geode/binding/FLAlertLayer.hpp>
|
||||
#include <Geode/ui/Popup.hpp>
|
||||
|
||||
class ModPopup;
|
||||
class ModItem;
|
||||
|
@ -141,6 +142,16 @@ namespace geode {
|
|||
* Open the settings popup for a mod (if it has any settings)
|
||||
*/
|
||||
GEODE_DLL void openSettingsPopup(Mod* mod);
|
||||
/**
|
||||
* Open the settings popup for a mod (if it has any settings)
|
||||
* @param mod Mod the open the popup for
|
||||
* @param disableGeodeTheme If false, the popup follows the user's chosen
|
||||
* theme options. If true, the popup is always in the GD theme (not Geode's
|
||||
* dark purple colors)
|
||||
* @returns A pointer to the created Popup, or null if the mod has no
|
||||
* settings
|
||||
*/
|
||||
GEODE_DLL Popup<Mod*>* openSettingsPopup(Mod* mod, bool disableGeodeTheme);
|
||||
/**
|
||||
* Create a default logo sprite
|
||||
*/
|
||||
|
|
|
@ -6,8 +6,59 @@
|
|||
#include <Geode/utils/cocos.hpp>
|
||||
|
||||
namespace geode {
|
||||
template <typename... InitArgs>
|
||||
template <class... InitArgs>
|
||||
class Popup : public FLAlertLayer {
|
||||
public:
|
||||
/**
|
||||
* Event posted when this popup is being closed
|
||||
*/
|
||||
class CloseEvent final : public ::geode::Event {
|
||||
private:
|
||||
class Impl final {
|
||||
private:
|
||||
Popup* popup;
|
||||
friend class CloseEvent;
|
||||
};
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
friend class Popup;
|
||||
|
||||
CloseEvent(Popup* popup) : m_impl(std::make_shared<Impl>()) {
|
||||
m_impl->popup = popup;
|
||||
}
|
||||
|
||||
public:
|
||||
Popup* getPopup() const {
|
||||
return m_impl->popup;
|
||||
}
|
||||
};
|
||||
class CloseEventFilter final : public ::geode::EventFilter<CloseEvent> {
|
||||
public:
|
||||
using Callback = void(CloseEvent*);
|
||||
|
||||
private:
|
||||
class Impl final {
|
||||
private:
|
||||
Popup* popup;
|
||||
friend class CloseEventFilter;
|
||||
};
|
||||
std::shared_ptr<Impl> m_impl;
|
||||
|
||||
friend class Popup;
|
||||
|
||||
CloseEventFilter(Popup* popup) : m_impl(std::make_shared<Impl>()) {
|
||||
m_impl->popup = popup;
|
||||
}
|
||||
|
||||
public:
|
||||
ListenerResult handle(utils::MiniFunction<Callback> fn, CloseEvent* event) {
|
||||
if (event->getPopup() == m_impl->popup) {
|
||||
fn(event);
|
||||
}
|
||||
return ListenerResult::Propagate;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
cocos2d::CCSize m_size;
|
||||
cocos2d::extension::CCScale9Sprite* m_bgSprite;
|
||||
|
@ -115,6 +166,7 @@ namespace geode {
|
|||
}
|
||||
|
||||
virtual void onClose(cocos2d::CCObject*) {
|
||||
CloseEvent(this).post();
|
||||
this->setKeypadEnabled(false);
|
||||
this->setTouchEnabled(false);
|
||||
this->removeFromParentAndCleanup(true);
|
||||
|
@ -158,6 +210,13 @@ namespace geode {
|
|||
spr->setAnchorPoint(orig->getAnchorPoint());
|
||||
m_closeBtn->setContentSize(origSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an event filter that listens for when this popup is closed
|
||||
*/
|
||||
CloseEventFilter listenForClose() {
|
||||
return CloseEventFilter(this);
|
||||
}
|
||||
};
|
||||
|
||||
GEODE_DLL FLAlertLayer* createQuickPopup(
|
||||
|
|
|
@ -3,28 +3,40 @@
|
|||
#include "../DefaultInclude.hpp"
|
||||
|
||||
#include <cocos2d.h>
|
||||
|
||||
namespace cocos2d {
|
||||
class CCArray;
|
||||
class CCNode;
|
||||
}
|
||||
#include <vector>
|
||||
#include <span>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
|
||||
namespace geode {
|
||||
class GEODE_DLL SceneManager final {
|
||||
protected:
|
||||
cocos2d::CCArray* m_persistedNodes;
|
||||
std::vector<Ref<cocos2d::CCNode>> m_persistedNodes;
|
||||
cocos2d::CCScene* m_lastScene = nullptr;
|
||||
|
||||
bool setup();
|
||||
|
||||
virtual ~SceneManager();
|
||||
|
||||
public:
|
||||
static SceneManager* get();
|
||||
|
||||
/**
|
||||
* Adds a node to the list of persisted nodes, which are kept across scene changes.
|
||||
* @param node The node to keep across scenes.
|
||||
*/
|
||||
void keepAcrossScenes(cocos2d::CCNode* node);
|
||||
|
||||
/**
|
||||
* Removes a node from the list of persisted nodes.
|
||||
* @param node The node to forget.
|
||||
*/
|
||||
void forget(cocos2d::CCNode* node);
|
||||
|
||||
/**
|
||||
* Gets a span of the persisted nodes. To add new nodes to the list, use keepAcrossScenes.
|
||||
*/
|
||||
std::span<Ref<cocos2d::CCNode> const> getPersistedNodes();
|
||||
|
||||
// This method should only be called by geode itself
|
||||
// TODO(v4): hide this
|
||||
void willSwitchToScene(cocos2d::CCScene* scene);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <set>
|
||||
#include <variant>
|
||||
#include <Geode/utils/MiniFunction.hpp>
|
||||
#include <Geode/utils/Result.hpp>
|
||||
|
||||
namespace geode {
|
||||
struct JsonChecker;
|
||||
|
@ -147,14 +148,14 @@ namespace geode {
|
|||
template <class T>
|
||||
bool is() {
|
||||
if (this->isError()) return false;
|
||||
return self().m_json.template is<T>();
|
||||
return self().m_json.is<T>();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
JsonMaybeValue& validate(JsonValueValidator<T> validator) {
|
||||
if (this->isError()) return *this;
|
||||
if (self().m_json.template is<T>()) {
|
||||
if (!validator(self().m_json.template as<T>())) {
|
||||
if (self().m_json.is<T>()) {
|
||||
if (!validator(self().m_json.as<T>())) {
|
||||
this->setError(self().m_hierarchy + ": Invalid value format");
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +196,9 @@ namespace geode {
|
|||
this->inferType<A>();
|
||||
if (this->isError()) return *this;
|
||||
|
||||
if (self().m_json.template is<A>()) {
|
||||
if (self().m_json.is<A>()) {
|
||||
try {
|
||||
target = self().m_json.template as<A>();
|
||||
target = self().m_json.as<A>();
|
||||
}
|
||||
catch(matjson::JsonException const& e) {
|
||||
this->setError(
|
||||
|
@ -219,8 +220,8 @@ namespace geode {
|
|||
T get() {
|
||||
this->inferType<T>();
|
||||
if (this->isError()) return T();
|
||||
if (self().m_json.template is<T>()) {
|
||||
return self().m_json.template as<T>();
|
||||
if (self().m_json.is<T>()) {
|
||||
return self().m_json.as<T>();
|
||||
}
|
||||
return T();
|
||||
}
|
||||
|
@ -325,8 +326,8 @@ namespace geode {
|
|||
}
|
||||
else {
|
||||
try {
|
||||
if (this->getJSONRef().template is<T>()) {
|
||||
return this->getJSONRef().template as<T>();
|
||||
if (this->getJSONRef().is<T>()) {
|
||||
return this->getJSONRef().as<T>();
|
||||
}
|
||||
else {
|
||||
this->setError(
|
||||
|
@ -396,21 +397,21 @@ namespace geode {
|
|||
|
||||
template <class T>
|
||||
T get(T const& defaultValue = T()) {
|
||||
if (auto v = this->template tryGet<T>()) {
|
||||
if (auto v = this->tryGet<T>()) {
|
||||
return *std::move(v);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
template <class T>
|
||||
JsonExpectedValue& into(T& value) {
|
||||
if (auto v = this->template tryGet<T>()) {
|
||||
if (auto v = this->tryGet<T>()) {
|
||||
value = *std::move(v);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
template <class T>
|
||||
JsonExpectedValue& into(std::optional<T>& value) {
|
||||
if (auto v = this->template tryGet<T>()) {
|
||||
if (auto v = this->tryGet<T>()) {
|
||||
value.emplace(*std::move(v));
|
||||
}
|
||||
return *this;
|
||||
|
@ -420,7 +421,7 @@ namespace geode {
|
|||
{ predicate(std::declval<T>()) } -> std::convertible_to<bool>;
|
||||
} {
|
||||
if (this->hasError()) return *this;
|
||||
if (auto v = this->template tryGet<T>()) {
|
||||
if (auto v = this->tryGet<T>()) {
|
||||
if (!predicate(*v)) {
|
||||
this->setError("json value is not {}", name);
|
||||
}
|
||||
|
@ -432,7 +433,7 @@ namespace geode {
|
|||
{ predicate(std::declval<T>()) } -> std::convertible_to<Result<>>;
|
||||
} {
|
||||
if (this->hasError()) return *this;
|
||||
if (auto v = this->template tryGet<T>()) {
|
||||
if (auto v = this->tryGet<T>()) {
|
||||
auto p = predicate(*v);
|
||||
if (!p) {
|
||||
this->setError("json value is not {}: {}", name, p.unwrapErr());
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace geode::node_ids {
|
|||
return child;
|
||||
}
|
||||
} else {
|
||||
if (auto child = cocos::getChildOfType<T>(node, index)) {
|
||||
if (auto child = node->getChildByType<T>(index)) {
|
||||
child->setID(id);
|
||||
return child;
|
||||
}
|
||||
|
|
|
@ -30,28 +30,28 @@ struct matjson::Serialize<cocos2d::ccColor4B> {
|
|||
|
||||
// operators for CC geometry
|
||||
namespace cocos2d {
|
||||
static cocos2d::CCPoint& operator*=(cocos2d::CCPoint& pos, float mul) {
|
||||
static constexpr cocos2d::CCPoint& operator*=(cocos2d::CCPoint& pos, float mul) {
|
||||
pos.x *= mul;
|
||||
pos.y *= mul;
|
||||
return pos;
|
||||
}
|
||||
static cocos2d::CCSize& operator*=(cocos2d::CCSize& size, float mul) {
|
||||
static constexpr cocos2d::CCSize& operator*=(cocos2d::CCSize& size, float mul) {
|
||||
size.width *= mul;
|
||||
size.height *= mul;
|
||||
return size;
|
||||
}
|
||||
static cocos2d::CCSize operator*(cocos2d::CCSize const& size, cocos2d::CCPoint const& point) {
|
||||
static constexpr cocos2d::CCSize operator*(cocos2d::CCSize const& size, cocos2d::CCPoint const& point) {
|
||||
return {
|
||||
size.width * point.x,
|
||||
size.height * point.y,
|
||||
};
|
||||
}
|
||||
static cocos2d::CCRect operator*=(cocos2d::CCRect& rect, float mul) {
|
||||
static constexpr cocos2d::CCRect operator*=(cocos2d::CCRect& rect, float mul) {
|
||||
rect.origin *= mul;
|
||||
rect.size *= mul;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCRect operator*(cocos2d::CCRect const& rect, float mul) {
|
||||
static constexpr cocos2d::CCRect operator*(cocos2d::CCRect const& rect, float mul) {
|
||||
return {
|
||||
rect.origin.x * mul,
|
||||
rect.origin.y * mul,
|
||||
|
@ -59,131 +59,131 @@ namespace cocos2d {
|
|||
rect.size.height * mul,
|
||||
};
|
||||
}
|
||||
static cocos2d::CCPoint operator/=(cocos2d::CCPoint& pos, float div) {
|
||||
static constexpr cocos2d::CCPoint operator/=(cocos2d::CCPoint& pos, float div) {
|
||||
pos.x /= div;
|
||||
pos.y /= div;
|
||||
return pos;
|
||||
}
|
||||
static cocos2d::CCSize operator/=(cocos2d::CCSize& size, float div) {
|
||||
static constexpr cocos2d::CCSize operator/=(cocos2d::CCSize& size, float div) {
|
||||
size.width /= div;
|
||||
size.height /= div;
|
||||
return size;
|
||||
}
|
||||
static cocos2d::CCRect operator/=(cocos2d::CCRect& rect, float div) {
|
||||
static constexpr cocos2d::CCRect operator/=(cocos2d::CCRect& rect, float div) {
|
||||
rect.origin /= div;
|
||||
rect.size /= div;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCPoint operator+=(cocos2d::CCPoint& pos, cocos2d::CCPoint const& add) {
|
||||
static constexpr cocos2d::CCPoint operator+=(cocos2d::CCPoint& pos, cocos2d::CCPoint const& add) {
|
||||
pos.x += add.x;
|
||||
pos.y += add.y;
|
||||
return pos;
|
||||
}
|
||||
static cocos2d::CCSize operator+=(cocos2d::CCSize& size, cocos2d::CCPoint const& add) {
|
||||
static constexpr cocos2d::CCSize operator+=(cocos2d::CCSize& size, cocos2d::CCPoint const& add) {
|
||||
size.width += add.x;
|
||||
size.height += add.y;
|
||||
return size;
|
||||
}
|
||||
static cocos2d::CCSize operator+=(cocos2d::CCSize& size, cocos2d::CCSize const& add) {
|
||||
static constexpr cocos2d::CCSize operator+=(cocos2d::CCSize& size, cocos2d::CCSize const& add) {
|
||||
size.width += add.width;
|
||||
size.height += add.height;
|
||||
return size;
|
||||
}
|
||||
static cocos2d::CCRect operator+=(cocos2d::CCRect& rect, cocos2d::CCPoint const& add) {
|
||||
static constexpr cocos2d::CCRect operator+=(cocos2d::CCRect& rect, cocos2d::CCPoint const& add) {
|
||||
rect.origin += add;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCRect operator+=(cocos2d::CCRect& rect, cocos2d::CCSize const& add) {
|
||||
static constexpr cocos2d::CCRect operator+=(cocos2d::CCRect& rect, cocos2d::CCSize const& add) {
|
||||
rect.size += add;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCRect operator+=(cocos2d::CCRect& rect, cocos2d::CCRect const& add) {
|
||||
static constexpr cocos2d::CCRect operator+=(cocos2d::CCRect& rect, cocos2d::CCRect const& add) {
|
||||
rect.origin += add.origin;
|
||||
rect.size += add.size;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCPoint operator-=(cocos2d::CCPoint& pos, cocos2d::CCPoint const& add) {
|
||||
static constexpr cocos2d::CCPoint operator-=(cocos2d::CCPoint& pos, cocos2d::CCPoint const& add) {
|
||||
pos.x -= add.x;
|
||||
pos.y -= add.y;
|
||||
return pos;
|
||||
}
|
||||
static cocos2d::CCSize operator-=(cocos2d::CCSize& size, cocos2d::CCPoint const& add) {
|
||||
static constexpr cocos2d::CCSize operator-=(cocos2d::CCSize& size, cocos2d::CCPoint const& add) {
|
||||
size.width -= add.x;
|
||||
size.height -= add.y;
|
||||
return size;
|
||||
}
|
||||
static cocos2d::CCSize operator-=(cocos2d::CCSize& size, cocos2d::CCSize const& add) {
|
||||
static constexpr cocos2d::CCSize operator-=(cocos2d::CCSize& size, cocos2d::CCSize const& add) {
|
||||
size.width -= add.width;
|
||||
size.height -= add.height;
|
||||
return size;
|
||||
}
|
||||
static cocos2d::CCRect operator-=(cocos2d::CCRect& rect, cocos2d::CCPoint const& add) {
|
||||
static constexpr cocos2d::CCRect operator-=(cocos2d::CCRect& rect, cocos2d::CCPoint const& add) {
|
||||
rect.origin -= add;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCRect operator-=(cocos2d::CCRect& rect, cocos2d::CCSize const& add) {
|
||||
static constexpr cocos2d::CCRect operator-=(cocos2d::CCRect& rect, cocos2d::CCSize const& add) {
|
||||
rect.size -= add;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCRect operator-=(cocos2d::CCRect& rect, cocos2d::CCRect const& add) {
|
||||
static constexpr cocos2d::CCRect operator-=(cocos2d::CCRect& rect, cocos2d::CCRect const& add) {
|
||||
rect.origin -= add.origin;
|
||||
rect.size -= add.size;
|
||||
return rect;
|
||||
}
|
||||
static cocos2d::CCSize operator-(cocos2d::CCSize const& size, float f) {
|
||||
static constexpr cocos2d::CCSize operator-(cocos2d::CCSize const& size, float f) {
|
||||
return {size.width - f, size.height - f};
|
||||
}
|
||||
static cocos2d::CCSize operator-(cocos2d::CCSize const& size) {
|
||||
static constexpr cocos2d::CCSize operator-(cocos2d::CCSize const& size) {
|
||||
return {-size.width, -size.height};
|
||||
}
|
||||
static bool operator==(cocos2d::CCPoint const& p1, cocos2d::CCPoint const& p2) {
|
||||
static constexpr bool operator==(cocos2d::CCPoint const& p1, cocos2d::CCPoint const& p2) {
|
||||
return p1.x == p2.x && p1.y == p2.y;
|
||||
}
|
||||
static bool operator!=(cocos2d::CCPoint const& p1, cocos2d::CCPoint const& p2) {
|
||||
static constexpr bool operator!=(cocos2d::CCPoint const& p1, cocos2d::CCPoint const& p2) {
|
||||
return p1.x != p2.x || p1.y != p2.y;
|
||||
}
|
||||
static bool operator==(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
static constexpr bool operator==(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
return s1.width == s2.width && s1.height == s2.height;
|
||||
}
|
||||
static bool operator!=(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
static constexpr bool operator!=(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
return s1.width != s2.width || s1.height != s2.height;
|
||||
}
|
||||
static bool operator<(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
static constexpr bool operator<(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
return s1.width < s2.width && s1.height < s2.height;
|
||||
}
|
||||
static bool operator<=(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
static constexpr bool operator<=(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
return s1.width <= s2.width && s1.height <= s2.height;
|
||||
}
|
||||
static bool operator>(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
static constexpr bool operator>(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
return s1.width > s2.width && s1.height > s2.height;
|
||||
}
|
||||
static bool operator>=(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
static constexpr bool operator>=(cocos2d::CCSize const& s1, cocos2d::CCSize const& s2) {
|
||||
return s1.width >= s2.width && s1.height >= s2.height;
|
||||
}
|
||||
static bool operator==(cocos2d::CCRect const& r1, cocos2d::CCRect const& r2) {
|
||||
static constexpr bool operator==(cocos2d::CCRect const& r1, cocos2d::CCRect const& r2) {
|
||||
return r1.origin == r2.origin && r1.size == r2.size;
|
||||
}
|
||||
static bool operator!=(cocos2d::CCRect const& r1, cocos2d::CCRect const& r2) {
|
||||
static constexpr bool operator!=(cocos2d::CCRect const& r1, cocos2d::CCRect const& r2) {
|
||||
return r1.origin != r2.origin || r1.size != r2.size;
|
||||
}
|
||||
static bool operator==(cocos2d::ccColor4B const& c1, cocos2d::ccColor4B const& c2) {
|
||||
static constexpr bool operator==(cocos2d::ccColor4B const& c1, cocos2d::ccColor4B const& c2) {
|
||||
return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b && c1.a == c2.a;
|
||||
}
|
||||
static bool operator!=(cocos2d::ccColor4B const& c1, cocos2d::ccColor4B const& c2) {
|
||||
static constexpr bool operator!=(cocos2d::ccColor4B const& c1, cocos2d::ccColor4B const& c2) {
|
||||
return c1.r != c2.r || c1.g != c2.g || c1.b != c2.b || c1.a != c2.a;
|
||||
}
|
||||
static bool operator==(cocos2d::ccColor3B const& c1, cocos2d::ccColor3B const& c2) {
|
||||
static constexpr bool operator==(cocos2d::ccColor3B const& c1, cocos2d::ccColor3B const& c2) {
|
||||
return c1.r == c2.r && c1.g == c2.g && c1.b == c2.b;
|
||||
}
|
||||
static bool operator!=(cocos2d::ccColor3B const& c1, cocos2d::ccColor3B const& c2) {
|
||||
static constexpr bool operator!=(cocos2d::ccColor3B const& c1, cocos2d::ccColor3B const& c2) {
|
||||
return c1.r != c2.r || c1.g != c2.g || c1.b != c2.b;
|
||||
}
|
||||
static bool operator==(cocos2d::ccHSVValue const& c1, cocos2d::ccHSVValue const& c2) {
|
||||
static constexpr bool operator==(cocos2d::ccHSVValue const& c1, cocos2d::ccHSVValue const& c2) {
|
||||
return c1.h == c2.h && c1.s == c2.s && c1.v == c2.v &&
|
||||
c1.absoluteSaturation == c2.absoluteSaturation &&
|
||||
c1.absoluteBrightness == c2.absoluteBrightness;
|
||||
}
|
||||
static bool operator!=(cocos2d::ccHSVValue const& c1, cocos2d::ccHSVValue const& c2) {
|
||||
static constexpr bool operator!=(cocos2d::ccHSVValue const& c1, cocos2d::ccHSVValue const& c2) {
|
||||
return !(c1 == c2);
|
||||
}
|
||||
}
|
||||
|
@ -620,37 +620,11 @@ namespace geode::cocos {
|
|||
* @returns Child at index cast to the given type,
|
||||
* or nullptr if index exceeds bounds
|
||||
*/
|
||||
template <class Type = cocos2d::CCNode>
|
||||
static Type* getChildOfType(cocos2d::CCNode* node, int index) {
|
||||
size_t indexCounter = 0;
|
||||
if (node->getChildrenCount() == 0) return nullptr;
|
||||
// start from end for negative index
|
||||
if (index < 0) {
|
||||
index = -index - 1;
|
||||
for (size_t i = node->getChildrenCount() - 1; i >= 0; i--) {
|
||||
auto obj = cast::typeinfo_cast<Type*>(node->getChildren()->objectAtIndex(i));
|
||||
if (obj != nullptr) {
|
||||
if (indexCounter == index) {
|
||||
return obj;
|
||||
}
|
||||
++indexCounter;
|
||||
}
|
||||
if (i == 0) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < node->getChildrenCount(); i++) {
|
||||
auto obj = cast::typeinfo_cast<Type*>(node->getChildren()->objectAtIndex(i));
|
||||
if (obj != nullptr) {
|
||||
if (indexCounter == index) {
|
||||
return obj;
|
||||
}
|
||||
++indexCounter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
template <class Type = cocos2d::CCNode>
|
||||
[[deprecated("Use CCNode::getChildByType instead")]]
|
||||
static Type* getChildOfType(cocos2d::CCNode* node, int index) {
|
||||
return node->getChildByType<Type>(index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -997,7 +971,8 @@ namespace std {
|
|||
template <typename T>
|
||||
struct std::hash<geode::WeakRef<T>> {
|
||||
size_t operator()(geode::WeakRef<T> const& ref) const {
|
||||
return hash{}(ref.m_controller);
|
||||
// the explicit template argument is needed here because it would otherwise cast to WeakRef and recurse
|
||||
return hash<std::shared_ptr<geode::WeakRefController>>{}(ref.m_controller);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1105,7 +1080,7 @@ namespace geode::cocos {
|
|||
}
|
||||
|
||||
T* pop_back() {
|
||||
T ret = m_arr->lastObject();
|
||||
T* ret = static_cast<T*>(m_arr->lastObject());
|
||||
m_arr->removeLastObject();
|
||||
return ret;
|
||||
}
|
||||
|
@ -1388,6 +1363,42 @@ namespace geode::cocos {
|
|||
}
|
||||
};
|
||||
|
||||
// CCCallFunc alternative that accepts a lambda (or any function object)
|
||||
template <std::invocable F>
|
||||
class CallFuncExtImpl : public cocos2d::CCActionInstant {
|
||||
public:
|
||||
static CallFuncExtImpl* create(const F& func) {
|
||||
auto ret = new CallFuncExtImpl;
|
||||
ret->m_func = func;
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static CallFuncExtImpl* create(F&& func) {
|
||||
auto ret = new CallFuncExtImpl;
|
||||
ret->m_func = std::move(func);
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
F m_func;
|
||||
|
||||
void update(float) override {
|
||||
if (m_func) this->m_func();
|
||||
}
|
||||
};
|
||||
|
||||
// small hack to allow template deduction
|
||||
struct CallFuncExt {
|
||||
template <std::invocable F>
|
||||
static auto create(F&& func) {
|
||||
using Fd = std::decay_t<F>;
|
||||
|
||||
return CallFuncExtImpl<Fd>::create(std::forward<F>(func));
|
||||
}
|
||||
};
|
||||
|
||||
void GEODE_DLL handleTouchPriorityWith(cocos2d::CCNode* node, int priority, bool force = false);
|
||||
void GEODE_DLL handleTouchPriority(cocos2d::CCNode* node, bool force = false);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ struct matjson::Serialize<std::filesystem::path> {
|
|||
return path.string();
|
||||
}
|
||||
static std::filesystem::path from_json(matjson::Value const& value) {
|
||||
return value.as_string();
|
||||
return std::filesystem::path(value.as_string()).make_preferred();
|
||||
}
|
||||
static bool is_json(matjson::Value const& value) {
|
||||
return value.is_string();
|
||||
|
@ -32,10 +32,10 @@ namespace geode::utils::file {
|
|||
template <class T>
|
||||
Result<T> readFromJson(std::filesystem::path const& file) {
|
||||
GEODE_UNWRAP_INTO(auto json, readJson(file));
|
||||
if (!json.template is<T>()) {
|
||||
if (!json.is<T>()) {
|
||||
return Err("JSON is not of type {}", typeid(T).name());
|
||||
}
|
||||
return Ok(json.template as<T>());
|
||||
return Ok(json.as<T>());
|
||||
}
|
||||
|
||||
GEODE_DLL Result<> writeString(std::filesystem::path const& path, std::string const& data);
|
||||
|
|
|
@ -99,9 +99,22 @@ namespace geode {
|
|||
*/
|
||||
template <std::integral Num>
|
||||
std::string numToAbbreviatedString(Num num) {
|
||||
if (num >= 1'000'000'000) return fmt::format("{:0.3}B", num / 1'000'000'000.f);
|
||||
if (num >= 1'000'000) return fmt::format("{:0.3}M", num / 1'000'000.f);
|
||||
if (num >= 1'000) return fmt::format("{:0.3}K", num / 1'000.f);
|
||||
// it's a mess... i'm sorry...
|
||||
constexpr auto numToFixedTrunc = [](float num) {
|
||||
|
||||
// calculate the number of digits we keep from the decimal
|
||||
auto remaining = std::max(3 - static_cast<int>(std::log10(num)) - 1, 0);
|
||||
|
||||
auto factor = std::pow(10, remaining);
|
||||
auto trunc = std::trunc(num * factor) / factor;
|
||||
|
||||
// doing this dynamic format thing lets the .0 show when needed
|
||||
return fmt::format("{:0.{}f}", trunc, static_cast<int>(remaining));
|
||||
};
|
||||
|
||||
if (num >= 1'000'000'000) return fmt::format("{}B", numToFixedTrunc(num / 1'000'000'000.f));
|
||||
if (num >= 1'000'000) return fmt::format("{}M", numToFixedTrunc(num / 1'000'000.f));
|
||||
if (num >= 1'000) return fmt::format("{}K", numToFixedTrunc(num / 1'000.f));
|
||||
return numToString(num);
|
||||
}
|
||||
|
||||
|
@ -137,8 +150,9 @@ namespace geode {
|
|||
if constexpr (std::is_floating_point_v<Num>) res = std::from_chars(str.data(), str.data() + str.size(), result);
|
||||
else res = std::from_chars(str.data(), str.data() + str.size(), result, base);
|
||||
|
||||
auto [_, ec] = res;
|
||||
auto [ptr, ec] = res;
|
||||
if (ec == std::errc()) return Ok(result);
|
||||
else if (ptr != str.data() + str.size()) return Err("String contains trailing extra data");
|
||||
else if (ec == std::errc::invalid_argument) return Err("String is not a number");
|
||||
else if (ec == std::errc::result_out_of_range) return Err("Number is too large to fit");
|
||||
else return Err("Unknown error");
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/DefaultInclude.hpp>
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <compare>
|
||||
|
||||
namespace geode::utils::string {
|
||||
/**
|
||||
|
@ -64,4 +64,10 @@ namespace geode::utils::string {
|
|||
|
||||
GEODE_DLL bool startsWith(std::string const& str, std::string const& prefix);
|
||||
GEODE_DLL bool endsWith(std::string const& str, std::string const& suffix);
|
||||
|
||||
/**
|
||||
* Similar to strcmp, but case insensitive.
|
||||
* Uses std::tolower, but could change in the future for better locale support
|
||||
*/
|
||||
GEODE_DLL std::strong_ordering caseInsensitiveCompare(std::string_view a, std::string_view b);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ constexpr static auto MAX_PATH_CHARS = 32768u;
|
|||
static HMODULE getXInput() {
|
||||
static auto xinput = []() -> HMODULE {
|
||||
std::wstring path(MAX_PATH_CHARS, L'\0');
|
||||
auto size = GetSystemDirectoryW(const_cast<wchar_t*>(path.data()), path.size());
|
||||
auto size = GetSystemDirectoryW(path.data(), path.size());
|
||||
if (size) {
|
||||
path.resize(size);
|
||||
return LoadLibraryW((path + L"\\XInput1_4.dll").c_str());
|
||||
|
|
|
@ -60,6 +60,9 @@
|
|||
],
|
||||
"BlankSheet": [
|
||||
"blanks/*.png"
|
||||
],
|
||||
"EventSheet": [
|
||||
"modtober/*.png"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
BIN
loader/resources/modtober/modtober24-banner-2.png
Normal file
BIN
loader/resources/modtober/modtober24-banner-2.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 101 KiB |
BIN
loader/resources/modtober/modtober24-banner.png
Normal file
BIN
loader/resources/modtober/modtober24-banner.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 83 KiB |
BIN
loader/resources/modtober/modtober24-popup.png
Normal file
BIN
loader/resources/modtober/modtober24-popup.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1 MiB |
BIN
loader/resources/persistent.png
Normal file
BIN
loader/resources/persistent.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 12 KiB |
BIN
loader/resources/save.png
Normal file
BIN
loader/resources/save.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 8.9 KiB |
Binary file not shown.
Before ![]() (image error) Size: 9.4 KiB After ![]() (image error) Size: 11 KiB ![]() ![]() |
BIN
loader/resources/tag-modtober.png
Normal file
BIN
loader/resources/tag-modtober.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 39 KiB |
|
@ -123,7 +123,7 @@ struct FileUtilsUpdatePaths : Modify<FileUtilsUpdatePaths, CCFileUtils> {
|
|||
// this is only an issue because cocos itself requests the full path for this in CCSprite,
|
||||
// and with a lot of search paths (specially ones added by geode), this can cause a significant amount of lag.
|
||||
// GJ_GameSheetIcons.png comes from an improper plist distributed in GDS :P
|
||||
if (filename == "cc_2x2_white_image"sv || filename == "GJ_GameSheetIcons.png"sv) {
|
||||
if (filename == "cc_2x2_white_image"sv) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ CCNode* CCNode::querySelector(std::string const& queryStr) {
|
|||
return nullptr;
|
||||
}
|
||||
auto query = std::move(res.unwrap());
|
||||
log::info("parsed query: {}", query->toString());
|
||||
// log::info("parsed query: {}", query->toString());
|
||||
return query->match(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,12 +90,14 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
Notification::create("There were errors - see Geode page!", NotificationIcon::Error)->show();
|
||||
}
|
||||
|
||||
m_fields->m_exclamation = CCSprite::createWithSpriteFrameName("exMark_001.png");
|
||||
m_fields->m_exclamation->setPosition(m_fields->m_geodeButton->getContentSize() - ccp(10, 10));
|
||||
m_fields->m_exclamation->setID("errors-found");
|
||||
m_fields->m_exclamation->setZOrder(99);
|
||||
m_fields->m_exclamation->setScale(.6f);
|
||||
m_fields->m_geodeButton->addChild(m_fields->m_exclamation);
|
||||
if (m_fields->m_geodeButton) {
|
||||
m_fields->m_exclamation = CCSprite::createWithSpriteFrameName("exMark_001.png");
|
||||
m_fields->m_exclamation->setPosition(m_fields->m_geodeButton->getContentSize() - ccp(10, 10));
|
||||
m_fields->m_exclamation->setID("errors-found");
|
||||
m_fields->m_exclamation->setZOrder(99);
|
||||
m_fields->m_exclamation->setScale(.6f);
|
||||
m_fields->m_geodeButton->addChild(m_fields->m_exclamation);
|
||||
}
|
||||
}
|
||||
|
||||
// show if the user tried to be naughty and load arbitrary DLLs
|
||||
|
@ -103,19 +105,21 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
if (!shownTriedToLoadDlls) {
|
||||
shownTriedToLoadDlls = true;
|
||||
if (LoaderImpl::get()->userTriedToLoadDLLs()) {
|
||||
auto popup = FLAlertLayer::create(
|
||||
"Hold up!",
|
||||
"It appears that you have tried to <cr>load DLLs</c> with Geode. "
|
||||
"Please note that <cy>Geode is incompatible with ALL DLLs</c>, "
|
||||
"as they can cause Geode mods to <cr>error</c>, or even "
|
||||
"<cr>crash</c>.\n\n"
|
||||
"Remove the DLLs / other mod loaders you have, or <cr>proceed at "
|
||||
"your own risk.</c>",
|
||||
"OK"
|
||||
);
|
||||
popup->m_scene = this;
|
||||
popup->m_noElasticity = true;
|
||||
popup->show();
|
||||
Loader::get()->queueInMainThread([] {
|
||||
auto popup = FLAlertLayer::create(
|
||||
"Hold up!",
|
||||
"It appears that you have tried to <cr>load DLLs</c> with Geode. "
|
||||
"Please note that <cy>Geode is incompatible with ALL DLLs</c>, "
|
||||
"as they can cause Geode mods to <cr>error</c>, or even "
|
||||
"<cr>crash</c>.\n\n"
|
||||
"Remove the DLLs / other mod loaders you have, or <cr>proceed at "
|
||||
"your own risk.</c>",
|
||||
"OK"
|
||||
);
|
||||
|
||||
popup->m_noElasticity = true;
|
||||
popup->show();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,15 +127,18 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
static bool shownUpdateInfo = false;
|
||||
if (updater::isNewUpdateDownloaded() && !shownUpdateInfo) {
|
||||
shownUpdateInfo = true;
|
||||
auto popup = FLAlertLayer::create(
|
||||
"Update downloaded",
|
||||
"A new <cy>update</c> for Geode has been installed! "
|
||||
"Please <cy>restart the game</c> to apply.",
|
||||
"OK"
|
||||
);
|
||||
popup->m_scene = this;
|
||||
popup->m_noElasticity = true;
|
||||
popup->show();
|
||||
|
||||
Loader::get()->queueInMainThread([] {
|
||||
auto popup = FLAlertLayer::create(
|
||||
"Update downloaded",
|
||||
"A new <cy>update</c> for Geode has been installed! "
|
||||
"Please <cy>restart the game</c> to apply.",
|
||||
"OK"
|
||||
);
|
||||
|
||||
popup->m_noElasticity = true;
|
||||
popup->show();
|
||||
});
|
||||
}
|
||||
|
||||
// show crash info
|
||||
|
@ -139,25 +146,29 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
if (
|
||||
crashlog::didLastLaunchCrash() &&
|
||||
!shownLastCrash &&
|
||||
!Mod::get()->template getSettingValue<bool>("disable-last-crashed-popup")
|
||||
!Mod::get()->getSettingValue<bool>("disable-last-crashed-popup")
|
||||
) {
|
||||
shownLastCrash = true;
|
||||
auto popup = createQuickPopup(
|
||||
"Crashed",
|
||||
"It appears that the last session crashed. Would you like to "
|
||||
"open the <cy>crashlog folder</c>?",
|
||||
"No",
|
||||
"Yes",
|
||||
[](auto, bool btn2) {
|
||||
if (btn2) {
|
||||
file::openFolder(dirs::getCrashlogsDir());
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
popup->m_scene = this;
|
||||
popup->m_noElasticity = true;
|
||||
popup->show();
|
||||
|
||||
// open the dialog a frame later (after the scene is set) for proper key priority
|
||||
Loader::get()->queueInMainThread([] {
|
||||
auto popup = createQuickPopup(
|
||||
"Crashed",
|
||||
"It appears that the last session crashed. Would you like to "
|
||||
"open the <cy>crashlog folder</c>?",
|
||||
"No",
|
||||
"Yes",
|
||||
[](auto, bool btn2) {
|
||||
if (btn2) {
|
||||
file::openFolder(dirs::getCrashlogsDir());
|
||||
}
|
||||
},
|
||||
false
|
||||
);
|
||||
popup->m_noElasticity = true;
|
||||
|
||||
popup->show();
|
||||
});
|
||||
}
|
||||
|
||||
// Check for mod updates
|
||||
|
@ -169,9 +180,9 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
[this](server::ServerRequest<std::vector<std::string>>::Value* result) {
|
||||
if (result->isOk()) {
|
||||
auto updatesFound = result->unwrap();
|
||||
if (updatesFound.size() && !m_fields->m_geodeButton->getChildByID("updates-available")) {
|
||||
if (updatesFound.size() && m_fields->m_geodeButton && !m_fields->m_geodeButton->getChildByID("updates-available")) {
|
||||
log::info("Found updates for mods: {}!", updatesFound);
|
||||
|
||||
|
||||
if(auto icon = CCSprite::createWithSpriteFrameName("updates-available.png"_spr)) {
|
||||
// Remove errors icon if it was added, to prevent overlap
|
||||
if (m_fields->m_exclamation) {
|
||||
|
|
|
@ -48,7 +48,7 @@ $register_ids(MenuLayer) {
|
|||
setIDSafe<CCLabelBMFont>(this, labelOffset++, "player-username");
|
||||
|
||||
// main menu
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 0)) {
|
||||
if (auto menu = this->getChildByType<CCMenu>(0)) {
|
||||
menu->setID("main-menu");
|
||||
auto playBtn = setIDSafe(menu, 0, "play-button");
|
||||
auto iconBtn = setIDSafe(menu, 1, "icon-kit-button");
|
||||
|
@ -83,7 +83,7 @@ $register_ids(MenuLayer) {
|
|||
}
|
||||
|
||||
// bottom menu
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 1)) {
|
||||
if (auto menu = this->getChildByType<CCMenu>(1)) {
|
||||
menu->setID("bottom-menu");
|
||||
auto ach = setIDSafe(menu, 0, "achievements-button");
|
||||
setIDSafe(menu, 1, "settings-button");
|
||||
|
@ -110,7 +110,7 @@ $register_ids(MenuLayer) {
|
|||
}
|
||||
|
||||
// social media menu
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 2)) {
|
||||
if (auto menu = this->getChildByType<CCMenu>(2)) {
|
||||
menu->setID("social-media-menu");
|
||||
setIDSafe(menu, 0, "robtop-logo-button");
|
||||
setIDSafe(menu, 1, "facebook-button");
|
||||
|
@ -121,7 +121,7 @@ $register_ids(MenuLayer) {
|
|||
}
|
||||
|
||||
// more games menu
|
||||
if (auto menu = getChildOfType<CCMenu>(this, 3)) {
|
||||
if (auto menu = this->getChildByType<CCMenu>(3)) {
|
||||
menu->setID("more-games-menu");
|
||||
auto moreGamesBtn = setIDSafe(menu, 0, "more-games-button");
|
||||
|
||||
|
@ -159,7 +159,7 @@ $register_ids(MenuLayer) {
|
|||
// but prolly a place mods want to add stuff
|
||||
|
||||
auto topRightMenu = CCMenu::create();
|
||||
topRightMenu->setPosition(winSize.width - 200.f / 2, winSize.height - 50.f / 2);
|
||||
topRightMenu->setPosition(winSize.width - 210.f / 2, winSize.height - 50.f / 2);
|
||||
topRightMenu->setID("top-right-menu");
|
||||
topRightMenu->setContentSize({ 200.f, 50.f });
|
||||
topRightMenu->setLayout(
|
||||
|
|
|
@ -33,8 +33,8 @@ $on_mod(Loaded) {
|
|||
JsonChecker checker(args);
|
||||
auto root = checker.root("[ipc/list-mods]").obj();
|
||||
|
||||
auto includeRunTimeInfo = root.has("include-runtime-info").template get<bool>();
|
||||
auto dontIncludeLoader = root.has("dont-include-loader").template get<bool>();
|
||||
auto includeRunTimeInfo = root.has("include-runtime-info").get<bool>();
|
||||
auto dontIncludeLoader = root.has("dont-include-loader").get<bool>();
|
||||
|
||||
if (!dontIncludeLoader) {
|
||||
res.push_back(
|
||||
|
|
|
@ -24,15 +24,15 @@ std::filesystem::path dirs::getGeodeLogDir() {
|
|||
}
|
||||
|
||||
std::filesystem::path dirs::getTempDir() {
|
||||
return getGeodeDir() / "temp";
|
||||
return dirs::getGeodeDir() / "temp";
|
||||
}
|
||||
|
||||
std::filesystem::path dirs::getModsDir() {
|
||||
return getGeodeDir() / "mods";
|
||||
return dirs::getGeodeDir() / "mods";
|
||||
}
|
||||
|
||||
std::filesystem::path dirs::getModsSaveDir() {
|
||||
return getGeodeSaveDir() / "mods";
|
||||
return dirs::getGeodeSaveDir() / "mods";
|
||||
}
|
||||
|
||||
std::filesystem::path dirs::getModConfigDir() {
|
||||
|
@ -46,3 +46,7 @@ std::filesystem::path dirs::getIndexDir() {
|
|||
std::filesystem::path dirs::getCrashlogsDir() {
|
||||
return crashlog::getCrashLogDirectory();
|
||||
}
|
||||
|
||||
std::filesystem::path dirs::getModPersistentDir() {
|
||||
return dirs::getSaveDir() / "geode-persistent";
|
||||
}
|
|
@ -535,7 +535,7 @@ void Loader::Impl::findProblems() {
|
|||
|
||||
switch(dep.importance) {
|
||||
case ModMetadata::Dependency::Importance::Suggested:
|
||||
if (!Mod::get()->template getSavedValue<bool>(dismissKey)) {
|
||||
if (!Mod::get()->getSavedValue<bool>(dismissKey)) {
|
||||
this->addProblem({
|
||||
LoadProblem::Type::Suggestion,
|
||||
mod,
|
||||
|
@ -548,7 +548,7 @@ void Loader::Impl::findProblems() {
|
|||
}
|
||||
break;
|
||||
case ModMetadata::Dependency::Importance::Recommended:
|
||||
if (!Mod::get()->template getSavedValue<bool>(dismissKey)) {
|
||||
if (!Mod::get()->getSavedValue<bool>(dismissKey)) {
|
||||
this->addProblem({
|
||||
LoadProblem::Type::Recommendation,
|
||||
mod,
|
||||
|
|
|
@ -49,7 +49,7 @@ matjson::Value& Mod::getSaveContainer() {
|
|||
}
|
||||
|
||||
matjson::Value& Mod::getSavedSettingsData() {
|
||||
return m_impl->getSavedSettingsData();
|
||||
return m_impl->m_settings->getSaveData();
|
||||
}
|
||||
|
||||
bool Mod::isEnabled() const {
|
||||
|
@ -143,6 +143,10 @@ std::filesystem::path Mod::getConfigDir(bool create) const {
|
|||
return m_impl->getConfigDir(create);
|
||||
}
|
||||
|
||||
std::filesystem::path Mod::getPersistentDir(bool create) const {
|
||||
return m_impl->getPersistentDir(create);
|
||||
}
|
||||
|
||||
bool Mod::hasSettings() const {
|
||||
return m_impl->hasSettings();
|
||||
}
|
||||
|
|
|
@ -66,7 +66,10 @@ Result<> Mod::Impl::setup() {
|
|||
CCFileUtils::get()->addSearchPath(searchPathRoot.string().c_str());
|
||||
});
|
||||
|
||||
const auto binariesDir = searchPathRoot / m_metadata.getID() / "binaries" / PlatformID::toShortString(GEODE_PLATFORM_TARGET);
|
||||
// binaries on macos are merged, so make the platform binaries merged as well
|
||||
auto const binaryPlatformId = PlatformID::toShortString(GEODE_PLATFORM_TARGET GEODE_MACOS(, true));
|
||||
|
||||
auto const binariesDir = searchPathRoot / m_metadata.getID() / "binaries" / binaryPlatformId;
|
||||
if (std::filesystem::exists(binariesDir))
|
||||
LoaderImpl::get()->addNativeBinariesPath(binariesDir);
|
||||
|
||||
|
@ -135,10 +138,6 @@ matjson::Value& Mod::Impl::getSaveContainer() {
|
|||
return m_saved;
|
||||
}
|
||||
|
||||
matjson::Value& Mod::Impl::getSavedSettingsData() {
|
||||
return m_savedSettingsData;
|
||||
}
|
||||
|
||||
bool Mod::Impl::isEnabled() const {
|
||||
return m_enabled || this->isInternal();
|
||||
}
|
||||
|
@ -174,16 +173,11 @@ std::vector<Patch*> Mod::Impl::getPatches() const {
|
|||
// Settings and saved values
|
||||
|
||||
Result<> Mod::Impl::loadData() {
|
||||
Loader::get()->queueInMainThread([&]() {
|
||||
ModStateEvent(m_self, ModEventType::DataLoaded).post();
|
||||
});
|
||||
|
||||
// Settings
|
||||
// Check if settings exist
|
||||
auto settingPath = m_saveDirPath / "settings.json";
|
||||
if (std::filesystem::exists(settingPath)) {
|
||||
GEODE_UNWRAP_INTO(auto json, utils::file::readJson(settingPath));
|
||||
m_savedSettingsData = json;
|
||||
auto load = m_settings->load(json);
|
||||
if (!load) {
|
||||
log::warn("Unable to load settings: {}", load.unwrapErr());
|
||||
|
@ -215,16 +209,13 @@ Result<> Mod::Impl::saveData() {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
// Data saving should be fully fail-safe
|
||||
// If some settings weren't provided a custom settings handler (for example,
|
||||
// the mod was not loaded) then make sure to save their previous state in
|
||||
// order to not lose data
|
||||
if (!m_savedSettingsData.is_object()) {
|
||||
m_savedSettingsData = matjson::Object();
|
||||
}
|
||||
matjson::Value json = m_savedSettingsData;
|
||||
// ModSettingsManager keeps track of the whole savedata
|
||||
matjson::Value json;
|
||||
m_settings->save(json);
|
||||
|
||||
// saveData is expected to be synchronous, and always called from GD thread
|
||||
ModStateEvent(m_self, ModEventType::DataSaved).post();
|
||||
|
||||
auto res = utils::file::writeString(m_saveDirPath / "settings.json", json.dump());
|
||||
if (!res) {
|
||||
log::error("Unable to save settings: {}", res.unwrapErr());
|
||||
|
@ -234,9 +225,6 @@ Result<> Mod::Impl::saveData() {
|
|||
log::error("Unable to save values: {}", res2.unwrapErr());
|
||||
}
|
||||
|
||||
// saveData is expected to be synchronous, and always called from GD thread
|
||||
ModStateEvent(m_self, ModEventType::DataSaved).post();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -331,6 +319,7 @@ Result<> Mod::Impl::loadBinary() {
|
|||
|
||||
ModStateEvent(m_self, ModEventType::Loaded).post();
|
||||
ModStateEvent(m_self, ModEventType::Enabled).post();
|
||||
ModStateEvent(m_self, ModEventType::DataLoaded).post();
|
||||
|
||||
m_isCurrentlyLoading = false;
|
||||
|
||||
|
@ -659,6 +648,14 @@ std::filesystem::path Mod::Impl::getConfigDir(bool create) const {
|
|||
return dir;
|
||||
}
|
||||
|
||||
std::filesystem::path Mod::Impl::getPersistentDir(bool create) const {
|
||||
auto dir = dirs::getModPersistentDir() / m_metadata.getID();
|
||||
if (create) {
|
||||
(void)file::createDirectoryAll(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
std::string_view Mod::Impl::expandSpriteName(std::string_view name) {
|
||||
std::string nameKey(name);
|
||||
if (m_expandedSprites.contains(nameKey)) return m_expandedSprites[nameKey];
|
||||
|
|
|
@ -52,10 +52,6 @@ namespace geode {
|
|||
* Setting values. This is behind unique_ptr for interior mutability
|
||||
*/
|
||||
std::unique_ptr<ModSettingsManager> m_settings = nullptr;
|
||||
/**
|
||||
* Settings save data. Stored for efficient loading of custom settings
|
||||
*/
|
||||
matjson::Value m_savedSettingsData = matjson::Object();
|
||||
/**
|
||||
* Whether the mod resources are loaded or not
|
||||
*/
|
||||
|
@ -101,7 +97,6 @@ namespace geode {
|
|||
std::filesystem::path getBinaryPath() const;
|
||||
|
||||
matjson::Value& getSaveContainer();
|
||||
matjson::Value& getSavedSettingsData();
|
||||
|
||||
#if defined(GEODE_EXPOSE_SECRET_INTERNALS_IN_HEADERS_DO_NOT_DEFINE_PLEASE)
|
||||
void setMetadata(ModMetadata const& metadata);
|
||||
|
@ -113,6 +108,7 @@ namespace geode {
|
|||
|
||||
std::filesystem::path getSaveDir() const;
|
||||
std::filesystem::path getConfigDir(bool create = true) const;
|
||||
std::filesystem::path getPersistentDir(bool create = true) const;
|
||||
|
||||
bool hasSettings() const;
|
||||
std::vector<std::string> getSettingKeys() const;
|
||||
|
|
|
@ -57,7 +57,7 @@ bool ModMetadata::Dependency::isResolved() const {
|
|||
|
||||
bool ModMetadata::Incompatibility::isResolved() const {
|
||||
return this->importance != Importance::Breaking ||
|
||||
(!this->mod || !this->version.compare(this->mod->getVersion()));
|
||||
(!this->mod || !this->mod->isEnabled() || !this->version.compare(this->mod->getVersion()));
|
||||
}
|
||||
|
||||
static std::string sanitizeDetailsData(std::string const& str) {
|
||||
|
@ -133,11 +133,17 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
|
|||
// change all of this to the gd.needs(...) stuff
|
||||
gd.assertIs({ matjson::Type::Object, matjson::Type::String });
|
||||
if (gd.isObject()) {
|
||||
gd.needs(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH)
|
||||
.mustBe<std::string>("a valid gd version", [](auto const& str) {
|
||||
return str == "*" || numFromString<double>(str).isOk();
|
||||
})
|
||||
.into(impl->m_gdVersion);
|
||||
if (gd.has(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH)) {
|
||||
gd.needs(GEODE_PLATFORM_SHORT_IDENTIFIER_NOARCH)
|
||||
.mustBe<std::string>("a valid gd version", [](auto const& str) {
|
||||
return str == "*" || numFromString<double>(str).isOk();
|
||||
})
|
||||
.into(impl->m_gdVersion);
|
||||
} else {
|
||||
// this will error later on, but try to load the rest of the metadata
|
||||
// so that the mod can show up in the mods listing
|
||||
impl->m_gdVersion = "0.000";
|
||||
}
|
||||
}
|
||||
else if (gd.isString()) {
|
||||
impl->m_softInvalidReason = "mod.json uses old syntax";
|
||||
|
@ -164,7 +170,7 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
|
|||
return Err("[mod.json] can not have both \"developer\" and \"developers\" specified");
|
||||
}
|
||||
for (auto& dev : root.needs("developers").items()) {
|
||||
impl->m_developers.push_back(dev.template get<std::string>());
|
||||
impl->m_developers.push_back(dev.get<std::string>());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -284,7 +290,7 @@ Result<ModMetadata> ModMetadata::Impl::createFromSchemaV010(ModJson const& rawJs
|
|||
|
||||
// Tags. Actual validation is done when interacting with the server in the UI
|
||||
for (auto& tag : root.has("tags").items()) {
|
||||
impl->m_tags.insert(tag.template get<std::string>());
|
||||
impl->m_tags.insert(tag.get<std::string>());
|
||||
}
|
||||
|
||||
// with new cli, binary name is always mod id
|
||||
|
|
|
@ -83,11 +83,51 @@ public:
|
|||
std::shared_ptr<SettingV3> v3 = nullptr;
|
||||
// todo: remove in v4
|
||||
std::shared_ptr<SettingValue> legacy = nullptr;
|
||||
};
|
||||
};
|
||||
std::string modID;
|
||||
std::unordered_map<std::string, SettingInfo> settings;
|
||||
// Stored so custom settings registered after the fact can be loaded
|
||||
// If the ability to unregister custom settings is ever added, remember to
|
||||
// update this by calling saveSettingValueToSave
|
||||
matjson::Value savedata;
|
||||
bool restartRequired = false;
|
||||
|
||||
void loadSettingValueFromSave(std::string const& key) {
|
||||
if (this->savedata.contains(key) && this->settings.contains(key)) {
|
||||
auto& sett = this->settings.at(key);
|
||||
if (!sett.v3) return;
|
||||
try {
|
||||
if (!sett.v3->load(this->savedata[key])) {
|
||||
log::error("Unable to load setting '{}' for mod {}", key, this->modID);
|
||||
}
|
||||
}
|
||||
// matjson::JsonException doesn't catch all possible json errors
|
||||
catch(std::exception const& e) {
|
||||
log::error("Unable to load setting '{}' for mod {} (JSON exception): {}", key, this->modID, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
void saveSettingValueToSave(std::string const& key) {
|
||||
if (this->settings.contains(key)) {
|
||||
auto& sett = this->settings.at(key);
|
||||
if (!sett.v3) return;
|
||||
// Store the value in an intermediary so if `save` fails the existing
|
||||
// value loaded from disk isn't overwritten
|
||||
matjson::Value value;
|
||||
try {
|
||||
if (sett.v3->save(value)) {
|
||||
this->savedata[key] = value;
|
||||
}
|
||||
else {
|
||||
log::error("Unable to save setting '{}' for mod {}", key, this->modID);
|
||||
}
|
||||
}
|
||||
catch(matjson::JsonException const& e) {
|
||||
log::error("Unable to save setting '{}' for mod {} (JSON exception): {}", key, this->modID, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createSettings() {
|
||||
for (auto& [key, setting] : settings) {
|
||||
if (setting.v3) {
|
||||
|
@ -100,6 +140,7 @@ public:
|
|||
}
|
||||
if (auto v3 = (*gen)(key, modID, setting.json)) {
|
||||
setting.v3 = *v3;
|
||||
this->loadSettingValueFromSave(key);
|
||||
}
|
||||
else {
|
||||
log::error(
|
||||
|
@ -131,7 +172,8 @@ ModSettingsManager::ModSettingsManager(ModMetadata const& metadata)
|
|||
"Setting \"{}\" in mod {} has the old \"custom\" type - "
|
||||
"this type has been deprecated and will be removed in Geode v4.0.0. "
|
||||
"Use the new \"custom:type-name-here\" syntax for defining custom "
|
||||
"setting types - see more in INSERT TUTORIAL HERE",
|
||||
"setting types - see more in "
|
||||
"https://docs.geode-sdk.org/mods/settings/#custom-settings",
|
||||
key, m_impl->modID
|
||||
);
|
||||
}
|
||||
|
@ -164,6 +206,7 @@ Result<> ModSettingsManager::registerLegacyCustomSetting(std::string_view key, s
|
|||
if (auto custom = typeinfo_pointer_cast<LegacyCustomSettingV3>(sett.v3)) {
|
||||
if (!custom->getValue()) {
|
||||
custom->setValue(std::move(ptr));
|
||||
m_impl->loadSettingValueFromSave(id);
|
||||
}
|
||||
else {
|
||||
return Err("Setting '{}' in mod {} has already been registed", id, m_impl->modID);
|
||||
|
@ -176,44 +219,25 @@ Result<> ModSettingsManager::registerLegacyCustomSetting(std::string_view key, s
|
|||
}
|
||||
|
||||
Result<> ModSettingsManager::load(matjson::Value const& json) {
|
||||
auto root = checkJson(json, "Settings");
|
||||
for (auto const& [key, value] : root.properties()) {
|
||||
if (m_impl->settings.contains(key)) {
|
||||
auto& sett = m_impl->settings.at(key);
|
||||
if (!sett.v3) continue;
|
||||
try {
|
||||
if (!sett.v3->load(value.json())) {
|
||||
log::error("Unable to load setting '{}' for mod {}", key, m_impl->modID);
|
||||
}
|
||||
}
|
||||
// matjson::JsonException doesn't catch all possible json errors
|
||||
catch(std::exception const& e) {
|
||||
log::error("Unable to load setting '{}' for mod {} (JSON exception): {}", key, m_impl->modID, e.what());
|
||||
}
|
||||
if (json.is_object()) {
|
||||
// Save this so when custom settings are registered they can load their
|
||||
// values properly
|
||||
m_impl->savedata = json.as_object();
|
||||
for (auto const& [key, _] : json.as_object()) {
|
||||
m_impl->loadSettingValueFromSave(key);
|
||||
}
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
void ModSettingsManager::save(matjson::Value& json) {
|
||||
for (auto& [key, sett] : m_impl->settings) {
|
||||
if (!sett.v3) {
|
||||
continue;
|
||||
}
|
||||
// Store the value in an intermediary so if `save` fails the existing
|
||||
// value loaded from disk isn't overwritten
|
||||
matjson::Value value;
|
||||
try {
|
||||
if (sett.v3->save(value)) {
|
||||
json[key] = value;
|
||||
}
|
||||
else {
|
||||
log::error("Unable to save setting '{}' for mod {}", key, m_impl->modID);
|
||||
}
|
||||
}
|
||||
catch(matjson::JsonException const& e) {
|
||||
log::error("Unable to save setting '{}' for mod {} (JSON exception): {}", key, m_impl->modID, e.what());
|
||||
}
|
||||
for (auto& [key, _] : m_impl->settings) {
|
||||
m_impl->saveSettingValueToSave(key);
|
||||
}
|
||||
// Doing this since `ModSettingsManager` is expected to manage savedata fully
|
||||
json = m_impl->savedata;
|
||||
}
|
||||
matjson::Value& ModSettingsManager::getSaveData() {
|
||||
return m_impl->savedata;
|
||||
}
|
||||
|
||||
std::shared_ptr<SettingV3> ModSettingsManager::get(std::string_view key) {
|
||||
|
|
|
@ -16,7 +16,7 @@ static void parseCommon(T& sett, JsonMaybeObject& obj) {
|
|||
obj.has("description").into(sett.description);
|
||||
if (auto defValue = obj.needs("default")) {
|
||||
// Platform-specific default value
|
||||
if (defValue.template is<matjson::Object>()) {
|
||||
if (defValue.is<matjson::Object>()) {
|
||||
auto def = defValue.obj();
|
||||
if (auto plat = def.has(PlatformID::toShortString(GEODE_PLATFORM_TARGET, true))) {
|
||||
plat.into(sett.defaultValue);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "SettingNodeV3.hpp"
|
||||
#include <Geode/loader/SettingNode.hpp>
|
||||
#include <Geode/utils/ColorProvider.hpp>
|
||||
#include <Geode/utils/ranges.hpp>
|
||||
#include <Geode/loader/Dirs.hpp>
|
||||
#include <ui/mods/GeodeStyle.hpp>
|
||||
|
||||
class SettingNodeSizeChangeEventV3::Impl final {
|
||||
|
@ -349,6 +351,10 @@ bool StringSettingNodeV3::init(std::shared_ptr<StringSettingV3> setting, float w
|
|||
});
|
||||
m_input->setScale(.7f);
|
||||
m_input->setString(this->getSetting()->getValue());
|
||||
if (auto filter = this->getSetting()->getAllowedCharacters()) {
|
||||
m_input->setFilter(*filter);
|
||||
}
|
||||
|
||||
this->getButtonMenu()->addChildAtPosition(m_input, Anchor::Center);
|
||||
|
||||
if (setting->getEnumOptions()) {
|
||||
|
@ -453,13 +459,28 @@ bool FileSettingNodeV3::init(std::shared_ptr<FileSettingV3> setting, float width
|
|||
}
|
||||
|
||||
void FileSettingNodeV3::updateState(CCNode* invoker) {
|
||||
// This is because people tend to put `"default": "Please pick a good file"`
|
||||
// which is clever and good UX but also a hack so I also need to hack to support that
|
||||
const auto isTextualDefaultValue = [this, setting = this->getSetting()]() {
|
||||
if (this->hasNonDefaultValue()) return false;
|
||||
std::error_code ec;
|
||||
return setting->isFolder() ?
|
||||
!std::filesystem::is_directory(setting->getDefaultValue(), ec) :
|
||||
!std::filesystem::is_regular_file(setting->getDefaultValue(), ec);
|
||||
}();
|
||||
|
||||
SettingValueNodeV3::updateState(invoker);
|
||||
m_fileIcon->setDisplayFrame(CCSpriteFrameCache::get()->spriteFrameByName(
|
||||
this->getSetting()->isFolder() ? "folderIcon_001.png" : "file.png"_spr
|
||||
));
|
||||
limitNodeSize(m_fileIcon, ccp(10, 10), 1.f, .1f);
|
||||
if (this->getValue().empty()) {
|
||||
m_nameLabel->setString(this->getSetting()->isFolder() ? "No Folder Selected" : "No File Selected");
|
||||
if (this->getValue().empty() || isTextualDefaultValue) {
|
||||
if (isTextualDefaultValue) {
|
||||
m_nameLabel->setString(this->getSetting()->getDefaultValue().string().c_str());
|
||||
}
|
||||
else {
|
||||
m_nameLabel->setString(this->getSetting()->isFolder() ? "No Folder Selected" : "No File Selected");
|
||||
}
|
||||
m_nameLabel->setColor(ccGRAY);
|
||||
m_nameLabel->setOpacity(155);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <Geode/loader/SettingV3.hpp>
|
||||
#include <Geode/loader/SettingNode.hpp>
|
||||
#include <Geode/binding/CCMenuItemToggler.hpp>
|
||||
#include <Geode/binding/ColorChannelSprite.hpp>
|
||||
#include <Geode/binding/Slider.hpp>
|
||||
#include <Geode/ui/ColorPickPopup.hpp>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include <Geode/loader/SettingV3.hpp>
|
||||
#include <Geode/loader/SettingEvent.hpp>
|
||||
#include <Geode/loader/ModSettingsManager.hpp>
|
||||
#include <Geode/utils/ranges.hpp>
|
||||
#include <Geode/utils/string.hpp>
|
||||
#include <Geode/loader/Dirs.hpp>
|
||||
#include <Geode/utils/JsonValidation.hpp>
|
||||
#include <regex>
|
||||
#include "SettingNodeV3.hpp"
|
||||
|
@ -51,7 +54,7 @@ namespace enable_if_parsing {
|
|||
}
|
||||
Result<> eval(std::string const& defaultModID) const override {
|
||||
if (auto mod = Loader::get()->getLoadedMod(modID)) {
|
||||
if (mod->template getSettingValue<bool>(settingID)) {
|
||||
if (mod->getSettingValue<bool>(settingID)) {
|
||||
return Ok();
|
||||
}
|
||||
// This is an if-check just in case, even though check() should already
|
||||
|
@ -83,7 +86,7 @@ namespace enable_if_parsing {
|
|||
}
|
||||
Result<> eval(std::string const& defaultModID) const override {
|
||||
if (auto mod = Loader::get()->getLoadedMod(modID)) {
|
||||
if (mod->template getSavedValue<bool>(savedValue)) {
|
||||
if (mod->getSavedValue<bool>(savedValue)) {
|
||||
return Ok();
|
||||
}
|
||||
if (modID == defaultModID) {
|
||||
|
@ -482,7 +485,7 @@ void SettingV3::init(std::string const& key, std::string const& modID, JsonExpec
|
|||
// Keys every setting must have
|
||||
json.needs("type");
|
||||
for (auto& plat : json.has("platforms").items()) {
|
||||
ranges::push(m_impl->platforms, PlatformID::getCovered(plat.template get<std::string>()));
|
||||
ranges::push(m_impl->platforms, PlatformID::getCovered(plat.get<std::string>()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,7 +495,7 @@ void SettingV3::parseNameAndDescription(JsonExpectedValue& json) {
|
|||
}
|
||||
void SettingV3::parseEnableIf(JsonExpectedValue& json) {
|
||||
json.has("enable-if")
|
||||
.template mustBe<std::string>("a valid \"enable-if\" scheme", [this](std::string const& str) -> Result<> {
|
||||
.mustBe<std::string>("a valid \"enable-if\" scheme", [this](std::string const& str) -> Result<> {
|
||||
GEODE_UNWRAP_INTO(auto tree, enable_if_parsing::Parser::parse(str, m_impl->modID));
|
||||
GEODE_UNWRAP(tree->check());
|
||||
m_impl->enableIfTree = std::move(tree);
|
||||
|
@ -638,9 +641,15 @@ void LegacyCustomSettingV3::setValue(std::shared_ptr<SettingValue> value) {
|
|||
}
|
||||
|
||||
bool LegacyCustomSettingV3::load(matjson::Value const& json) {
|
||||
if (m_impl->legacyValue) {
|
||||
return m_impl->legacyValue->load(json);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool LegacyCustomSettingV3::save(matjson::Value& json) const {
|
||||
if (m_impl->legacyValue) {
|
||||
return m_impl->legacyValue->save(json);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
SettingNodeV3* LegacyCustomSettingV3::createNode(float width) {
|
||||
|
@ -739,10 +748,10 @@ Result<std::shared_ptr<IntSettingV3>> IntSettingV3::parse(std::string const& key
|
|||
// This silly code is because step size being 0 is what defines if they are enabled
|
||||
|
||||
// Small arrows are enabled by default
|
||||
if (!root.has("control").has("arrows").template get<bool>(true)) {
|
||||
if (!root.has("control").has("arrows").get<bool>(true)) {
|
||||
ret->m_impl->controls.arrowStepSize = 0;
|
||||
}
|
||||
if (!root.has("control").has("big-arrows").template get<bool>()) {
|
||||
if (!root.has("control").has("big-arrows").get<bool>()) {
|
||||
ret->m_impl->controls.bigArrowStepSize = 0;
|
||||
}
|
||||
|
||||
|
@ -870,10 +879,10 @@ Result<std::shared_ptr<FloatSettingV3>> FloatSettingV3::parse(std::string const&
|
|||
|
||||
// Disable arrows if they aren't enabled
|
||||
// Small arrows are enabled by default
|
||||
if (!root.has("control").has("arrows").template get<bool>(true)) {
|
||||
if (!root.has("control").has("arrows").get<bool>(true)) {
|
||||
ret->m_impl->controls.arrowStepSize = 0;
|
||||
}
|
||||
if (!root.has("control").has("big-arrows").template get<bool>()) {
|
||||
if (!root.has("control").has("big-arrows").get<bool>()) {
|
||||
ret->m_impl->controls.bigArrowStepSize = 0;
|
||||
}
|
||||
|
||||
|
@ -1046,6 +1055,8 @@ Result<std::shared_ptr<FileSettingV3>> FileSettingV3::parse(std::string const& k
|
|||
auto root = checkJson(json, "FileSettingV3");
|
||||
ret->parseBaseProperties(key, modID, root);
|
||||
|
||||
ret->setDefaultValue(ret->getDefaultValue().make_preferred());
|
||||
|
||||
// Replace known paths like `{gd-save-dir}/`
|
||||
try {
|
||||
ret->setDefaultValue(fmt::format(
|
||||
|
@ -1106,6 +1117,11 @@ Result<std::shared_ptr<FileSettingV3>> FileSettingV3::parse(std::string const& k
|
|||
}
|
||||
|
||||
Result<> FileSettingV3::isValid(std::filesystem::path const& value) const {
|
||||
// This is because people tend to put `"default": "Please pick a good file"`
|
||||
// which is clever and good UX but also a hack so I also need to hack to support that
|
||||
if (value == this->getDefaultValue()) {
|
||||
return Ok();
|
||||
}
|
||||
std::error_code ec;
|
||||
if (m_impl->folder) {
|
||||
if (!std::filesystem::is_directory(value, ec)) {
|
||||
|
|
|
@ -109,9 +109,9 @@ void updater::downloadLatestLoaderResources() {
|
|||
// find release asset
|
||||
for (auto asset : root.needs("assets").iterate()) {
|
||||
auto obj = asset.obj();
|
||||
if (obj.needs("name").template get<std::string>() == "resources.zip") {
|
||||
if (obj.needs("name").get<std::string>() == "resources.zip") {
|
||||
updater::tryDownloadLoaderResources(
|
||||
obj.needs("browser_download_url").template get<std::string>(),
|
||||
obj.needs("browser_download_url").get<std::string>(),
|
||||
false
|
||||
);
|
||||
return;
|
||||
|
@ -213,9 +213,9 @@ void updater::downloadLoaderResources(bool useLatestRelease) {
|
|||
// find release asset
|
||||
for (auto asset : root.needs("assets").iterate()) {
|
||||
auto obj = asset.obj();
|
||||
if (obj.needs("name").template get<std::string>() == "resources.zip") {
|
||||
if (obj.needs("name").get<std::string>() == "resources.zip") {
|
||||
updater::tryDownloadLoaderResources(
|
||||
obj.needs("browser_download_url").template get<std::string>(),
|
||||
obj.needs("browser_download_url").get<std::string>(),
|
||||
false
|
||||
);
|
||||
return *response;
|
||||
|
@ -391,11 +391,11 @@ void updater::checkForLoaderUpdates() {
|
|||
for (auto asset : root.needs("assets").iterate()) {
|
||||
auto obj = asset.obj();
|
||||
if (string::endsWith(
|
||||
obj.needs("name").template get<std::string>(),
|
||||
obj.needs("name").get<std::string>(),
|
||||
fmt::format("{}.zip", PlatformID::toShortString(GEODE_PLATFORM_TARGET, true))
|
||||
)) {
|
||||
updater::downloadLoaderUpdate(
|
||||
obj.needs("browser_download_url").template get<std::string>()
|
||||
obj.needs("browser_download_url").get<std::string>()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <loader/ModImpl.hpp>
|
||||
#include <sys/stat.h>
|
||||
#include <loader/LogImpl.hpp>
|
||||
#include <dlfcn.h>
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
|
@ -132,7 +133,31 @@ bool Loader::Impl::userTriedToLoadDLLs() const {
|
|||
}
|
||||
|
||||
void Loader::Impl::addNativeBinariesPath(std::filesystem::path const& path) {
|
||||
log::warn("LoaderImpl::addNativeBinariesPath not implement on this platform, not adding path {}", path.string());
|
||||
// this takes advantage of dyld using already loaded binaries when loading relative shared libraries
|
||||
// however, this also means that the binaries are loaded, which could have some weird side effects
|
||||
// but if you could use dlopen (and thus control when libraries are loaded), then you wouldn't be using this, would you?
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(path)) {
|
||||
if (!entry.is_regular_file()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& entry_path = entry.path();
|
||||
|
||||
if (entry_path.extension() != ".dylib") {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto handle = dlopen(entry_path.string().c_str(), RTLD_LAZY);
|
||||
|
||||
if (!handle) {
|
||||
auto err = dlerror();
|
||||
log::warn("failed to load native binary at {}: dlerror returned ({})", entry_path.string(), err);
|
||||
continue;
|
||||
}
|
||||
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Loader::Impl::getGameVersion() {
|
||||
|
|
|
@ -115,18 +115,19 @@ void console::setup() {
|
|||
path = std::string(buf, count - 1);
|
||||
}
|
||||
|
||||
// count == 0 => not a console and not a file, assume it's closed
|
||||
// wine does something weird with /dev/null? not sure tbh but it's definitely up to no good
|
||||
if ((count == 0 || path.ends_with("\\dev\\null")) && Mod::get()->getSettingValue<bool>("show-platform-console")) {
|
||||
s_outHandle = nullptr;
|
||||
CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
CloseHandle(GetStdHandle(STD_INPUT_HANDLE));
|
||||
CloseHandle(GetStdHandle(STD_ERROR_HANDLE));
|
||||
FreeConsole();
|
||||
SetStdHandle(STD_OUTPUT_HANDLE, nullptr);
|
||||
SetStdHandle(STD_INPUT_HANDLE, nullptr);
|
||||
SetStdHandle(STD_ERROR_HANDLE, nullptr);
|
||||
}
|
||||
// TODO: this code causes a crash when piping game's output somewhere (and in some other cases), so it's removed for now
|
||||
// // count == 0 => not a console and not a file, assume it's closed
|
||||
// // wine does something weird with /dev/null? not sure tbh but it's definitely up to no good
|
||||
// if ((count == 0 || path.ends_with("\\dev\\null"))) {
|
||||
// s_outHandle = nullptr;
|
||||
// CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||
// CloseHandle(GetStdHandle(STD_INPUT_HANDLE));
|
||||
// CloseHandle(GetStdHandle(STD_ERROR_HANDLE));
|
||||
// FreeConsole();
|
||||
// SetStdHandle(STD_OUTPUT_HANDLE, nullptr);
|
||||
// SetStdHandle(STD_INPUT_HANDLE, nullptr);
|
||||
// SetStdHandle(STD_ERROR_HANDLE, nullptr);
|
||||
// }
|
||||
}
|
||||
|
||||
// clion console supports escape codes but we can't query that because it's a named pipe
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
.percentage = 0,
|
||||
};
|
||||
|
||||
m_downloadListener.bind([this, hash = version.hash](web::WebTask::Event* event) {
|
||||
m_downloadListener.bind([this, hash = version.hash, version = version](web::WebTask::Event* event) {
|
||||
if (auto value = event->getValue()) {
|
||||
if (value->ok()) {
|
||||
if (auto actualHash = ::calculateHash(value->data()); actualHash != hash) {
|
||||
|
@ -134,7 +134,9 @@ public:
|
|||
};
|
||||
}
|
||||
else {
|
||||
m_status = DownloadStatusDone();
|
||||
m_status = DownloadStatusDone {
|
||||
.version = version
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -319,6 +321,11 @@ bool ModDownloadManager::checkAutoConfirm() {
|
|||
if (inc.mod && (!download.getVersion().has_value() || inc.version.compare(download.getVersion().value()))) {
|
||||
return false;
|
||||
}
|
||||
for (auto download : ModDownloadManager::get()->getDownloads()) {
|
||||
if (download.isDone() && inc.id == download.getID() && (!download.getVersion().has_value() || inc.version.compare(download.getVersion().value()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If some installed mod is incompatible with this one,
|
||||
// we need to ask for confirmation
|
||||
|
@ -329,6 +336,19 @@ bool ModDownloadManager::checkAutoConfirm() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If some newly downloaded mods are incompatible with this one,
|
||||
// we need to ask for confirmation
|
||||
for (auto download : ModDownloadManager::get()->getDownloads()) {
|
||||
auto status = download.getStatus();
|
||||
if (auto done = std::get_if<DownloadStatusDone>(&status)) {
|
||||
for (auto inc : done->version.metadata.getIncompatibilities()) {
|
||||
if (inc.id == download.getID() && inc.version.compare(done->version.metadata.getVersion())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there are mods we aren't sure about yet, we can't auto-confirm
|
||||
else if (std::holds_alternative<DownloadStatusFetching>(status)) {
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace server {
|
|||
bool operator==(DownloadStatusDownloading const&) const = default;
|
||||
};
|
||||
struct DownloadStatusDone {
|
||||
ServerModVersion version;
|
||||
bool operator==(DownloadStatusDone const&) const = default;
|
||||
};
|
||||
struct DownloadStatusError {
|
||||
|
|
|
@ -189,7 +189,7 @@ static ServerError parseServerError(web::WebResponse const& error) {
|
|||
if (json.is_object() && json.contains("error")) {
|
||||
return ServerError(
|
||||
error.code(),
|
||||
"{}", json.template get<std::string>("error")
|
||||
"{}", json.get<std::string>("error")
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -264,13 +264,13 @@ Result<ServerModVersion> ServerModVersion::parse(matjson::Value const& raw) {
|
|||
|
||||
auto res = ServerModVersion();
|
||||
|
||||
res.metadata.setGeodeVersion(root.needs("geode").template get<VersionInfo>());
|
||||
res.metadata.setGeodeVersion(root.needs("geode").get<VersionInfo>());
|
||||
|
||||
// Verify target GD version
|
||||
auto gd_obj = root.needs("gd").obj();
|
||||
std::string gd = "0.000";
|
||||
if (gd_obj.has(GEODE_PLATFORM_SHORT_IDENTIFIER)) {
|
||||
gd = gd_obj.has(GEODE_PLATFORM_SHORT_IDENTIFIER).template get<std::string>();
|
||||
gd = gd_obj.has(GEODE_PLATFORM_SHORT_IDENTIFIER). get<std::string>();
|
||||
}
|
||||
|
||||
if (gd != "*") {
|
||||
|
@ -283,11 +283,11 @@ Result<ServerModVersion> ServerModVersion::parse(matjson::Value const& raw) {
|
|||
root.needs("hash").into(res.hash);
|
||||
|
||||
// Get mod metadata info
|
||||
res.metadata.setID(root.needs("mod_id").template get<std::string>());
|
||||
res.metadata.setName(root.needs("name").template get<std::string>());
|
||||
res.metadata.setDescription(root.needs("description").template get<std::string>());
|
||||
res.metadata.setVersion(root.needs("version").template get<VersionInfo>());
|
||||
res.metadata.setIsAPI(root.needs("api").template get<bool>());
|
||||
res.metadata.setID(root.needs("mod_id").get<std::string>());
|
||||
res.metadata.setName(root.needs("name").get<std::string>());
|
||||
res.metadata.setDescription(root.needs("description").get<std::string>());
|
||||
res.metadata.setVersion(root.needs("version").get<VersionInfo>());
|
||||
res.metadata.setIsAPI(root.needs("api").get<bool>());
|
||||
|
||||
std::vector<ModMetadata::Dependency> dependencies {};
|
||||
for (auto dep : root.has("dependencies").iterate()) {
|
||||
|
@ -433,10 +433,10 @@ Result<ServerModMetadata> ServerModMetadata::parse(matjson::Value const& raw) {
|
|||
root.has("changelog").into(res.changelog);
|
||||
root.has("repository").into(res.repository);
|
||||
if (root.has("created_at")) {
|
||||
GEODE_UNWRAP_INTO(res.createdAt, ServerDateTime::parse(root.has("created_at").template get<std::string>()));
|
||||
GEODE_UNWRAP_INTO(res.createdAt, ServerDateTime::parse(root.has("created_at").get<std::string>()));
|
||||
}
|
||||
if (root.has("updated_at")) {
|
||||
GEODE_UNWRAP_INTO(res.updatedAt, ServerDateTime::parse(root.has("updated_at").template get<std::string>()));
|
||||
GEODE_UNWRAP_INTO(res.updatedAt, ServerDateTime::parse(root.has("updated_at").get<std::string>()));
|
||||
}
|
||||
|
||||
std::vector<std::string> developerNames;
|
||||
|
@ -470,7 +470,7 @@ Result<ServerModMetadata> ServerModMetadata::parse(matjson::Value const& raw) {
|
|||
}
|
||||
|
||||
for (auto item : root.has("tags").iterate()) {
|
||||
res.tags.insert(item.template get<std::string>());
|
||||
res.tags.insert(item.get<std::string>());
|
||||
}
|
||||
|
||||
root.needs("download_count").into(res.downloadCount);
|
||||
|
|
|
@ -159,9 +159,15 @@ void geode::openChangelogPopup(Mod* mod) {
|
|||
}
|
||||
|
||||
void geode::openSettingsPopup(Mod* mod) {
|
||||
openSettingsPopup(mod, true);
|
||||
}
|
||||
Popup<Mod*>* geode::openSettingsPopup(Mod* mod, bool disableGeodeTheme) {
|
||||
if (mod->hasSettings()) {
|
||||
ModSettingsPopup::create(mod)->show();
|
||||
auto popup = ModSettingsPopup::create(mod, disableGeodeTheme);
|
||||
popup->show();
|
||||
return popup;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
class ModLogoSprite : public CCNode {
|
||||
|
@ -233,7 +239,7 @@ protected:
|
|||
else {
|
||||
auto data = result->unwrap();
|
||||
auto image = Ref(new CCImage());
|
||||
image->initWithImageData(const_cast<uint8_t*>(data.data()), data.size());
|
||||
image->initWithImageData(data.data(), data.size());
|
||||
|
||||
auto texture = CCTextureCache::get()->addUIImage(image, m_modID.c_str());
|
||||
this->setSprite(CCSprite::createWithTexture(texture), true);
|
||||
|
|
|
@ -70,16 +70,21 @@ $on_mod(Loaded) {
|
|||
Loader::get()->queueInMainThread([updateColors = updateColors] {
|
||||
// this code is ran during static init, where settings aren't loaded yet, and getSettingValue will always return false.
|
||||
// because of that, we have to delay it until next frame.
|
||||
updateColors(Mod::get()->template getSettingValue<bool>("enable-geode-theme"));
|
||||
updateColors(Mod::get()->getSettingValue<bool>("enable-geode-theme"));
|
||||
});
|
||||
}
|
||||
|
||||
bool GeodeSquareSprite::init(CCSprite* top, bool* state) {
|
||||
if (!CCSprite::initWithFile(isGeodeTheme() ? "GE_button_05.png"_spr : "GJ_button_01.png"))
|
||||
bool isGeodeTheme(bool forceDisableTheme) {
|
||||
return !forceDisableTheme && Mod::get()->getSettingValue<bool>("enable-geode-theme");
|
||||
}
|
||||
|
||||
bool GeodeSquareSprite::init(CCSprite* top, bool* state, bool forceDisableTheme) {
|
||||
if (!CCSprite::initWithFile(isGeodeTheme(forceDisableTheme) ? "GE_button_05.png"_spr : "GJ_button_01.png"))
|
||||
return false;
|
||||
|
||||
m_stateSrc = state;
|
||||
m_topSprite = top;
|
||||
m_forceDisableTheme = forceDisableTheme;
|
||||
|
||||
limitNodeSize(top, m_obContentSize * .65f, 2.f, .1f);
|
||||
this->addChildAtPosition(top, Anchor::Center);
|
||||
|
@ -94,7 +99,7 @@ bool GeodeSquareSprite::init(CCSprite* top, bool* state) {
|
|||
|
||||
void GeodeSquareSprite::updateImage() {
|
||||
this->setTexture(CCTextureCache::get()->addImage(
|
||||
(m_state ? "GJ_button_02.png" : (isGeodeTheme() ? "GE_button_05.png"_spr : "GJ_button_01.png")),
|
||||
(m_state ? "GJ_button_02.png" : (isGeodeTheme(m_forceDisableTheme) ? "GE_button_05.png"_spr : "GJ_button_01.png")),
|
||||
false
|
||||
));
|
||||
}
|
||||
|
@ -106,18 +111,18 @@ void GeodeSquareSprite::update(float dt) {
|
|||
}
|
||||
}
|
||||
|
||||
GeodeSquareSprite* GeodeSquareSprite::create(const char* top, bool* state) {
|
||||
GeodeSquareSprite* GeodeSquareSprite::create(const char* top, bool* state, bool forceDisableTheme) {
|
||||
auto ret = new GeodeSquareSprite();
|
||||
if (ret->init(CCSprite::create(top), state)) {
|
||||
if (ret->init(CCSprite::create(top), state, forceDisableTheme)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
delete ret;
|
||||
return nullptr;
|
||||
}
|
||||
GeodeSquareSprite* GeodeSquareSprite::createWithSpriteFrameName(const char* top, bool* state) {
|
||||
GeodeSquareSprite* GeodeSquareSprite::createWithSpriteFrameName(const char* top, bool* state, bool forceDisableTheme) {
|
||||
auto ret = new GeodeSquareSprite();
|
||||
if (ret->init(CCSprite::createWithSpriteFrameName(top), state)) {
|
||||
if (ret->init(CCSprite::createWithSpriteFrameName(top), state, forceDisableTheme)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
@ -142,8 +147,8 @@ CCNode* createLoadingCircle(float sideLength, const char* id) {
|
|||
return spinner;
|
||||
}
|
||||
|
||||
const char* getGeodeButtonSpriteName(GeodeButtonSprite spr) {
|
||||
if (isGeodeTheme()) {
|
||||
const char* getGeodeButtonSpriteName(GeodeButtonSprite spr, bool forceDisableTheme) {
|
||||
if (isGeodeTheme(forceDisableTheme)) {
|
||||
switch (spr) {
|
||||
default:
|
||||
case GeodeButtonSprite::Default: return "GE_button_05.png"_spr;
|
||||
|
@ -165,18 +170,18 @@ const char* getGeodeButtonSpriteName(GeodeButtonSprite spr) {
|
|||
}
|
||||
}
|
||||
|
||||
IconButtonSprite* createGeodeButton(CCNode* icon, std::string const& text, GeodeButtonSprite bg) {
|
||||
return IconButtonSprite::create(getGeodeButtonSpriteName(bg), icon, text.c_str(), "bigFont.fnt");
|
||||
IconButtonSprite* createGeodeButton(CCNode* icon, std::string const& text, GeodeButtonSprite bg, bool forceDisableTheme) {
|
||||
return IconButtonSprite::create(getGeodeButtonSpriteName(bg, forceDisableTheme), icon, text.c_str(), "bigFont.fnt");
|
||||
}
|
||||
ButtonSprite* createGeodeButton(std::string const& text, int width, bool gold, bool absolute, GeodeButtonSprite bg) {
|
||||
return ButtonSprite::create(text.c_str(), width, absolute, gold ? "goldFont.fnt" : "bigFont.fnt", getGeodeButtonSpriteName(bg), 0.0f, .8f);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, int width, bool gold, bool absolute, GeodeButtonSprite bg, bool forceDisableTheme) {
|
||||
return ButtonSprite::create(text.c_str(), width, absolute, gold ? "goldFont.fnt" : "bigFont.fnt", getGeodeButtonSpriteName(bg, forceDisableTheme), 0.0f, .8f);
|
||||
}
|
||||
ButtonSprite* createGeodeButton(std::string const& text, bool gold, GeodeButtonSprite bg) {
|
||||
return ButtonSprite::create(text.c_str(), gold ? "goldFont.fnt" : "bigFont.fnt", getGeodeButtonSpriteName(bg), .8f);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, bool gold, GeodeButtonSprite bg, bool forceDisableTheme) {
|
||||
return ButtonSprite::create(text.c_str(), gold ? "goldFont.fnt" : "bigFont.fnt", getGeodeButtonSpriteName(bg, forceDisableTheme), .8f);
|
||||
}
|
||||
|
||||
CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale, CircleBaseSize size, bool altColor) {
|
||||
const auto geodeTheme = isGeodeTheme();
|
||||
CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale, CircleBaseSize size, bool altColor, bool forceDisableTheme) {
|
||||
const auto geodeTheme = isGeodeTheme(forceDisableTheme);
|
||||
auto ret = CircleButtonSprite::create(
|
||||
top, geodeTheme ? (altColor ? CircleBaseColor::DarkAqua : CircleBaseColor::DarkPurple) : CircleBaseColor::Green, size
|
||||
);
|
||||
|
@ -184,21 +189,16 @@ CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale, CircleBa
|
|||
return ret;
|
||||
}
|
||||
|
||||
ButtonSprite* createGeodeTagLabel(std::string const& text, std::optional<std::pair<ccColor3B, ccColor3B>> const& color) {
|
||||
ButtonSprite* createTagLabel(std::string const& text, std::pair<ccColor3B, ccColor3B> const& color) {
|
||||
auto label = ButtonSprite::create(text.c_str(), "bigFont.fnt", "white-square.png"_spr, .8f);
|
||||
if (color) {
|
||||
label->m_label->setColor(color->first);
|
||||
label->m_BGSprite->setColor(color->second);
|
||||
}
|
||||
else {
|
||||
auto def = geodeTagColor(text);
|
||||
label->m_label->setColor(def.first);
|
||||
label->m_BGSprite->setColor(def.second);
|
||||
}
|
||||
label->m_label->setColor(color.first);
|
||||
label->m_BGSprite->setColor(color.second);
|
||||
return label;
|
||||
}
|
||||
|
||||
std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text) {
|
||||
ButtonSprite* createGeodeTagLabel(std::string_view tag) {
|
||||
return createTagLabel(geodeTagName(tag), geodeTagColors(tag));
|
||||
}
|
||||
std::pair<ccColor3B, ccColor3B> geodeTagColors(std::string_view tag) {
|
||||
static std::array TAG_COLORS {
|
||||
std::make_pair(ccc3(240, 233, 255), ccc3(130, 123, 163)),
|
||||
std::make_pair(ccc3(234, 255, 245), ccc3(123, 163, 136)),
|
||||
|
@ -206,20 +206,32 @@ std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text) {
|
|||
std::make_pair(ccc3(255, 253, 240), ccc3(163, 157, 123)),
|
||||
std::make_pair(ccc3(255, 242, 240), ccc3(163, 128, 123)),
|
||||
};
|
||||
return TAG_COLORS[hash(text) % 5932 % TAG_COLORS.size()];
|
||||
}
|
||||
|
||||
ListBorders* createGeodeListBorders(CCSize const& size) {
|
||||
auto ret = ListBorders::create();
|
||||
if (isGeodeTheme()) {
|
||||
ret->setSpriteFrames("geode-list-top.png"_spr, "geode-list-side.png"_spr, 2);
|
||||
if (tag == "modtober24") {
|
||||
return std::make_pair(ccc3(225, 236, 245), ccc3(82, 139, 201));
|
||||
}
|
||||
ret->setContentSize(size);
|
||||
return ret;
|
||||
return TAG_COLORS[hash(tag) % 5932 % TAG_COLORS.size()];
|
||||
}
|
||||
std::string geodeTagName(std::string_view tag) {
|
||||
// todo in v4: rework tags to use a server-provided display name instead
|
||||
if (tag == "modtober24") {
|
||||
return "Modtober 2024";
|
||||
}
|
||||
// Everything else just capitalize and that's it
|
||||
auto readable = std::string(tag);
|
||||
readable[0] = std::toupper(readable[0]);
|
||||
return readable;
|
||||
}
|
||||
|
||||
bool isGeodeTheme() {
|
||||
return Mod::get()->template getSettingValue<bool>("enable-geode-theme");
|
||||
ListBorders* createGeodeListBorders(CCSize const& size, bool forceDisableTheme) {
|
||||
auto ret = ListBorders::create();
|
||||
const bool geodeTheme = isGeodeTheme(forceDisableTheme);
|
||||
if (geodeTheme) {
|
||||
ret->setSpriteFrames("geode-list-top.png"_spr, "geode-list-side.png"_spr, 2);
|
||||
ret->setContentSize(size);
|
||||
} else {
|
||||
ret->setContentSize(size + ccp(5, 5));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool GeodeTabSprite::init(const char* iconFrame, const char* text, float width, bool altColor) {
|
||||
|
|
|
@ -16,11 +16,16 @@ enum class GeodePopupStyle {
|
|||
Alt2,
|
||||
};
|
||||
|
||||
bool isGeodeTheme(bool forceDisableTheme = false);
|
||||
|
||||
template <class... Args>
|
||||
class GeodePopup : public Popup<Args...> {
|
||||
protected:
|
||||
bool m_forceDisableTheme = false;
|
||||
|
||||
bool init(float width, float height, Args... args, GeodePopupStyle style = GeodePopupStyle::Default, bool forceDisableTheme = false) {
|
||||
const bool geodeTheme = !forceDisableTheme && Mod::get()->template getSettingValue<bool>("enable-geode-theme");
|
||||
m_forceDisableTheme = forceDisableTheme;
|
||||
const bool geodeTheme = isGeodeTheme(forceDisableTheme);
|
||||
const char* bg;
|
||||
switch (style) {
|
||||
default:
|
||||
|
@ -49,16 +54,17 @@ class GeodeSquareSprite : public CCSprite {
|
|||
protected:
|
||||
bool* m_stateSrc = nullptr;
|
||||
bool m_state = false;
|
||||
bool m_forceDisableTheme = false;
|
||||
CCSprite* m_topSprite;
|
||||
|
||||
bool init(CCSprite* top, bool* state);
|
||||
bool init(CCSprite* top, bool* state, bool forceDisableTheme = false);
|
||||
|
||||
void update(float dt) override;
|
||||
void updateImage();
|
||||
|
||||
public:
|
||||
static GeodeSquareSprite* create(const char* top, bool* state = nullptr);
|
||||
static GeodeSquareSprite* createWithSpriteFrameName(const char* top, bool* state = nullptr);
|
||||
static GeodeSquareSprite* create(const char* top, bool* state = nullptr, bool forceDisableTheme = false);
|
||||
static GeodeSquareSprite* createWithSpriteFrameName(const char* top, bool* state = nullptr, bool forceDisableTheme = false);
|
||||
|
||||
CCSprite* getTopSprite() const;
|
||||
void setState(bool state);
|
||||
|
@ -73,19 +79,19 @@ enum class GeodeButtonSprite {
|
|||
Enable,
|
||||
Gray,
|
||||
};
|
||||
const char* getGeodeButtonSpriteName(GeodeButtonSprite spr);
|
||||
IconButtonSprite* createGeodeButton(CCNode* icon, std::string const& text, GeodeButtonSprite bg = GeodeButtonSprite::Default);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, int width, bool absolute = false, bool gold = false, GeodeButtonSprite bg = GeodeButtonSprite::Default);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, bool gold = false, GeodeButtonSprite bg = GeodeButtonSprite::Default);
|
||||
const char* getGeodeButtonSpriteName(GeodeButtonSprite spr, bool forceDisableTheme = false);
|
||||
IconButtonSprite* createGeodeButton(CCNode* icon, std::string const& text, GeodeButtonSprite bg = GeodeButtonSprite::Default, bool forceDisableTheme = false);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, int width, bool absolute = false, bool gold = false, GeodeButtonSprite bg = GeodeButtonSprite::Default, bool forceDisableTheme = false);
|
||||
ButtonSprite* createGeodeButton(std::string const& text, bool gold = false, GeodeButtonSprite bg = GeodeButtonSprite::Default, bool forceDisableTheme = false);
|
||||
|
||||
CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale = 1.f, CircleBaseSize size = CircleBaseSize::Medium, bool altColor = false);
|
||||
CircleButtonSprite* createGeodeCircleButton(CCSprite* top, float scale = 1.f, CircleBaseSize size = CircleBaseSize::Medium, bool altColor = false, bool forceDisableTheme = false);
|
||||
|
||||
ButtonSprite* createGeodeTagLabel(std::string const& text, std::optional<std::pair<ccColor3B, ccColor3B>> const& color = std::nullopt);
|
||||
std::pair<ccColor3B, ccColor3B> geodeTagColor(std::string_view const& text);
|
||||
ButtonSprite* createTagLabel(std::string const& text, std::pair<ccColor3B, ccColor3B> const& color);
|
||||
ButtonSprite* createGeodeTagLabel(std::string_view tag);
|
||||
std::pair<ccColor3B, ccColor3B> geodeTagColors(std::string_view tag);
|
||||
std::string geodeTagName(std::string_view tag);
|
||||
|
||||
ListBorders* createGeodeListBorders(CCSize const& size);
|
||||
|
||||
bool isGeodeTheme();
|
||||
ListBorders* createGeodeListBorders(CCSize const& size, bool forceDisableTheme = false);
|
||||
|
||||
class GeodeTabSprite : public CCNode {
|
||||
protected:
|
||||
|
|
|
@ -430,14 +430,15 @@ bool ModsLayer::init() {
|
|||
// Increment touch priority so the mods in the list don't override
|
||||
mainTabs->setTouchPriority(-150);
|
||||
|
||||
for (auto item : std::initializer_list<std::tuple<const char*, const char*, ModListSource*, const char*>> {
|
||||
{ "download.png"_spr, "Installed", InstalledModListSource::get(InstalledModListType::All), "installed-button" },
|
||||
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button" },
|
||||
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button" },
|
||||
{ "GJ_timeIcon_001.png", "Recent", ServerModListSource::get(ServerModListType::Recent), "recent-button" },
|
||||
for (auto item : std::initializer_list<std::tuple<const char*, const char*, ModListSource*, const char*, bool>> {
|
||||
{ "download.png"_spr, "Installed", InstalledModListSource::get(InstalledModListType::All), "installed-button", false },
|
||||
{ "GJ_starsIcon_001.png", "Featured", ServerModListSource::get(ServerModListType::Featured), "featured-button", false },
|
||||
{ "globe.png"_spr, "Download", ServerModListSource::get(ServerModListType::Download), "download-button", false },
|
||||
{ "GJ_timeIcon_001.png", "Recent", ServerModListSource::get(ServerModListType::Recent), "recent-button", false },
|
||||
{ "d_artCloud_03_001.png", "Modtober", ServerModListSource::get(ServerModListType::Modtober24), "modtober-button", true },
|
||||
}) {
|
||||
auto btn = CCMenuItemSpriteExtra::create(
|
||||
GeodeTabSprite::create(std::get<0>(item), std::get<1>(item), 120),
|
||||
GeodeTabSprite::create(std::get<0>(item), std::get<1>(item), 100, std::get<4>(item)),
|
||||
this, menu_selector(ModsLayer::onTab)
|
||||
);
|
||||
btn->setUserData(std::get<2>(item));
|
||||
|
@ -683,7 +684,7 @@ void ModsLayer::onSearch(CCObject*) {
|
|||
}
|
||||
}
|
||||
void ModsLayer::onTheme(CCObject*) {
|
||||
auto old = Mod::get()->template getSettingValue<bool>("enable-geode-theme");
|
||||
auto old = Mod::get()->getSettingValue<bool>("enable-geode-theme");
|
||||
createQuickPopup(
|
||||
"Switch Theme",
|
||||
fmt::format(
|
||||
|
@ -704,7 +705,7 @@ void ModsLayer::onTheme(CCObject*) {
|
|||
);
|
||||
}
|
||||
void ModsLayer::onSettings(CCObject*) {
|
||||
openSettingsPopup(Mod::get());
|
||||
openSettingsPopup(Mod::get(), false);
|
||||
}
|
||||
|
||||
ModsLayer* ModsLayer::create() {
|
||||
|
|
|
@ -84,12 +84,12 @@ bool ModItem::init(ModSource&& source) {
|
|||
);
|
||||
m_infoContainer->addChild(m_developers);
|
||||
|
||||
m_restartRequiredLabel = createGeodeTagLabel(
|
||||
m_restartRequiredLabel = createTagLabel(
|
||||
"Restart Required",
|
||||
{{
|
||||
{
|
||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
|
||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
|
||||
}}
|
||||
}
|
||||
);
|
||||
m_restartRequiredLabel->setID("restart-required-label");
|
||||
m_restartRequiredLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(std::nullopt, .75f));
|
||||
|
@ -140,7 +140,7 @@ bool ModItem::init(ModSource&& source) {
|
|||
|
||||
auto geodeValid = Loader::get()->isModVersionSupported(version.getGeodeVersion());
|
||||
auto gameVersion = version.getGameVersion();
|
||||
auto gdValid = gameVersion == "*" || gameVersion == GEODE_STR(GEODE_GD_VERSION);
|
||||
auto gdValid = !gameVersion || gameVersion == "*" || gameVersion == GEODE_STR(GEODE_GD_VERSION);
|
||||
|
||||
if (!geodeValid || !gdValid) {
|
||||
spr = createGeodeButton("N/A", 50, false, true, GeodeButtonSprite::Gray);
|
||||
|
@ -208,6 +208,11 @@ bool ModItem::init(ModSource&& source) {
|
|||
paidModLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .8f));
|
||||
m_titleContainer->addChild(paidModLabel);
|
||||
}
|
||||
if (metadata.tags.contains("modtober24")) {
|
||||
auto modtoberLabel = CCSprite::createWithSpriteFrameName("tag-modtober.png"_spr);
|
||||
modtoberLabel->setLayoutOptions(AxisLayoutOptions::create()->setScaleLimits(.1f, .8f));
|
||||
m_titleContainer->addChild(modtoberLabel);
|
||||
}
|
||||
|
||||
// Show mod download count here already so people can make informed decisions
|
||||
// on which mods to install
|
||||
|
@ -363,7 +368,10 @@ void ModItem::updateState() {
|
|||
m_bg->setColor("mod-list-paid-color"_cc3b);
|
||||
m_bg->setOpacity(55);
|
||||
}
|
||||
|
||||
if (metadata.tags.contains("modtober24")) {
|
||||
m_bg->setColor(ccc3(63, 91, 138));
|
||||
m_bg->setOpacity(85);
|
||||
}
|
||||
if (isGeodeTheme() && metadata.featured) {
|
||||
m_bg->setColor("mod-list-featured-color"_cc3b);
|
||||
m_bg->setOpacity(65);
|
||||
|
@ -496,21 +504,28 @@ void ModItem::onView(CCObject*) {
|
|||
// Show popups for invalid mods
|
||||
if (m_source.asServer()) {
|
||||
auto version = m_source.asServer()->latestVersion();
|
||||
if (!Loader::get()->isModVersionSupported(version.getGeodeVersion())) {
|
||||
auto gameVersion = version.getGameVersion();
|
||||
if (gameVersion == "0.000") {
|
||||
return FLAlertLayer::create(
|
||||
nullptr,
|
||||
"Outdated",
|
||||
"This mod is targets an <cr>outdated version of Geode</c>. "
|
||||
"<co>Please wait for its developer to update it.</c>",
|
||||
"Invalid Platform",
|
||||
"This mod is <cr>not available</c> for your current platform.",
|
||||
"OK", nullptr, 360
|
||||
)->show();
|
||||
}
|
||||
if (version.getGameVersion() != "*" && version.getGameVersion() != GEODE_STR(GEODE_GD_VERSION)) {
|
||||
if (gameVersion && gameVersion != "*" && gameVersion != GEODE_STR(GEODE_GD_VERSION)) {
|
||||
return FLAlertLayer::create(
|
||||
nullptr,
|
||||
"Outdated",
|
||||
"This mod is targets a <cr>different version of Geometry Dash</c>. "
|
||||
"<co>Please wait for its developer to update it.</c>",
|
||||
"Unavailable",
|
||||
"This mod targets an <cr>unsupported version of Geometry Dash</c>.",
|
||||
"OK", nullptr, 360
|
||||
)->show();
|
||||
}
|
||||
if (!Loader::get()->isModVersionSupported(version.getGeodeVersion())) {
|
||||
return FLAlertLayer::create(
|
||||
nullptr,
|
||||
"Unavailable",
|
||||
"This mod targets an <cr>unsupported version of Geode</c>.",
|
||||
"OK", nullptr, 360
|
||||
)->show();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../popups/SortPopup.hpp"
|
||||
#include "../GeodeStyle.hpp"
|
||||
#include "../ModsLayer.hpp"
|
||||
#include "../popups/ModtoberPopup.hpp"
|
||||
|
||||
bool ModList::init(ModListSource* src, CCSize const& size) {
|
||||
if (!CCNode::init())
|
||||
|
@ -249,6 +250,34 @@ bool ModList::init(ModListSource* src, CCSize const& size) {
|
|||
|
||||
m_topContainer->addChild(m_searchMenu);
|
||||
|
||||
// Modtober banner; this can be removed after Modtober 2024 is over!
|
||||
if (
|
||||
auto src = typeinfo_cast<ServerModListSource*>(m_source);
|
||||
src && src->getType() == ServerModListType::Modtober24
|
||||
) {
|
||||
auto menu = CCMenu::create();
|
||||
menu->setID("modtober-banner");
|
||||
menu->ignoreAnchorPointForPosition(false);
|
||||
menu->setContentSize({ size.width, 30 });
|
||||
|
||||
auto banner = CCSprite::createWithSpriteFrameName("modtober24-banner.png"_spr);
|
||||
limitNodeWidth(banner, size.width, 1.f, .1f);
|
||||
menu->addChildAtPosition(banner, Anchor::Center);
|
||||
|
||||
auto label = CCLabelBMFont::create("Modtober 2024 is Here!", "bigFont.fnt");
|
||||
label->setScale(.5f);
|
||||
menu->addChildAtPosition(label, Anchor::Left, ccp(10, 0), ccp(0, .5f));
|
||||
|
||||
auto aboutSpr = createGeodeButton("About");
|
||||
aboutSpr->setScale(.5f);
|
||||
auto aboutBtn = CCMenuItemSpriteExtra::create(
|
||||
aboutSpr, this, menu_selector(ModList::onModtoberInfo)
|
||||
);
|
||||
menu->addChildAtPosition(aboutBtn, Anchor::Right, ccp(-35, 0));
|
||||
|
||||
m_topContainer->addChild(menu);
|
||||
}
|
||||
|
||||
m_topContainer->setLayout(
|
||||
ColumnLayout::create()
|
||||
->setGap(0)
|
||||
|
@ -492,7 +521,7 @@ void ModList::updateTopContainer() {
|
|||
auto oldPosition = oldPositionArea > 0.f ?
|
||||
m_list->m_contentLayer->getPositionY() / oldPositionArea :
|
||||
-1.f;
|
||||
|
||||
|
||||
// Update list size to account for the top menu
|
||||
// (giving a little bit of extra padding for it, the same size as gap)
|
||||
m_list->setContentHeight(
|
||||
|
@ -501,6 +530,8 @@ void ModList::updateTopContainer() {
|
|||
static_cast<AxisLayout*>(m_list->m_contentLayer->getLayout())->getGap() :
|
||||
this->getContentHeight()
|
||||
);
|
||||
static_cast<ColumnLayout*>(m_list->m_contentLayer->getLayout())->setAutoGrowAxis(m_list->getContentHeight());
|
||||
m_list->m_contentLayer->updateLayout();
|
||||
|
||||
// Preserve relative scroll position
|
||||
m_list->m_contentLayer->setPositionY((
|
||||
|
@ -659,6 +690,9 @@ void ModList::onToggleErrors(CCObject*) {
|
|||
void ModList::onUpdateAll(CCObject*) {
|
||||
server::ModDownloadManager::get()->startUpdateAll();
|
||||
}
|
||||
void ModList::onModtoberInfo(CCObject*) {
|
||||
ModtoberPopup::create()->show();
|
||||
}
|
||||
|
||||
size_t ModList::getPage() const {
|
||||
return m_page;
|
||||
|
|
|
@ -71,6 +71,7 @@ protected:
|
|||
void onToggleUpdates(CCObject*);
|
||||
void onToggleErrors(CCObject*);
|
||||
void onUpdateAll(CCObject*);
|
||||
void onModtoberInfo(CCObject*);
|
||||
|
||||
public:
|
||||
static ModList* create(ModListSource* src, CCSize const& size);
|
||||
|
|
|
@ -12,6 +12,7 @@ void askConfirmModInstalls() {
|
|||
size_t replacementCount = 0;
|
||||
size_t dependencyCount = 0;
|
||||
std::unordered_set<Mod*> toDisable;
|
||||
std::unordered_set<std::string> toDisableModId;
|
||||
std::unordered_set<Mod*> toEnable;
|
||||
};
|
||||
|
||||
|
@ -39,6 +40,11 @@ void askConfirmModInstalls() {
|
|||
if (inc.mod && inc.version.compare(conf->version.metadata.getVersion()) && inc.mod->isOrWillBeEnabled()) {
|
||||
toConfirm.toDisable.insert(inc.mod);
|
||||
}
|
||||
for (auto download : ModDownloadManager::get()->getDownloads()) {
|
||||
if (download.isDone() && inc.id == download.getID() && inc.version.compare(conf->version.metadata.getVersion())) {
|
||||
toConfirm.toDisableModId.insert(inc.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// If some installed mods are incompatible with this one, disable them
|
||||
for (auto mod : Loader::get()->getAllMods()) {
|
||||
|
@ -48,6 +54,17 @@ void askConfirmModInstalls() {
|
|||
}
|
||||
}
|
||||
}
|
||||
// If some newly downloaded mods are incompatible with this one, disable them
|
||||
for (auto download : ModDownloadManager::get()->getDownloads()) {
|
||||
auto status = download.getStatus();
|
||||
if (auto done = std::get_if<DownloadStatusDone>(&status)) {
|
||||
for (auto inc : done->version.metadata.getIncompatibilities()) {
|
||||
if (inc.id == conf->version.metadata.getID() && inc.version.compare(done->version.metadata.getVersion())) {
|
||||
toConfirm.toDisableModId.insert(download.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this mod has required dependencies that are disabled, enable them
|
||||
for (auto dep : conf->version.metadata.getDependencies()) {
|
||||
|
@ -71,6 +88,20 @@ void askConfirmModInstalls() {
|
|||
);
|
||||
};
|
||||
|
||||
auto joinIdsToIDs = [](std::unordered_set<std::string> const& ids) {
|
||||
return ranges::join(
|
||||
ranges::map<std::vector<std::string>>(
|
||||
ids, [](std::string const& id) { return fmt::format("<cp>{}</c>", id); }
|
||||
),
|
||||
", "
|
||||
);
|
||||
};
|
||||
|
||||
std::unordered_set<std::string> idsToDisable = toConfirm.toDisableModId;
|
||||
for (auto mod : toConfirm.toDisable) {
|
||||
idsToDisable.insert(mod->getID());
|
||||
}
|
||||
|
||||
createQuickPopup(
|
||||
"Confirm Install",
|
||||
fmt::format(
|
||||
|
@ -78,7 +109,7 @@ void askConfirmModInstalls() {
|
|||
"<cr>{} mods will be force-disabled, as they are incompatible</c>: {}\n"
|
||||
"<cg>{} mods will be force-enabled</c>: {}",
|
||||
toConfirm.modCount, toConfirm.dependencyCount, toConfirm.replacementCount,
|
||||
toConfirm.toDisable.size(), joinModsToIDs(toConfirm.toDisable),
|
||||
idsToDisable.size(), joinIdsToIDs(idsToDisable),
|
||||
toConfirm.toEnable.size(), joinModsToIDs(toConfirm.toEnable)
|
||||
),
|
||||
"Cancel", "Continue",
|
||||
|
@ -87,6 +118,9 @@ void askConfirmModInstalls() {
|
|||
for (auto mod : toConfirm.toDisable) {
|
||||
(void)mod->disable();
|
||||
}
|
||||
for (auto modId : toConfirm.toDisableModId) {
|
||||
Mod::get()->setSavedValue("should-load-" + modId, false);
|
||||
}
|
||||
for (auto mod : toConfirm.toEnable) {
|
||||
(void)mod->enable();
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ bool FiltersPopup::setup(ModListSource* src) {
|
|||
m_mainLayer->addChildAtPosition(inputContainer, Anchor::Bottom, ccp(0, 60), ccp(.5f, .5f));
|
||||
}
|
||||
|
||||
auto okSpr = createGeodeButton("OK");
|
||||
auto okSpr = createGeodeButton("OK", false, GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
okSpr->setScale(.7f);
|
||||
auto okBtn = CCMenuItemSpriteExtra::create(
|
||||
okSpr, this, menu_selector(FiltersPopup::onClose)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "ModPopup.hpp"
|
||||
#include <Geode/binding/ButtonSprite.hpp>
|
||||
#include <Geode/ui/MDTextArea.hpp>
|
||||
#include <Geode/ui/TextInput.hpp>
|
||||
#include <Geode/utils/web.hpp>
|
||||
#include <Geode/loader/Loader.hpp>
|
||||
#include <Geode/loader/ModSettingsManager.hpp>
|
||||
|
@ -10,6 +11,7 @@
|
|||
#include "../settings/ModSettingsPopup.hpp"
|
||||
#include "../../../internal/about.hpp"
|
||||
#include "../../GeodeUIEvent.hpp"
|
||||
#include "../popups/ModtoberPopup.hpp"
|
||||
|
||||
class FetchTextArea : public CCNode {
|
||||
public:
|
||||
|
@ -300,12 +302,12 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
manageTitle->setOpacity(195);
|
||||
manageContainer->addChildAtPosition(manageTitle, Anchor::Left, ccp(0, 0), ccp(0, .5f));
|
||||
|
||||
m_restartRequiredLabel = createGeodeTagLabel(
|
||||
m_restartRequiredLabel = createTagLabel(
|
||||
"Restart Required",
|
||||
{{
|
||||
{
|
||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label"_spr)),
|
||||
to3B(ColorProvider::get()->color("mod-list-restart-required-label-bg"_spr))
|
||||
}}
|
||||
}
|
||||
);
|
||||
m_restartRequiredLabel->setScale(.3f);
|
||||
manageContainer->addChildAtPosition(m_restartRequiredLabel, Anchor::Right, ccp(0, 0), ccp(1, .5f));
|
||||
|
@ -334,7 +336,8 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
auto updateModSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("update.png"_spr),
|
||||
"Update",
|
||||
GeodeButtonSprite::Install
|
||||
GeodeButtonSprite::Install,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
updateModSpr->setScale(.5f);
|
||||
m_updateBtn = CCMenuItemSpriteExtra::create(
|
||||
|
@ -345,13 +348,15 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
auto enableModOffSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("GJ_completesIcon_001.png"),
|
||||
"Enable",
|
||||
GeodeButtonSprite::Enable
|
||||
GeodeButtonSprite::Enable,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
enableModOffSpr->setScale(.5f);
|
||||
auto enableModOnSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png"),
|
||||
"Disable",
|
||||
GeodeButtonSprite::Delete
|
||||
GeodeButtonSprite::Delete,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
enableModOnSpr->setScale(.5f);
|
||||
m_enableBtn = CCMenuItemToggler::create(
|
||||
|
@ -364,7 +369,8 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
auto reenableModOffSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("reset.png"_spr),
|
||||
"Re-Enable",
|
||||
GeodeButtonSprite::Default
|
||||
GeodeButtonSprite::Default,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
reenableModOffSpr->setScale(.5f);
|
||||
auto reenableModOnSpr = createGeodeButton(
|
||||
|
@ -383,7 +389,8 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
auto installModSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("GJ_downloadsIcon_001.png"),
|
||||
"Install",
|
||||
GeodeButtonSprite::Install
|
||||
GeodeButtonSprite::Install,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
installModSpr->setScale(.5f);
|
||||
m_installBtn = CCMenuItemSpriteExtra::create(
|
||||
|
@ -394,7 +401,8 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
auto uninstallModSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("delete-white.png"_spr),
|
||||
"Uninstall",
|
||||
GeodeButtonSprite::Default
|
||||
GeodeButtonSprite::Default,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
uninstallModSpr->setScale(.5f);
|
||||
m_uninstallBtn = CCMenuItemSpriteExtra::create(
|
||||
|
@ -405,7 +413,8 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
auto cancelDownloadSpr = createGeodeButton(
|
||||
CCSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png"),
|
||||
"Cancel",
|
||||
GeodeButtonSprite::Default
|
||||
GeodeButtonSprite::Default,
|
||||
m_forceDisableTheme
|
||||
);
|
||||
cancelDownloadSpr->setScale(.5f);
|
||||
m_cancelBtn = CCMenuItemSpriteExtra::create(
|
||||
|
@ -565,7 +574,7 @@ bool ModPopup::setup(ModSource&& src) {
|
|||
m_settingsBG->setContentSize(ccp(35, 30) / linksBG->getScale());
|
||||
m_buttonMenu->addChildAtPosition(m_settingsBG, Anchor::BottomLeft, ccp(28, 25));
|
||||
|
||||
auto settingsSpr = createGeodeCircleButton(CCSprite::createWithSpriteFrameName("settings.png"_spr));
|
||||
auto settingsSpr = createGeodeCircleButton(CCSprite::createWithSpriteFrameName("settings.png"_spr), 1.f, CircleBaseSize::Medium, false, m_forceDisableTheme);
|
||||
settingsSpr->setScale(.6f);
|
||||
auto settingsBtn = CCMenuItemSpriteExtra::create(
|
||||
settingsSpr, this, menu_selector(ModPopup::onSettings)
|
||||
|
@ -880,10 +889,7 @@ void ModPopup::onLoadTags(typename server::ServerRequest<std::unordered_set<std:
|
|||
m_tags->removeAllChildren();
|
||||
|
||||
for (auto& tag : data) {
|
||||
auto readable = tag;
|
||||
readable[0] = std::toupper(readable[0]);
|
||||
auto colors = geodeTagColor(tag);
|
||||
m_tags->addChild(createGeodeTagLabel(readable));
|
||||
m_tags->addChild(createGeodeTagLabel(tag));
|
||||
}
|
||||
|
||||
if (data.empty()) {
|
||||
|
@ -891,6 +897,50 @@ void ModPopup::onLoadTags(typename server::ServerRequest<std::unordered_set<std:
|
|||
label->setOpacity(120);
|
||||
m_tags->addChild(label);
|
||||
}
|
||||
// This should probably be kept even after modtober ends,
|
||||
// so the banner sprite must be kept
|
||||
// If the build times from the cool popup become too long then we can
|
||||
// probably move that to a normal FLAlert that explains "Modtober was
|
||||
// this contest blah blah this mod was made for it"
|
||||
else if (data.contains("modtober24")) {
|
||||
auto menu = CCMenu::create();
|
||||
menu->setID("modtober-banner");
|
||||
menu->ignoreAnchorPointForPosition(false);
|
||||
menu->setContentSize({ m_rightColumn->getContentWidth(), 25 });
|
||||
|
||||
auto banner = CCSprite::createWithSpriteFrameName("modtober24-banner-2.png"_spr);
|
||||
limitNodeWidth(banner, m_rightColumn->getContentWidth(), 1.f, .1f);
|
||||
menu->addChildAtPosition(banner, Anchor::Center);
|
||||
|
||||
auto label = CCLabelBMFont::create("Entry for Modtober 2024", "bigFont.fnt");
|
||||
label->setScale(.35f);
|
||||
menu->addChildAtPosition(label, Anchor::Left, ccp(10, 0), ccp(0, .5f));
|
||||
|
||||
auto aboutSpr = createGeodeButton("About", false, GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
aboutSpr->setScale(.35f);
|
||||
auto aboutBtn = CCMenuItemSpriteExtra::create(
|
||||
aboutSpr, this, menu_selector(ModPopup::onModtoberInfo)
|
||||
);
|
||||
menu->addChildAtPosition(aboutBtn, Anchor::Right, ccp(-25, 0));
|
||||
|
||||
m_rightColumn->addChildAtPosition(menu, Anchor::Bottom, ccp(0, 0), ccp(.5f, 0));
|
||||
|
||||
m_modtoberBanner = menu;
|
||||
|
||||
// Force reload of all the tabs since otherwise their contents will overflow
|
||||
for (auto& [_, tab] : m_tabs) {
|
||||
if (tab.second && tab.second->getParent()) {
|
||||
tab.second->removeFromParent();
|
||||
}
|
||||
tab.second = nullptr;
|
||||
}
|
||||
|
||||
m_currentTabPage = nullptr;
|
||||
|
||||
// This might cause a minor inconvenience to someone who opens the popup and
|
||||
// immediately switches to changelog but is then forced back into details
|
||||
this->loadTab(Tab::Details);
|
||||
}
|
||||
|
||||
m_tags->updateLayout();
|
||||
|
||||
|
@ -920,12 +970,17 @@ void ModPopup::loadTab(ModPopup::Tab tab) {
|
|||
btn.first->select(value == tab);
|
||||
}
|
||||
|
||||
float modtoberBannerHeight = 0;
|
||||
if (m_modtoberBanner) {
|
||||
modtoberBannerHeight = 30;
|
||||
}
|
||||
|
||||
if (auto existing = m_tabs.at(tab).second) {
|
||||
m_currentTabPage = existing;
|
||||
m_rightColumn->addChildAtPosition(existing, Anchor::Bottom);
|
||||
m_rightColumn->addChildAtPosition(existing, Anchor::Bottom, ccp(0, modtoberBannerHeight));
|
||||
}
|
||||
else {
|
||||
const auto size = (m_rightColumn->getContentSize() - ccp(0, 30));
|
||||
const auto size = (m_rightColumn->getContentSize() - ccp(0, 30 + modtoberBannerHeight));
|
||||
const float mdScale = .85f;
|
||||
switch (tab) {
|
||||
case Tab::Details: {
|
||||
|
@ -955,7 +1010,7 @@ void ModPopup::loadTab(ModPopup::Tab tab) {
|
|||
} break;
|
||||
}
|
||||
m_currentTabPage->setAnchorPoint({ .5f, .0f });
|
||||
m_rightColumn->addChildAtPosition(m_currentTabPage, Anchor::Bottom);
|
||||
m_rightColumn->addChildAtPosition(m_currentTabPage, Anchor::Bottom, ccp(0, modtoberBannerHeight));
|
||||
m_tabs.at(tab).second = m_currentTabPage;
|
||||
}
|
||||
}
|
||||
|
@ -1030,6 +1085,12 @@ void ModPopup::onLink(CCObject* sender) {
|
|||
void ModPopup::onSupport(CCObject*) {
|
||||
openSupportPopup(m_source.getMetadata());
|
||||
}
|
||||
void ModPopup::onModtoberInfo(CCObject*) {
|
||||
// todo: if we want to get rid of the modtober popup sprite (because it's fucking massive)
|
||||
// then we can just replace this with a normal FLAlert explaining
|
||||
// "this mod was an entry for modtober 2024 blah blah blah"
|
||||
ModtoberPopup::create()->show();
|
||||
}
|
||||
|
||||
ModPopup* ModPopup::create(ModSource&& src) {
|
||||
auto ret = new ModPopup();
|
||||
|
|
|
@ -35,6 +35,7 @@ protected:
|
|||
ButtonSprite* m_restartRequiredLabel;
|
||||
CCNode* m_rightColumn;
|
||||
CCNode* m_currentTabPage = nullptr;
|
||||
CCNode* m_modtoberBanner = nullptr;
|
||||
std::unordered_map<Tab, std::pair<GeodeTabSprite*, Ref<CCNode>>> m_tabs;
|
||||
EventListener<server::ServerRequest<server::ServerModMetadata>> m_statsListener;
|
||||
EventListener<server::ServerRequest<std::unordered_set<std::string>>> m_tagsListener;
|
||||
|
@ -63,6 +64,7 @@ protected:
|
|||
void onSettings(CCObject*);
|
||||
void onLink(CCObject*);
|
||||
void onSupport(CCObject*);
|
||||
void onModtoberInfo(CCObject*);
|
||||
|
||||
public:
|
||||
void loadTab(Tab tab);
|
||||
|
|
44
loader/src/ui/mods/popups/ModtoberPopup.cpp
Normal file
44
loader/src/ui/mods/popups/ModtoberPopup.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include "ModtoberPopup.hpp"
|
||||
#include <Geode/utils/web.hpp>
|
||||
#include <Geode/loader/Mod.hpp>
|
||||
#include <Geode/binding/ButtonSprite.hpp>
|
||||
|
||||
bool ModtoberPopup::setup() {
|
||||
m_bgSprite->setVisible(false);
|
||||
|
||||
auto bg = CCSprite::createWithSpriteFrameName("modtober24-popup.png"_spr);
|
||||
m_mainLayer->addChildAtPosition(bg, Anchor::Center);
|
||||
|
||||
auto supportSpr = createGeodeButton("Join", false, GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
supportSpr->setScale(.8f);
|
||||
auto supportBtn = CCMenuItemSpriteExtra::create(
|
||||
supportSpr, this, menu_selector(ModtoberPopup::onDiscord)
|
||||
);
|
||||
m_buttonMenu->addChildAtPosition(supportBtn, Anchor::BottomRight, ccp(-65, 50));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModtoberPopup::onDiscord(CCObject*) {
|
||||
createQuickPopup(
|
||||
"Join Modtober",
|
||||
"<cf>Modtober</c> is being hosted on the <cg>GD Programming</c> <ca>Discord Server</c>.\n"
|
||||
"To participate, join GDP and read the rules for the contest in <co>#modtober-2024</c>",
|
||||
"Cancel", "Join Discord",
|
||||
[](auto, bool btn2) {
|
||||
if (btn2) {
|
||||
web::openLinkInBrowser("https://discord.gg/gd-programming-646101505417674758");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ModtoberPopup* ModtoberPopup::create() {
|
||||
auto ret = new ModtoberPopup();
|
||||
if (ret && ret->init(410, 270)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
CC_SAFE_DELETE(ret);
|
||||
return nullptr;
|
||||
}
|
16
loader/src/ui/mods/popups/ModtoberPopup.hpp
Normal file
16
loader/src/ui/mods/popups/ModtoberPopup.hpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/ui/Popup.hpp>
|
||||
#include "../GeodeStyle.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
||||
class ModtoberPopup : public GeodePopup<> {
|
||||
protected:
|
||||
bool setup() override;
|
||||
|
||||
void onDiscord(CCObject*);
|
||||
|
||||
public:
|
||||
static ModtoberPopup* create();
|
||||
};
|
|
@ -6,6 +6,7 @@
|
|||
#include <Geode/ui/ScrollLayer.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include <Geode/ui/General.hpp>
|
||||
#include <Geode/ui/Scrollbar.hpp>
|
||||
#include <loader/SettingNodeV3.hpp>
|
||||
// needed for weightedFuzzyMatch
|
||||
#include <ui/mods/sources/ModListSource.hpp>
|
||||
|
@ -25,10 +26,7 @@ static bool matchSearch(SettingNodeV3* node, std::string const& query) {
|
|||
else {
|
||||
addToList |= weightedFuzzyMatch(setting->getKey(), query, 1, weighted);
|
||||
}
|
||||
if (auto desc = setting->getDescription()) {
|
||||
addToList |= weightedFuzzyMatch(*desc, query, 0.02, weighted);
|
||||
}
|
||||
if (weighted < 2) {
|
||||
if (weighted < 60 + 10 * query.size()) {
|
||||
addToList = false;
|
||||
}
|
||||
return addToList;
|
||||
|
@ -62,7 +60,7 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
m_searchInput->setID("search-input");
|
||||
searchContainer->addChildAtPosition(m_searchInput, Anchor::Left, ccp(7.5f, 0), ccp(0, .5f));
|
||||
|
||||
auto searchClearSpr = GeodeSquareSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png");
|
||||
auto searchClearSpr = GeodeSquareSprite::createWithSpriteFrameName("GJ_deleteIcon_001.png", nullptr, m_forceDisableTheme);
|
||||
searchClearSpr->setScale(.45f);
|
||||
m_searchClearBtn = CCMenuItemSpriteExtra::create(
|
||||
searchClearSpr, this, menu_selector(ModSettingsPopup::onClearSearch)
|
||||
|
@ -83,11 +81,6 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
else {
|
||||
node = UnresolvedCustomSettingNodeV3::create(key, mod, layerSize.width);
|
||||
}
|
||||
|
||||
// auto separator = CCLayerColor::create({ 0, 0, 0, 50 }, layerSize.width, 1.f);
|
||||
// separator->setOpacity(bg ? 100 : 50);
|
||||
// separator->ignoreAnchorPointForPosition(false);
|
||||
// bg->addChildAtPosition(separator, Anchor::Bottom, ccp(0, 0), ccp(.5f, .5f));
|
||||
|
||||
m_settings.push_back(node);
|
||||
m_list->m_contentLayer->addChild(node);
|
||||
|
@ -95,18 +88,23 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
m_list->m_contentLayer->setLayout(
|
||||
ColumnLayout::create()
|
||||
->setAxisReverse(true)
|
||||
->setAutoGrowAxis(layerSize.height)
|
||||
->setAutoGrowAxis(m_list->getContentHeight())
|
||||
->setCrossAxisOverflow(false)
|
||||
->setAxisAlignment(AxisAlignment::End)
|
||||
->setGap(0)
|
||||
);
|
||||
m_list->moveToTop();
|
||||
|
||||
const int buttonPriority = m_list->getTouchPriority() - 1;
|
||||
|
||||
m_buttonMenu->setTouchPriority(buttonPriority);
|
||||
searchContainer->setTouchPriority(buttonPriority);
|
||||
|
||||
layerBG->addChildAtPosition(m_list, Anchor::BottomLeft);
|
||||
|
||||
// layer borders
|
||||
|
||||
m_mainLayer->addChildAtPosition(createGeodeListBorders(layerSize), Anchor::Center);
|
||||
m_mainLayer->addChildAtPosition(createGeodeListBorders(layerSize, m_forceDisableTheme), Anchor::Center);
|
||||
|
||||
auto scrollBar = Scrollbar::create(m_list);
|
||||
m_mainLayer->addChildAtPosition(
|
||||
|
@ -119,15 +117,16 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
m_applyMenu->setContentWidth(150);
|
||||
m_applyMenu->setLayout(RowLayout::create());
|
||||
m_applyMenu->getLayout()->ignoreInvisibleChildren(true);
|
||||
m_applyMenu->setTouchPriority(buttonPriority);
|
||||
|
||||
auto restartBtnSpr = createGeodeButton("Restart Now", true);
|
||||
auto restartBtnSpr = createGeodeButton("Restart Now", true, GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
restartBtnSpr->setScale(.6f);
|
||||
m_restartBtn = CCMenuItemSpriteExtra::create(
|
||||
restartBtnSpr, this, menu_selector(ModSettingsPopup::onRestart)
|
||||
);
|
||||
m_applyMenu->addChildAtPosition(m_restartBtn, Anchor::Bottom, ccp(0, 20));
|
||||
|
||||
m_applyBtnSpr = createGeodeButton("Apply", true);
|
||||
m_applyBtnSpr = createGeodeButton("Apply", true, GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
m_applyBtnSpr->setScale(.6f);
|
||||
m_applyBtn = CCMenuItemSpriteExtra::create(
|
||||
m_applyBtnSpr, this, menu_selector(ModSettingsPopup::onApply)
|
||||
|
@ -136,7 +135,7 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
|
||||
m_mainLayer->addChildAtPosition(m_applyMenu, Anchor::Bottom, ccp(0, 20));
|
||||
|
||||
auto resetBtnSpr = createGeodeButton("Reset All", true);
|
||||
auto resetBtnSpr = createGeodeButton("Reset All", true, GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
resetBtnSpr->setScale(.6f);
|
||||
|
||||
auto resetBtn = CCMenuItemSpriteExtra::create(
|
||||
|
@ -144,28 +143,46 @@ bool ModSettingsPopup::setup(Mod* mod) {
|
|||
);
|
||||
m_buttonMenu->addChildAtPosition(resetBtn, Anchor::BottomLeft, ccp(45, 20));
|
||||
|
||||
auto configFolderSpr = CCSprite::createWithSpriteFrameName("folderIcon_001.png");
|
||||
m_openConfigDirBtnSpr = createGeodeButton(configFolderSpr, "");
|
||||
m_openConfigDirBtnSpr->setScale(.6f);
|
||||
m_openConfigDirBtnSpr->getIcon()->setScale(m_openConfigDirBtnSpr->getIcon()->getScale() * 1.4f);
|
||||
auto openConfigDirBtn = CCMenuItemSpriteExtra::create(
|
||||
m_openConfigDirBtnSpr, this, menu_selector(ModSettingsPopup::onOpenConfigDirectory)
|
||||
);
|
||||
m_buttonMenu->addChildAtPosition(openConfigDirBtn, Anchor::BottomRight, ccp(-50, 20));
|
||||
auto foldersMenu = CCMenu::create();
|
||||
foldersMenu->setContentSize({ 0, 30 });
|
||||
foldersMenu->setAnchorPoint(ccp(1, 0));
|
||||
foldersMenu->setLayout(RowLayout::create()
|
||||
->setAxisReverse(true)
|
||||
->setGap(5)
|
||||
->setAutoGrowAxis(30)
|
||||
->setGrowCrossAxis(true));
|
||||
m_buttonMenu->addChildAtPosition(foldersMenu, Anchor::BottomRight, ccp(-5, 10));
|
||||
|
||||
auto settingFolderSpr = CCSprite::createWithSpriteFrameName("folderIcon_001.png");
|
||||
auto settingFolderSprSub = CCSprite::createWithSpriteFrameName("settings.png"_spr);
|
||||
settingFolderSprSub->setColor(ccBLACK);
|
||||
settingFolderSprSub->setOpacity(155);
|
||||
settingFolderSprSub->setScale(.55f);
|
||||
settingFolderSpr->addChildAtPosition(settingFolderSprSub, Anchor::Center, ccp(0, -3));
|
||||
auto openDirBtnSpr = createGeodeButton(settingFolderSpr, "");
|
||||
openDirBtnSpr->setScale(.6f);
|
||||
openDirBtnSpr->getIcon()->setScale(openDirBtnSpr->getIcon()->getScale() * 1.4f);
|
||||
auto openDirBtn = CCMenuItemSpriteExtra::create(
|
||||
openDirBtnSpr, this, menu_selector(ModSettingsPopup::onOpenSaveDirectory)
|
||||
);
|
||||
m_buttonMenu->addChildAtPosition(openDirBtn, Anchor::BottomRight, ccp(-20, 20));
|
||||
auto createFolderButton = [&, this](auto subSprName, auto callback) {
|
||||
auto folderSpr = CCSprite::createWithSpriteFrameName("folderIcon_001.png");
|
||||
auto folderSprSub = CCSprite::createWithSpriteFrameName(subSprName);
|
||||
folderSprSub->setColor(ccBLACK);
|
||||
folderSprSub->setOpacity(155);
|
||||
folderSprSub->setScale(.55f);
|
||||
folderSpr->addChildAtPosition(folderSprSub, Anchor::Center, ccp(0, -3));
|
||||
auto buttonSpr = createGeodeButton(folderSpr, "", GeodeButtonSprite::Default, m_forceDisableTheme);
|
||||
buttonSpr->setScale(.6f);
|
||||
buttonSpr->getIcon()->setScale(buttonSpr->getIcon()->getScale() * 1.4f);
|
||||
auto folderBtn = CCMenuItemSpriteExtra::create(
|
||||
buttonSpr, this, static_cast<SEL_MenuHandler>(callback)
|
||||
);
|
||||
foldersMenu->addChild(folderBtn);
|
||||
return folderBtn;
|
||||
};
|
||||
|
||||
createFolderButton("save.png"_spr, &ModSettingsPopup::onOpenSaveDirectory);
|
||||
createFolderButton("settings.png"_spr, &ModSettingsPopup::onOpenConfigDirectory);
|
||||
auto persistentBtn = createFolderButton("persistent.png"_spr, &ModSettingsPopup::onOpenPersistentDirectory);
|
||||
if (!std::filesystem::exists(mod->getPersistentDir(false))) {
|
||||
persistentBtn->setEnabled(false);
|
||||
auto spr = static_cast<CCSprite*>(persistentBtn->getNormalImage());
|
||||
spr->setCascadeColorEnabled(true);
|
||||
spr->setCascadeOpacityEnabled(true);
|
||||
spr->setColor(ccGRAY);
|
||||
spr->setOpacity(155);
|
||||
}
|
||||
|
||||
foldersMenu->updateLayout();
|
||||
|
||||
m_changeListener.bind([this](auto* ev) {
|
||||
this->updateState(ev->getNode());
|
||||
|
@ -223,7 +240,9 @@ void ModSettingsPopup::onOpenSaveDirectory(CCObject*) {
|
|||
}
|
||||
void ModSettingsPopup::onOpenConfigDirectory(CCObject*) {
|
||||
file::openFolder(m_mod->getConfigDir());
|
||||
this->updateState();
|
||||
}
|
||||
void ModSettingsPopup::onOpenPersistentDirectory(CCObject*) {
|
||||
file::openFolder(m_mod->getPersistentDir());
|
||||
}
|
||||
void ModSettingsPopup::onClearSearch(CCObject*) {
|
||||
m_searchInput->setString("");
|
||||
|
@ -238,12 +257,6 @@ void ModSettingsPopup::updateState(SettingNodeV3* invoker) {
|
|||
m_restartBtn->setVisible(ModSettingsManager::from(m_mod)->restartRequired());
|
||||
m_applyMenu->updateLayout();
|
||||
|
||||
auto configDirExists = std::filesystem::exists(m_mod->getConfigDir(false));
|
||||
m_openConfigDirBtnSpr->setCascadeColorEnabled(true);
|
||||
m_openConfigDirBtnSpr->setCascadeOpacityEnabled(true);
|
||||
m_openConfigDirBtnSpr->setColor(configDirExists ? ccWHITE : ccGRAY);
|
||||
m_openConfigDirBtnSpr->setOpacity(configDirExists ? 255 : 155);
|
||||
|
||||
auto listPosBefore = m_list->m_contentLayer->getPositionY();
|
||||
auto listHeightBefore = m_list->m_contentLayer->getContentHeight();
|
||||
|
||||
|
@ -330,9 +343,9 @@ void ModSettingsPopup::onClose(CCObject* sender) {
|
|||
GeodePopup::onClose(sender);
|
||||
}
|
||||
|
||||
ModSettingsPopup* ModSettingsPopup::create(Mod* mod) {
|
||||
ModSettingsPopup* ModSettingsPopup::create(Mod* mod, bool forceDisableTheme) {
|
||||
auto ret = new ModSettingsPopup();
|
||||
if (ret->init(440, 280, mod)) {
|
||||
if (ret->init(440, 280, mod, GeodePopupStyle::Default, forceDisableTheme)) {
|
||||
ret->autorelease();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
#include <Geode/loader/SettingV3.hpp>
|
||||
#include <Geode/ui/Popup.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include <Geode/ui/ScrollLayer.hpp>
|
||||
#include <Geode/ui/TextInput.hpp>
|
||||
|
||||
#include "../GeodeStyle.hpp"
|
||||
|
||||
using namespace geode::prelude;
|
||||
|
@ -16,7 +19,6 @@ protected:
|
|||
CCMenuItemSpriteExtra* m_applyBtn;
|
||||
CCMenuItemSpriteExtra* m_restartBtn;
|
||||
ButtonSprite* m_applyBtnSpr;
|
||||
IconButtonSprite* m_openConfigDirBtnSpr;
|
||||
TextInput* m_searchInput;
|
||||
CCMenuItemSpriteExtra* m_searchClearBtn;
|
||||
EventListener<EventFilter<SettingNodeValueChangeEventV3>> m_changeListener;
|
||||
|
@ -30,8 +32,9 @@ protected:
|
|||
void onResetAll(CCObject*);
|
||||
void onOpenSaveDirectory(CCObject*);
|
||||
void onOpenConfigDirectory(CCObject*);
|
||||
void onOpenPersistentDirectory(CCObject*);
|
||||
void onClearSearch(CCObject*);
|
||||
|
||||
public:
|
||||
static ModSettingsPopup* create(Mod* mod);
|
||||
static ModSettingsPopup* create(Mod* mod, bool forceDisableTheme = false);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include <Geode/utils/string.hpp>
|
||||
#include <server/Server.hpp>
|
||||
#include "../list/ModItem.hpp"
|
||||
|
||||
|
@ -143,6 +144,7 @@ enum class ServerModListType {
|
|||
Featured,
|
||||
Trending,
|
||||
Recent,
|
||||
Modtober24,
|
||||
};
|
||||
|
||||
class ServerModListSource : public ModListSource {
|
||||
|
@ -165,6 +167,8 @@ public:
|
|||
server::ModsQuery const& getQuery() const;
|
||||
InvalidateQueryAfter<server::ModsQuery> getQueryMut();
|
||||
bool isDefaultQuery() const override;
|
||||
server::ModsQuery createDefaultQuery() const;
|
||||
ServerModListType getType() const;
|
||||
};
|
||||
|
||||
class ModPackListSource : public ModListSource {
|
||||
|
@ -191,6 +195,7 @@ void filterModsWithLocalQuery(ModListSource::ProvidedMods& mods, Query const& qu
|
|||
std::vector<std::pair<ModSource, double>> filtered;
|
||||
|
||||
// Filter installed mods based on query
|
||||
// TODO: maybe skip fuzzy matching altogether if query is empty?
|
||||
for (auto& src : mods.mods) {
|
||||
double weighted = 0;
|
||||
bool addToList = true;
|
||||
|
@ -223,7 +228,10 @@ void filterModsWithLocalQuery(ModListSource::ProvidedMods& mods, Query const& qu
|
|||
return a.second > b.second;
|
||||
}
|
||||
// Sort secondarily alphabetically
|
||||
return a.first.getMetadata().getName() < b.first.getMetadata().getName();
|
||||
return utils::string::caseInsensitiveCompare(
|
||||
a.first.getMetadata().getName(),
|
||||
b.first.getMetadata().getName()
|
||||
) == std::strong_ordering::less;
|
||||
});
|
||||
|
||||
mods.mods.clear();
|
||||
|
|
|
@ -1,29 +1,7 @@
|
|||
#include "ModListSource.hpp"
|
||||
|
||||
void ServerModListSource::resetQuery() {
|
||||
switch (m_type) {
|
||||
case ServerModListType::Download: {
|
||||
m_query = server::ModsQuery {};
|
||||
} break;
|
||||
|
||||
case ServerModListType::Featured: {
|
||||
m_query = server::ModsQuery {
|
||||
.featured = true,
|
||||
};
|
||||
} break;
|
||||
|
||||
case ServerModListType::Trending: {
|
||||
m_query = server::ModsQuery {
|
||||
.sorting = server::ModsSort::RecentlyUpdated,
|
||||
};
|
||||
} break;
|
||||
|
||||
case ServerModListType::Recent: {
|
||||
m_query = server::ModsQuery {
|
||||
.sorting = server::ModsSort::RecentlyPublished,
|
||||
};
|
||||
} break;
|
||||
}
|
||||
m_query = this->createDefaultQuery();
|
||||
}
|
||||
|
||||
ServerModListSource::ProviderTask ServerModListSource::fetchPage(size_t page, size_t pageSize, bool forceUpdate) {
|
||||
|
@ -56,7 +34,7 @@ ServerModListSource::ServerModListSource(ServerModListType type)
|
|||
|
||||
ServerModListSource* ServerModListSource::get(ServerModListType type) {
|
||||
switch (type) {
|
||||
default:
|
||||
default: [[fallthrough]];
|
||||
case ServerModListType::Download: {
|
||||
static auto inst = new ServerModListSource(ServerModListType::Download);
|
||||
return inst;
|
||||
|
@ -76,6 +54,11 @@ ServerModListSource* ServerModListSource::get(ServerModListType type) {
|
|||
static auto inst = new ServerModListSource(ServerModListType::Recent);
|
||||
return inst;
|
||||
} break;
|
||||
|
||||
case ServerModListType::Modtober24: {
|
||||
static auto inst = new ServerModListSource(ServerModListType::Modtober24);
|
||||
return inst;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +87,31 @@ InvalidateQueryAfter<server::ModsQuery> ServerModListSource::getQueryMut() {
|
|||
return InvalidateQueryAfter(m_query, this);
|
||||
}
|
||||
bool ServerModListSource::isDefaultQuery() const {
|
||||
return !m_query.query.has_value() &&
|
||||
m_query.tags.empty() &&
|
||||
!m_query.developer.has_value();
|
||||
return m_query == this->createDefaultQuery();
|
||||
}
|
||||
|
||||
server::ModsQuery ServerModListSource::createDefaultQuery() const {
|
||||
switch (m_type) {
|
||||
case ServerModListType::Download: return server::ModsQuery {};
|
||||
|
||||
case ServerModListType::Featured: return server::ModsQuery {
|
||||
.featured = true,
|
||||
};
|
||||
|
||||
case ServerModListType::Trending: return server::ModsQuery {
|
||||
.sorting = server::ModsSort::RecentlyUpdated,
|
||||
};
|
||||
|
||||
case ServerModListType::Recent: return server::ModsQuery {
|
||||
.sorting = server::ModsSort::RecentlyPublished,
|
||||
};
|
||||
|
||||
case ServerModListType::Modtober24: return server::ModsQuery {
|
||||
.tags = { "modtober24" },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
ServerModListType ServerModListSource::getType() const {
|
||||
return m_type;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue