merge utils to be in fewer better-named files

This commit is contained in:
HJfod 2022-11-28 19:09:39 +02:00
parent dd65a36f2c
commit 516393ae99
59 changed files with 838 additions and 1504 deletions

View file

@ -1,17 +1,12 @@
#pragma once
#include "utils/Ref.hpp"
#include "DefaultInclude.hpp"
#include "utils/Result.hpp"
#include "utils/VersionInfo.hpp"
#include "utils/casts.hpp"
#include "utils/cocos.hpp"
#include "utils/convert.hpp"
#include "utils/ext.hpp"
#include "utils/map.hpp"
#include "utils/string.hpp"
#include "utils/file.hpp"
#include "utils/general.hpp"
#include "utils/json.hpp"
#include "utils/operators.hpp"
#include "utils/platform.hpp"
#include "utils/timer.hpp"
#include "utils/types.hpp"
#include <Geode/DefaultInclude.hpp>

View file

@ -1,11 +1,11 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <Geode/hook-core/Hook.hpp>
#include <Geode/utils/types.hpp>
#include "../DefaultInclude.hpp"
#include "../hook-core/Hook.hpp"
#include "../utils/general.hpp"
#include "../external/json/json.hpp"
#include <inttypes.h>
#include <string_view>
#include "../utils/json.hpp"
namespace geode {
class Mod;

View file

@ -4,11 +4,12 @@
#include "Setting.hpp"
#include "Types.hpp"
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/Result.hpp>
#include <Geode/utils/VersionInfo.hpp>
#include <Geode/utils/json.hpp>
#include <Geode/utils/types.hpp>
#include "../DefaultInclude.hpp"
#include "../utils/Result.hpp"
#include "../utils/VersionInfo.hpp"
#include "../external/json/json.hpp"
#include "../utils/general.hpp"
#include "../cocos/support/zip_support/ZipUtils.h"
#include <optional>
#include <string_view>
#include <type_traits>

View file

@ -1,13 +1,12 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/JsonValidation.hpp>
#include <Geode/utils/Result.hpp>
#include <Geode/utils/container.hpp>
#include <Geode/utils/convert.hpp>
#include <Geode/utils/json.hpp>
#include <Geode/utils/platform.hpp>
#include <Geode/utils/ranges.hpp>
#include "../DefaultInclude.hpp"
#include "../utils/JsonValidation.hpp"
#include "../utils/Result.hpp"
#include "../external/json/json.hpp"
#include "../utils/file.hpp"
#include "../utils/ranges.hpp"
#include "../utils/cocos.hpp"
#include <optional>
#include <regex>
#include <unordered_set>

View file

@ -1,6 +1,6 @@
#pragma once
#include "../utils/Ref.hpp"
#include "../utils/cocos.hpp"
#include "SceneManager.hpp"
#include <chrono>

View file

@ -1,7 +1,7 @@
#pragma once
#include "../loader/Log.hpp"
#include "json.hpp"
#include "../external/json/json.hpp"
#include <set>
#include <variant>

View file

@ -1,132 +0,0 @@
#pragma once
#include <cocos2d.h>
namespace geode {
/**
* A smart pointer to a managed CCObject-deriving class. Retains shared
* ownership over the managed instance. Releases the object when the Ref
* is destroyed, or assigned another object or nullptr.
*
* Use-cases include, for example, non-CCNode class members, or nodes that
* are not always in the scene tree.
*
* @example class MyNode : public CCNode {
* protected:
* // no need to manually call retain or
* // release on this array; Ref manages it
* // for you :3
* Ref<CCArray> m_list = CCArray::create();
* };
*/
template <class T>
class Ref final {
static_assert(
std::is_base_of_v<cocos2d::CCObject, T>,
"Ref can only be used with a CCObject-inheriting class!"
);
T* m_obj = nullptr;
public:
/**
* Construct a Ref of an object. The object will be retained and
* managed until Ref goes out of scope
*/
Ref(T* obj) : m_obj(obj) {
CC_SAFE_RETAIN(obj);
}
Ref(Ref<T> const& other) : Ref(other.data()) {}
Ref(Ref<T>&& other) : m_obj(other.m_obj) {
other.m_obj = nullptr;
}
/**
* Construct an empty Ref (the managed object will be null)
*/
Ref() = default;
~Ref() {
CC_SAFE_RELEASE(m_obj);
}
/**
* Swap the managed object with another object. The managed object
* will be released, and the new object retained
* @param other The new object to swap to
*/
void swap(T* other) {
CC_SAFE_RELEASE(m_obj);
m_obj = other;
CC_SAFE_RETAIN(other);
}
/**
* Return the managed object
* @returns The managed object
*/
T* data() const {
return m_obj;
}
operator T*() const {
return m_obj;
}
T* operator*() const {
return m_obj;
}
T* operator->() const {
return m_obj;
}
T* operator=(T* obj) {
this->swap(obj);
return obj;
}
Ref<T>& operator=(Ref<T> const& other) {
this->swap(other.data());
return *this;
}
Ref<T>& operator=(Ref<T>&& other) {
this->swap(other.data());
return *this;
}
bool operator==(T* other) const {
return m_obj == other;
}
bool operator==(Ref<T> const& other) const {
return m_obj == other.m_obj;
}
bool operator!=(T* other) const {
return m_obj != other;
}
bool operator!=(Ref<T> const& other) const {
return m_obj != other.m_obj;
}
// for containers
bool operator<(Ref<T> const& other) const {
return m_obj < other.m_obj;
}
bool operator>(Ref<T> const& other) const {
return m_obj > other.m_obj;
}
};
}
namespace std {
template<class T>
struct hash<geode::Ref<T>> {
size_t operator()(geode::Ref<T> const& ref) const {
return std::hash<T*>()(ref.data());
}
};
}

View file

@ -1,8 +1,8 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include "../DefaultInclude.hpp"
#include <string_view>
#include "json.hpp"
#include "../external/json/json.hpp"
namespace geode {
/**

View file

@ -1,14 +0,0 @@
#pragma once
#define CCARRAY_FOREACH_B_BASE(__array__, __obj__, __type__, __index__) \
if ((__array__) && (__array__)->count()) \
for (auto [__index__, __obj__] = std::tuple<unsigned int, __type__> { 0u, nullptr }; \
(__index__ < (__array__)->count() && \
(__obj__ = static_cast<__type__>((__array__)->objectAtIndex(__index__)))); \
__index__++)
#define CCARRAY_FOREACH_B_TYPE(__array__, __obj__, __type__) \
CCARRAY_FOREACH_B_BASE(__array__, __obj__, __type__*, ccArray_forEach_b_base_index)
#define CCARRAY_FOREACH_B(__array__, __obj__) \
CCARRAY_FOREACH_B_BASE(__array__, __obj__, cocos2d::CCObject*, ccArray_forEach_b_index)

View file

@ -1,13 +1,310 @@
#pragma once
#include "Ref.hpp"
#include "casts.hpp"
#include "../external/json/json.hpp"
#include "general.hpp"
#include <Geode/DefaultInclude.hpp>
#include <cocos2d.h>
#include <functional>
#include <type_traits>
// support converting ccColor3B / ccColor4B to / from json
namespace cocos2d {
void GEODE_DLL to_json(nlohmann::json& json, cocos2d::ccColor3B const& color);
void GEODE_DLL from_json(nlohmann::json const& json, cocos2d::ccColor3B& color);
void GEODE_DLL to_json(nlohmann::json& json, cocos2d::ccColor4B const& color);
void GEODE_DLL from_json(nlohmann::json const& json, cocos2d::ccColor4B& color);
}
// operators for CC geometry
namespace geode {
static 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) {
size.width *= mul;
size.height *= mul;
return size;
}
static 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) {
rect.origin *= mul;
rect.size *= mul;
return rect;
}
static cocos2d::CCRect operator*(cocos2d::CCRect const& rect, float mul) {
return {
rect.origin.x * mul,
rect.origin.y * mul,
rect.size.width * mul,
rect.size.height * mul,
};
}
static 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) {
size.width /= div;
size.height /= div;
return size;
}
static 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) {
pos.x += add.x;
pos.y += add.y;
return pos;
}
static 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) {
size.width += add.width;
size.height += add.height;
return size;
}
static 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) {
rect.size += add;
return rect;
}
static 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) {
pos.x -= add.x;
pos.y -= add.y;
return pos;
}
static 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) {
size.width -= add.width;
size.height -= add.height;
return size;
}
static 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) {
rect.size -= add;
return rect;
}
static 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) {
return { size.width - f, size.height - f };
}
static cocos2d::CCSize operator-(cocos2d::CCSize const& size) {
return { -size.width, -size.height };
}
static 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) {
return p1.x != p2.x || p1.y != p2.y;
}
static 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) {
return s1.width != s2.width || s1.height != s2.height;
}
static 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) {
return r1.origin != r2.origin || r1.size != r2.size;
}
static 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) {
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) {
return c1.r != c2.r || c1.g != c2.g || c1.b != c2.b;
}
}
// Ref
namespace geode {
/**
* A smart pointer to a managed CCObject-deriving class. Retains shared
* ownership over the managed instance. Releases the object when the Ref
* is destroyed, or assigned another object or nullptr.
*
* Use-cases include, for example, non-CCNode class members, or nodes that
* are not always in the scene tree.
*
* @example class MyNode : public CCNode {
* protected:
* // no need to manually call retain or
* // release on this array; Ref manages it
* // for you :3
* Ref<CCArray> m_list = CCArray::create();
* };
*/
template <class T>
class Ref final {
static_assert(
std::is_base_of_v<cocos2d::CCObject, T>,
"Ref can only be used with a CCObject-inheriting class!"
);
T* m_obj = nullptr;
public:
/**
* Construct a Ref of an object. The object will be retained and
* managed until Ref goes out of scope
*/
Ref(T* obj) : m_obj(obj) {
CC_SAFE_RETAIN(obj);
}
Ref(Ref<T> const& other) : Ref(other.data()) {}
Ref(Ref<T>&& other) : m_obj(other.m_obj) {
other.m_obj = nullptr;
}
/**
* Construct an empty Ref (the managed object will be null)
*/
Ref() = default;
~Ref() {
CC_SAFE_RELEASE(m_obj);
}
/**
* Swap the managed object with another object. The managed object
* will be released, and the new object retained
* @param other The new object to swap to
*/
void swap(T* other) {
CC_SAFE_RELEASE(m_obj);
m_obj = other;
CC_SAFE_RETAIN(other);
}
/**
* Return the managed object
* @returns The managed object
*/
T* data() const {
return m_obj;
}
operator T*() const {
return m_obj;
}
T* operator*() const {
return m_obj;
}
T* operator->() const {
return m_obj;
}
T* operator=(T* obj) {
this->swap(obj);
return obj;
}
Ref<T>& operator=(Ref<T> const& other) {
this->swap(other.data());
return *this;
}
Ref<T>& operator=(Ref<T>&& other) {
this->swap(other.data());
return *this;
}
bool operator==(T* other) const {
return m_obj == other;
}
bool operator==(Ref<T> const& other) const {
return m_obj == other.m_obj;
}
bool operator!=(T* other) const {
return m_obj != other;
}
bool operator!=(Ref<T> const& other) const {
return m_obj != other.m_obj;
}
// for containers
bool operator<(Ref<T> const& other) const {
return m_obj < other.m_obj;
}
bool operator>(Ref<T> const& other) const {
return m_obj > other.m_obj;
}
};
}
// Cocos2d utils
namespace geode::cocos {
/**
* Get child at index. Checks bounds. A negative
@ -300,9 +597,141 @@ namespace geode::cocos {
}
};
inline void ccDrawColor4B(cocos2d::ccColor4B const& color) {
cocos2d::ccDrawColor4B(color.r, color.g, color.b, color.a);
}
inline cocos2d::ccColor4B invert4B(cocos2d::ccColor4B const& color) {
return { static_cast<GLubyte>(255 - color.r), static_cast<GLubyte>(255 - color.g),
static_cast<GLubyte>(255 - color.b), color.a };
}
inline cocos2d::ccColor3B invert3B(cocos2d::ccColor3B const& color) {
return { static_cast<GLubyte>(255 - color.r), static_cast<GLubyte>(255 - color.g),
static_cast<GLubyte>(255 - color.b) };
}
inline cocos2d::ccColor3B lighten3B(cocos2d::ccColor3B const& color, int amount) {
return {
static_cast<GLubyte>(utils::clamp(color.r + amount, 0, 255)),
static_cast<GLubyte>(utils::clamp(color.g + amount, 0, 255)),
static_cast<GLubyte>(utils::clamp(color.b + amount, 0, 255)),
};
}
inline cocos2d::ccColor3B darken3B(cocos2d::ccColor3B const& color, int amount) {
return lighten3B(color, -amount);
}
inline cocos2d::ccColor3B to3B(cocos2d::ccColor4B const& color) {
return { color.r, color.g, color.b };
}
inline cocos2d::ccColor4B to4B(cocos2d::ccColor3B const& color, GLubyte alpha = 255) {
return { color.r, color.g, color.b, alpha };
}
inline cocos2d::ccColor4F to4F(cocos2d::ccColor4B const& color) {
return { color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f };
}
constexpr cocos2d::ccColor3B cc3x(int hexValue) {
if (hexValue <= 0xf)
return cocos2d::ccColor3B { static_cast<GLubyte>(hexValue * 17),
static_cast<GLubyte>(hexValue * 17),
static_cast<GLubyte>(hexValue * 17) };
if (hexValue <= 0xff)
return cocos2d::ccColor3B { static_cast<GLubyte>(hexValue),
static_cast<GLubyte>(hexValue),
static_cast<GLubyte>(hexValue) };
if (hexValue <= 0xfff)
return cocos2d::ccColor3B { static_cast<GLubyte>((hexValue >> 8 & 0xf) * 17),
static_cast<GLubyte>((hexValue >> 4 & 0xf) * 17),
static_cast<GLubyte>((hexValue >> 0 & 0xf) * 17) };
else
return cocos2d::ccColor3B { static_cast<GLubyte>(hexValue >> 16 & 0xff),
static_cast<GLubyte>(hexValue >> 8 & 0xff),
static_cast<GLubyte>(hexValue >> 0 & 0xff) };
}
GEODE_DLL Result<cocos2d::ccColor3B> cc3bFromHexString(std::string const& hexValue);
GEODE_DLL Result<cocos2d::ccColor4B> cc4bFromHexString(std::string const& hexValue);
GEODE_DLL std::string cc3bToHexString(cocos2d::ccColor3B const& color);
GEODE_DLL std::string cc4bToHexString(cocos2d::ccColor4B const& color);
template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>>
static cocos2d::CCArray* vectorToCCArray(std::vector<T> const& vec) {
auto res = cocos2d::CCArray::createWithCapacity(vec.size());
for (auto const& item : vec)
res->addObject(item);
return res;
}
template <typename T, typename C, typename = std::enable_if_t<std::is_pointer_v<C>>>
static cocos2d::CCArray* vectorToCCArray(
std::vector<T> const& vec, std::function<C(T)> convFunc
) {
auto res = cocos2d::CCArray::createWithCapacity(vec.size());
for (auto const& item : vec)
res->addObject(convFunc(item));
return res;
}
template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>>
std::vector<T> ccArrayToVector(cocos2d::CCArray* arr) {
return std::vector<T>(
reinterpret_cast<T*>(arr->data->arr),
reinterpret_cast<T*>(arr->data->arr) + arr->data->num
);
}
template <
typename K, typename V,
typename = std::enable_if_t<std::is_same_v<K, std::string> || std::is_same_v<K, intptr_t>>>
static cocos2d::CCDictionary* mapToCCDict(std::map<K, V> const& map) {
auto res = cocos2d::CCDictionary::create();
for (auto const& [key, value] : map)
res->setObject(value, key);
return res;
}
template <
typename K, typename V, typename C,
typename = std::enable_if_t<std::is_same_v<C, std::string> || std::is_same_v<C, intptr_t>>>
static cocos2d::CCDictionary* mapToCCDict(
std::map<K, V> const& map, std::function<C(K)> convFunc
) {
auto res = cocos2d::CCDictionary::create();
for (auto const& [key, value] : map)
res->setObject(value, convFunc(key));
return res;
}
// template<typename K, typename V,
// typename = std::enable_if_t<std::is_same_v<K, std::string> || std::is_same_v<K, intptr_t>> >
// static std::map<K, V> ccDictToMap(cocos2d::CCDictionary* dict) {
// auto res = std::map<K, V>();
// cocos2d::CCDictElement* element = nullptr;
// CCDICT_FOREACH(dict, element) {
// if constexpr (std::is_same_v<K, std::string>)
// res[element->getStrKey()] = element->getObject();
// if constexpr (std::is_same_v<K, intptr_t>)
// res[element->getIntKey()] = element->getObject();
// }
// return res;
// }
}
// std specializations
namespace std {
// enables using Ref as the key in unordered_map etc.
template<class T>
struct hash<geode::Ref<T>> {
size_t operator()(geode::Ref<T> const& ref) const {
return std::hash<T*>()(ref.data());
}
};
template <typename T>
struct iterator_traits<geode::cocos::CCArrayIterator<T>> {
using difference_type = ptrdiff_t;
@ -314,8 +743,8 @@ namespace std {
};
}
// more utils
namespace geode::cocos {
struct GEODE_DLL CCArrayInserter {
public:
CCArrayInserter(cocos2d::CCArray* p) : m_array(p) {}

View file

@ -1,57 +0,0 @@
#pragma once
#include <array>
#include <string_view>
using namespace std::string_view_literals;
namespace geode::utils {
static constexpr const std::string_view sv_null = "\0";
static constexpr const std::string_view sv_none = "";
static constexpr const std::string_view sv_path = "/";
// straight off
// https://stackoverflow.com/questions/38955940/how-to-concatenate-static-strings-at-compile-time
template <std::string_view const& Separator, std::string_view const&... Strs>
struct ConstStringJoin {
static constexpr auto impl() noexcept {
constexpr std::size_t len =
(Strs.size() + ... + 0) + (sizeof...(Strs) - 1) * Separator.size();
std::array<char, len + 1> arr {};
auto append = [len, i = 0, &arr](auto const& s) mutable {
for (auto c : s)
arr[i++] = c;
if (i < static_cast<int>(len - 1)) {
for (auto c : Separator)
arr[i++] = c;
}
};
(append(Strs), ...);
arr[len] = 0;
return arr;
}
static constexpr auto arr = impl();
static constexpr std::string_view value { arr.data(), arr.size() - 1 };
};
template <std::string_view const& Separator, std::string_view const&... Strs>
static constexpr auto const_join_sep = ConstStringJoin<Separator, Strs...>::value;
template <std::string_view const&... Strs>
static constexpr auto const_join = ConstStringJoin<sv_none, Strs...>::value;
template <std::string_view const&... Strs>
static constexpr auto const_join_path = ConstStringJoin<sv_path, Strs...>::value;
template <std::string_view const& Separator, std::string_view const&... Strs>
static constexpr char const* const_join_sep_c_str =
ConstStringJoin<Separator, Strs...>::value.data();
template <std::string_view const&... Strs>
static constexpr char const* const_join_c_str = ConstStringJoin<sv_none, Strs...>::value.data();
template <std::string_view const&... Strs>
static constexpr char const* const_join_path_c_str =
ConstStringJoin<sv_path, Strs...>::value.data();
}

View file

@ -1,84 +0,0 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <algorithm>
#include <string>
namespace geode::utils::container {
/**
* Check if a container contains an element by value.
* @param vec The vector to check.
* @param elem The element to find.
* @returns True if element is in `vec`, false if not.
*/
template <class C, class T>
[[deprecated("Use geode::utils::ranges::contains instead")]] bool contains(
C const& cont, T const& elem
) {
return std::find(cont.begin(), cont.end(), elem) != cont.end();
}
/**
* Check if a vector contains an element via a function.
* @param vec The vector to check.
* @param containFunc A function that returns bool if the
* element parameter is what is looked for.
* @returns True if an element matching `containFunc` is
* in `vec`, false if not.
*/
template <class C, class T>
[[deprecated("Use geode::utils::ranges::contains instead")]] bool contains(
C const& cont, std::function<bool(T)> containFunc
) {
for (auto const& item : cont) {
if (containFunc(item)) return true;
}
return false;
}
/**
* Turn a vector into a string. T must be either a string,
* or convertible via `std::to_string`.
* @param vec The vector to add to.
* @param sep Separator string.
* @returns Joined string.
*/
template <class C>
[[deprecated("Use geode::utils::ranges::join instead")]] std::string join(
C const& cont, std::string const& sep
) {
std::string res = "";
bool first = true;
for (auto p : cont) {
if (!first) {
res += sep;
}
else {
first = false;
}
if constexpr (std::is_same_v<decltype(p), std::string>) {
res += p;
}
else {
res += std::to_string(p);
}
}
return res;
}
/**
* Map a container of items type T to a new container of items
* type T2.
* @param vec The container to map.
* @param mapFunc Function that converts an element from T to T2.
* @returns Mapped container.
*/
template <class C, class C2, class T, class T2>
[[deprecated("Use geode::utils::ranges::map instead")]] C2 map(
C const& cont, std::function<T2(T)> mapFunc
) {
C2 res;
std::transform(cont.begin(), cont.end(), res.end(), mapFunc);
return res;
}
}

View file

@ -1,140 +0,0 @@
#pragma once
#include "general.hpp"
#include "json.hpp"
#include <cocos2d.h>
// support converting ccColor3B / ccColor4B to / from json
namespace cocos2d {
void GEODE_DLL to_json(nlohmann::json& json, cocos2d::ccColor3B const& color);
void GEODE_DLL from_json(nlohmann::json const& json, cocos2d::ccColor3B& color);
void GEODE_DLL to_json(nlohmann::json& json, cocos2d::ccColor4B const& color);
void GEODE_DLL from_json(nlohmann::json const& json, cocos2d::ccColor4B& color);
}
namespace geode::cocos {
inline void ccDrawColor4B(cocos2d::ccColor4B const& color) {
cocos2d::ccDrawColor4B(color.r, color.g, color.b, color.a);
}
inline cocos2d::ccColor4B invert4B(cocos2d::ccColor4B const& color) {
return { static_cast<GLubyte>(255 - color.r), static_cast<GLubyte>(255 - color.g),
static_cast<GLubyte>(255 - color.b), color.a };
}
inline cocos2d::ccColor3B invert3B(cocos2d::ccColor3B const& color) {
return { static_cast<GLubyte>(255 - color.r), static_cast<GLubyte>(255 - color.g),
static_cast<GLubyte>(255 - color.b) };
}
inline cocos2d::ccColor3B lighten3B(cocos2d::ccColor3B const& color, int amount) {
return {
static_cast<GLubyte>(utils::clamp(color.r + amount, 0, 255)),
static_cast<GLubyte>(utils::clamp(color.g + amount, 0, 255)),
static_cast<GLubyte>(utils::clamp(color.b + amount, 0, 255)),
};
}
inline cocos2d::ccColor3B darken3B(cocos2d::ccColor3B const& color, int amount) {
return lighten3B(color, -amount);
}
inline cocos2d::ccColor3B to3B(cocos2d::ccColor4B const& color) {
return { color.r, color.g, color.b };
}
inline cocos2d::ccColor4B to4B(cocos2d::ccColor3B const& color, GLubyte alpha = 255) {
return { color.r, color.g, color.b, alpha };
}
inline cocos2d::ccColor4F to4F(cocos2d::ccColor4B const& color) {
return { color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f };
}
constexpr cocos2d::ccColor3B cc3x(int hexValue) {
if (hexValue <= 0xf)
return cocos2d::ccColor3B { static_cast<GLubyte>(hexValue * 17),
static_cast<GLubyte>(hexValue * 17),
static_cast<GLubyte>(hexValue * 17) };
if (hexValue <= 0xff)
return cocos2d::ccColor3B { static_cast<GLubyte>(hexValue),
static_cast<GLubyte>(hexValue),
static_cast<GLubyte>(hexValue) };
if (hexValue <= 0xfff)
return cocos2d::ccColor3B { static_cast<GLubyte>((hexValue >> 8 & 0xf) * 17),
static_cast<GLubyte>((hexValue >> 4 & 0xf) * 17),
static_cast<GLubyte>((hexValue >> 0 & 0xf) * 17) };
else
return cocos2d::ccColor3B { static_cast<GLubyte>(hexValue >> 16 & 0xff),
static_cast<GLubyte>(hexValue >> 8 & 0xff),
static_cast<GLubyte>(hexValue >> 0 & 0xff) };
}
GEODE_DLL Result<cocos2d::ccColor3B> cc3bFromHexString(std::string const& hexValue);
GEODE_DLL Result<cocos2d::ccColor4B> cc4bFromHexString(std::string const& hexValue);
GEODE_DLL std::string cc3bToHexString(cocos2d::ccColor3B const& color);
GEODE_DLL std::string cc4bToHexString(cocos2d::ccColor4B const& color);
template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>>
static cocos2d::CCArray* vectorToCCArray(std::vector<T> const& vec) {
auto res = cocos2d::CCArray::createWithCapacity(vec.size());
for (auto const& item : vec)
res->addObject(item);
return res;
}
template <typename T, typename C, typename = std::enable_if_t<std::is_pointer_v<C>>>
static cocos2d::CCArray* vectorToCCArray(
std::vector<T> const& vec, std::function<C(T)> convFunc
) {
auto res = cocos2d::CCArray::createWithCapacity(vec.size());
for (auto const& item : vec)
res->addObject(convFunc(item));
return res;
}
template <typename T, typename = std::enable_if_t<std::is_pointer_v<T>>>
std::vector<T> ccArrayToVector(cocos2d::CCArray* arr) {
return std::vector<T>(
reinterpret_cast<T*>(arr->data->arr),
reinterpret_cast<T*>(arr->data->arr) + arr->data->num
);
}
template <
typename K, typename V,
typename = std::enable_if_t<std::is_same_v<K, std::string> || std::is_same_v<K, intptr_t>>>
static cocos2d::CCDictionary* mapToCCDict(std::map<K, V> const& map) {
auto res = cocos2d::CCDictionary::create();
for (auto const& [key, value] : map)
res->setObject(value, key);
return res;
}
template <
typename K, typename V, typename C,
typename = std::enable_if_t<std::is_same_v<C, std::string> || std::is_same_v<C, intptr_t>>>
static cocos2d::CCDictionary* mapToCCDict(
std::map<K, V> const& map, std::function<C(K)> convFunc
) {
auto res = cocos2d::CCDictionary::create();
for (auto const& [key, value] : map)
res->setObject(value, convFunc(key));
return res;
}
// template<typename K, typename V,
// typename = std::enable_if_t<std::is_same_v<K, std::string> || std::is_same_v<K, intptr_t>> >
// static std::map<K, V> ccDictToMap(cocos2d::CCDictionary* dict) {
// auto res = std::map<K, V>();
// cocos2d::CCDictElement* element = nullptr;
// CCDICT_FOREACH(dict, element) {
// if constexpr (std::is_same_v<K, std::string>)
// res[element->getStrKey()] = element->getObject();
// if constexpr (std::is_same_v<K, intptr_t>)
// res[element->getIntKey()] = element->getObject();
// }
// return res;
// }
}

View file

@ -1,8 +0,0 @@
#pragma once
#include "conststring.hpp"
#include "container.hpp"
#include "file.hpp"
#include "map.hpp"
#include "string.hpp"
#include "vector.hpp"

View file

@ -1,48 +1,21 @@
#pragma once
#include "Result.hpp"
#include "types.hpp"
#include "general.hpp"
#include <Geode/DefaultInclude.hpp>
#include <fs/filesystem.hpp>
#include <string>
#include <unordered_set>
namespace geode::utils::file {
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<std::string>
readString(std::string const& path);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<std::string>
readString(std::wstring const& path);
GEODE_DLL Result<std::string> readString(ghc::filesystem::path const& path);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<byte_array> readBinary(
std::string const& path
);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<byte_array> readBinary(
std::wstring const& path
);
GEODE_DLL Result<byte_array> readBinary(ghc::filesystem::path const& path);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<> writeString(
std::string const& path, std::string const& data
);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<> writeString(
std::wstring const& path, std::string const& data
);
GEODE_DLL Result<> writeString(ghc::filesystem::path const& path, std::string const& data);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<> writeBinary(
std::string const& path, byte_array const& data
);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<> writeBinary(
std::wstring const& path, byte_array const& data
);
GEODE_DLL Result<> writeBinary(ghc::filesystem::path const& path, byte_array const& data);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<> createDirectory(
std::string const& path
);
GEODE_DLL Result<> createDirectory(ghc::filesystem::path const& path);
[[deprecated("Use the ghc::filesystem::path version")]] GEODE_DLL Result<> createDirectoryAll(
std::string const& path
);
GEODE_DLL Result<> createDirectoryAll(ghc::filesystem::path const& path);
GEODE_DLL Result<std::vector<std::string>> listFiles(std::string const& path);
GEODE_DLL Result<std::vector<std::string>> listFilesRecursively(std::string const& path);
@ -54,4 +27,28 @@ namespace geode::utils::file {
* @returns Ok on success, Error on error
*/
GEODE_DLL Result<> unzipTo(ghc::filesystem::path const& from, ghc::filesystem::path const& to);
GEODE_DLL ghc::filesystem::path geodeRoot();
GEODE_DLL bool openFolder(ghc::filesystem::path const& path);
enum class PickMode {
OpenFile,
SaveFile,
OpenFolder,
};
struct FilePickOptions {
struct Filter {
// Name of the filter
std::string description;
// Extensions (*.txt, *.doc, *.mp3, etc.)
std::unordered_set<std::string> files;
};
ghc::filesystem::path defaultPath;
std::vector<Filter> filters;
};
GEODE_DLL Result<ghc::filesystem::path> pickFile(PickMode mode, FilePickOptions const& options);
GEODE_DLL Result<std::vector<ghc::filesystem::path>> pickFiles(FilePickOptions const& options);
}

View file

@ -7,79 +7,105 @@
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#undef snprintf
namespace geode::utils {
constexpr unsigned int hash(char const* str, int h = 0) {
return !str[h] ? 5381 : (hash(str, h + 1) * 33) ^ str[h];
}
constexpr unsigned int hash(wchar_t const* str, int h = 0) {
return !str[h] ? 5381 : (hash(str, h + 1) * 33) ^ str[h];
}
constexpr size_t operator"" _h(char const* txt, size_t) {
return geode::utils::hash(txt);
}
constexpr size_t operator"" _h(wchar_t const* txt, size_t) {
return geode::utils::hash(txt);
}
namespace geode {
using byte_array = std::vector<uint8_t>;
template <typename T>
constexpr const T& clamp(const T& value, const T& minValue, const T& maxValue) {
return value < minValue ? minValue : maxValue < value ? maxValue : value;
byte_array to_byte_array(T const& a) {
byte_array out;
out.resize(sizeof(T));
std::memcpy(out.data(), &a, sizeof(T));
return out;
}
// from https://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf
template <typename... Args>
std::string strfmt(std::string const& format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
if (size_s <= 0) {
throw std::runtime_error("Error during formatting.");
template <class T>
struct TypeIdentity {
using type = T;
};
template <class T>
using TypeIdentityType = typename TypeIdentity<T>::type;
namespace utils {
constexpr unsigned int hash(char const* str, int h = 0) {
return !str[h] ? 5381 : (hash(str, h + 1) * 33) ^ str[h];
}
auto size = static_cast<size_t>(size_s);
auto buf = std::make_unique<char[]>(size);
std::snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1);
}
/**
* Format a string
* @returns Pointer to char array. MAKE SURE TO CALL DELETE[]!
*/
template <typename... Args>
char const* cstrfmt(char const* fmt, Args... args) {
auto str = strfmt(fmt, args...);
char* ptr = new char[str.size() + 1];
strcpy_s(ptr, str.c_str());
return ptr;
}
template <typename T>
std::string intToHex(T i) {
std::stringstream stream;
stream << std::showbase << std::setbase(16) << (uint64_t)i;
return stream.str();
}
/**
* Turn a number into a string, with support for specifying precision
* (unlike std::to_string).
* @param num Number to convert to string
* @param precision Precision of the converted number
* @returns Number as string
*/
template <class Num>
std::string numToString(Num num, size_t precision = 0) {
std::stringstream ss;
if (precision) {
ss << std::fixed << std::setprecision(precision);
constexpr unsigned int hash(wchar_t const* str, int h = 0) {
return !str[h] ? 5381 : (hash(str, h + 1) * 33) ^ str[h];
}
ss << num;
return ss.str();
}
GEODE_DLL std::string timePointAsString(std::chrono::system_clock::time_point const& tp);
constexpr size_t operator"" _h(char const* txt, size_t) {
return geode::utils::hash(txt);
}
constexpr size_t operator"" _h(wchar_t const* txt, size_t) {
return geode::utils::hash(txt);
}
template <typename T>
constexpr const T& clamp(const T& value, const T& minValue, const T& maxValue) {
return value < minValue ? minValue : maxValue < value ? maxValue : value;
}
// from https://stackoverflow.com/questions/2342162/stdstring-formatting-like-sprintf
template <typename... Args>
std::string strfmt(std::string const& format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0'
if (size_s <= 0) {
throw std::runtime_error("Error during formatting.");
}
auto size = static_cast<size_t>(size_s);
auto buf = std::make_unique<char[]>(size);
std::snprintf(buf.get(), size, format.c_str(), args...);
return std::string(buf.get(), buf.get() + size - 1);
}
/**
* Format a string
* @returns Pointer to char array. MAKE SURE TO CALL DELETE[]!
*/
template <typename... Args>
char const* cstrfmt(char const* fmt, Args... args) {
auto str = strfmt(fmt, args...);
char* ptr = new char[str.size() + 1];
strcpy_s(ptr, str.c_str());
return ptr;
}
template <typename T>
std::string intToHex(T i) {
std::stringstream stream;
stream << std::showbase << std::setbase(16) << (uint64_t)i;
return stream.str();
}
/**
* Turn a number into a string, with support for specifying precision
* (unlike std::to_string).
* @param num Number to convert to string
* @param precision Precision of the converted number
* @returns Number as string
*/
template <class Num>
std::string numToString(Num num, size_t precision = 0) {
std::stringstream ss;
if (precision) {
ss << std::fixed << std::setprecision(precision);
}
ss << num;
return ss.str();
}
GEODE_DLL std::string timePointAsString(std::chrono::system_clock::time_point const& tp);
}
}
namespace geode::utils::clipboard {
GEODE_DLL bool write(std::string const& data);
GEODE_DLL std::string read();
}

View file

@ -1,169 +0,0 @@
#pragma once
#include <cocos2d.h>
namespace geode {
static 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) {
size.width *= mul;
size.height *= mul;
return size;
}
static 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) {
rect.origin *= mul;
rect.size *= mul;
return rect;
}
static cocos2d::CCRect operator*(cocos2d::CCRect const& rect, float mul) {
return {
rect.origin.x * mul,
rect.origin.y * mul,
rect.size.width * mul,
rect.size.height * mul,
};
}
static 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) {
size.width /= div;
size.height /= div;
return size;
}
static 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) {
pos.x += add.x;
pos.y += add.y;
return pos;
}
static 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) {
size.width += add.width;
size.height += add.height;
return size;
}
static 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) {
rect.size += add;
return rect;
}
static 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) {
pos.x -= add.x;
pos.y -= add.y;
return pos;
}
static 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) {
size.width -= add.width;
size.height -= add.height;
return size;
}
static 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) {
rect.size -= add;
return rect;
}
static 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) {
return { size.width - f, size.height - f };
}
static cocos2d::CCSize operator-(cocos2d::CCSize const& size) {
return { -size.width, -size.height };
}
static 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) {
return p1.x != p2.x || p1.y != p2.y;
}
static 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) {
return s1.width != s2.width || s1.height != s2.height;
}
static 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) {
return r1.origin != r2.origin || r1.size != r2.size;
}
static 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) {
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) {
return c1.r != c2.r || c1.g != c2.g || c1.b != c2.b;
}
}

View file

@ -1,45 +0,0 @@
#pragma once
#include "Result.hpp"
#include "fs/filesystem.hpp"
#include <Geode/DefaultInclude.hpp>
#include <functional>
#include <string>
#include <unordered_set>
#include <vector>
namespace geode::utils::clipboard {
GEODE_DLL bool write(std::string const& data);
GEODE_DLL std::string read();
}
namespace geode::utils::file {
GEODE_DLL ghc::filesystem::path geodeRoot();
GEODE_DLL bool openFolder(ghc::filesystem::path const& path);
enum class PickMode {
OpenFile,
SaveFile,
OpenFolder,
};
struct FilePickOptions {
struct Filter {
// Name of the filter
std::string description;
// Extensions (*.txt, *.doc, *.mp3, etc.)
std::unordered_set<std::string> files;
};
ghc::filesystem::path defaultPath;
std::vector<Filter> filters;
};
GEODE_DLL Result<ghc::filesystem::path> pickFile(PickMode mode, FilePickOptions const& options);
GEODE_DLL Result<std::vector<ghc::filesystem::path>> pickFiles(FilePickOptions const& options);
}
namespace geode::utils::web {
GEODE_DLL void openLinkInBrowser(std::string const& url);
}

View file

@ -1,23 +0,0 @@
#pragma once
#include <vector>
namespace geode {
using byte_array = std::vector<uint8_t>;
template <typename T>
byte_array to_byte_array(T const& a) {
byte_array out;
out.resize(sizeof(T));
std::memcpy(out.data(), &a, sizeof(T));
return out;
}
template <class T>
struct TypeIdentity {
using type = T;
};
template <class T>
using TypeIdentityType = typename TypeIdentity<T>::type;
}

View file

@ -1,282 +0,0 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
namespace geode::utils::vector {
/**
* Check if a vector contains an element by value.
* @param vec The vector to check.
* @param elem The element to find.
* @returns True if element is in `vec`, false if not.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::contains instead")]] bool contains(
std::vector<T> const& vec, T const& elem
) {
return std::find(vec.begin(), vec.end(), elem) != vec.end();
}
/**
* Get the index of an element in a vector by value.
* @param vec The vector to check.
* @param elem The element to get the index of.
* @returns Iterator to the index of element, or
* std::vector::end if the item is not in the vector.
*/
template <class T>
[[deprecated(
"Useless utility, if you want it added to geode::utils::ranges open an Issue on GitHub"
)]] typename std::vector<T>::const_iterator
indexOf(std::vector<T> const& vec, T const& elem) {
return std::find(vec.begin(), vec.end(), elem);
}
/**
* Check if a vector contains an element via a function.
* @param vec The vector to check.
* @param containFunc A function that returns bool if the
* element parameter is what is looked for.
* @returns True if an element matching `containFunc` is
* in `vec`, false if not.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::contains instead")]] bool contains(
std::vector<T> const& vec, std::function<bool(T)> containFunc
) {
for (auto const& item : vec) {
if (containFunc(item)) return true;
}
return false;
}
/**
* Add a vector to the end of another vector.
* @param vec The vector to add to.
* @param subVec The vector to add.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::push instead")]] void push(
std::vector<T>& vec, std::vector<T> const& subVec
) {
vec.insert(vec.begin(), subVec.begin(), subVec.end());
}
/**
* Turn a vector into a string. T must be either a string,
* or convertible via `std::to_string`.
* @param vec The vector to add to.
* @param sep Separator string.
* @returns Joined string.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::join instead")]] std::string join(
std::vector<T> const& vec, std::string const& sep
) {
std::string res = "";
for (auto p : vec) {
if constexpr (std::is_same_v<T, std::string>) {
res += p + sep;
}
else {
res += std::to_string(p) + sep;
}
}
res = res.substr(0, res.length() - sep.length());
return res;
}
/**
* Map a vector of items type T to a new vector of items
* type T2.
* @param vec The vector to map.
* @param mapFunc Function that converts an element from T to T2.
* @returns Mapped vector.
*/
template <class T, class T2>
[[deprecated("Use geode::utils::ranges::map instead")]] std::vector<T2> map(
std::vector<T> const& vec, std::function<T2(T)> mapFunc
) {
std::vector<T2> res;
std::transform(vec.begin(), vec.end(), res.end(), mapFunc);
return res;
}
/**
* Remove items from a vector that don't match the filter
* predicate.
* @param vec The vector to filter.
* @param filterFunc Predicate function that returns true
* if element should be kept in vector.
* @returns Filtered vector.
*/
template <class T>
[[deprecated(
"Useless utility, if you want it added to geode::utils::ranges open an Issue on GitHub"
)]] std::vector<T>&
filterIP(std::vector<T>& vec, std::function<bool(T)> filterFunc) {
std::vector<T> res;
for (auto m : vec) {
if (filterFunc(m)) {
res.push_back(m);
}
}
vec = res;
return vec;
}
/**
* Return a copy of the vector that has items not
* matching `filterFunc` removed.
* @param vec The vector to filter.
* @param filterFunc Predicate function that returns true
* if element should be kept in vector.
* @returns Filtered vector.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::filter instead")]] std::vector<T> filter(
std::vector<T> const& vec, std::function<bool(T)> filterFunc
) {
std::vector<T> res;
for (auto m : vec) {
if (filterFunc(m)) {
res.push_back(m);
}
}
return res;
}
/**
* See if an item in the vector matching the predicate
* `selectFunc` exists, and return it if it does.
* @param vec The vector to select from.
* @param selectFunc Predicate function to see if a
* given item is what is looked for.
* @returns Found item, or the default of T if it was
* not found. If T is pointer type and item was not
* found, the return type is nullptr.
*/
template <class T>
[[deprecated(
"Useless utility, if you want it added to geode::utils::ranges open an Issue on GitHub"
)]] T
select(std::vector<T> const& vec, std::function<bool(T)> selectFunc) {
for (auto const& v : vec) {
if (selectFunc(v)) {
return v;
}
}
if (std::is_pointer<T>::value) {
return nullptr;
}
return T();
}
/**
* Alias for `filter`.
* @param vec The vector to filter.
* @param selectFunc Predicate function that returns true
* if element should be kept in vector.
* @returns Filtered vector.
*/
template <class T>
[[deprecated(
"Useless utility, if you want it added to geode::utils::ranges open an Issue on GitHub"
)]] std::vector<T>
selectAll(std::vector<T> const& vec, std::function<bool(T)> selectFunc) {
return filter<T>(vec, selectFunc);
}
/**
* Remove elements from a vector by value.
* @param vec The vector to remove from.
* @param element Elements to remove.
* @returns Reference to vector.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::remove instead")]] std::vector<T>& erase(
std::vector<T>& vec, T const& element
) {
vec.erase(std::remove(vec.begin(), vec.end(), element), vec.end());
return vec;
}
/**
* Remove elements from a vector via a function.
* @param vec The vector to remove from.
* @param eraseFunc Predicate function to decide whether
* to remove an element or not.
* @returns Reference to vector.
*/
template <class T>
[[deprecated("Use geode::utils::ranges::remove instead")]] std::vector<T>& erase(
std::vector<T>& vec, std::function<bool(T)> eraseFunc
) {
vec.erase(std::remove_if(vec.begin(), vec.end(), eraseFunc), vec.end());
return vec;
}
/**
* Reduce vector of elements to single value.
* @param vec The vector to reduce.
* @param reduceFunc Function to handle the
* creation of the reduced value. First parameter
* is a reference to the accumulator and second
* is the current item. Modify the value in the
* accumulator, for example with R += T, to
* compute the reduced value.
* @example ```cpp
* std::vector<int> numbers = { 1, 3, 7, 8, };
* int total = reduce<int, int>(numbers, [](int& acc, int val) -> void {
* acc += val;
* }); // 19
* ```
* @returns Reduced value.
*/
template <class R, class T>
[[deprecated("Use geode::utils::ranges::reduce instead")]] R reduce(
std::vector<T> const& vec, std::function<void(R&, T)> reduceFunc
) {
R res = R();
for (auto const& item : vec) {
reduceFunc(res, item);
}
return res;
}
/**
* Insert an element in a vector before another
* element.
* @param vec Vector to insert into.
* @param item Element to insert.
* @param after Element to insert before.
*/
template <class T>
[[deprecated(
"Useless utility, if you want it added to geode::utils::ranges open an Issue on GitHub"
)]] void
insertBefore(std::vector<T>& vec, T const& item, T const& before) {
vec.insert(utils::vector::indexOf(vec, before), item);
}
/**
* Insert an element in a vector after another
* element.
* @param vec Vector to insert into.
* @param item Element to insert.
* @param after Element to insert after.
*/
template <class T>
[[deprecated(
"Useless utility, if you want it added to geode::utils::ranges open an Issue on GitHub"
)]] void
insertAfter(std::vector<T>& vec, T const& item, T const& after) {
vec.insert(utils::vector::indexOf(vec, after) + 1, item);
}
}

View file

@ -2,13 +2,15 @@
#include "../DefaultInclude.hpp"
#include "Result.hpp"
#include "json.hpp"
#include "types.hpp"
#include "../external/json/json.hpp"
#include "general.hpp"
#include <fs/filesystem.hpp>
#include <mutex>
namespace geode::utils::web {
GEODE_DLL void openLinkInBrowser(std::string const& url);
using FileProgressCallback = std::function<bool(double, double)>;
/**

View file

@ -1,8 +1,6 @@
#include <Geode/modify/Field.hpp>
#include <Geode/utils/Ref.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/modify/Field.hpp>
#include <Geode/utils/WackyGeodeMacros.hpp>
#include <Geode/modify/CCNode.hpp>
#include <cocos2d.h>
@ -133,7 +131,7 @@ void CCNode::updateLayout() {
if (auto layout = GeodeNodeMetadata::set(this)->m_layout.get()) {
// nodes with absolute position should never be rearranged
auto filtered = CCArray::create();
CCARRAY_FOREACH_B_TYPE(m_pChildren, child, CCNode) {
for (auto& child : CCArrayExt<CCNode>(m_pChildren)) {
if (child->getPositionHint() != PositionHint::Absolute) {
filtered->addObject(child);
}

View file

@ -1,7 +1,5 @@
#include <Geode/utils/WackyGeodeMacros.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/Ref.hpp>
#include "../ui/internal/info/ModInfoLayer.hpp"
#include "../ui/internal/list/ModListLayer.hpp"
#include <Geode/ui/BasedButtonSprite.hpp>

View file

@ -4,14 +4,13 @@
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/utils/JsonValidation.hpp>
#include <Geode/utils/fetch.hpp>
#include <Geode/utils/web.hpp>
#include <Geode/utils/file.hpp>
#include <Geode/utils/general.hpp>
#include <Geode/utils/json.hpp>
#include <Geode/external/json/json.hpp>
#include <Geode/utils/map.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/string.hpp>
#include <Geode/utils/vector.hpp>
#include <fmt/format.h>
#include <hash.hpp>
#include <thread>

View file

@ -1,6 +1,6 @@
#pragma once
#include <Geode/utils/fetch.hpp>
#include <Geode/utils/web.hpp>
#include <mutex>
#include <optional>
#include <unordered_set>

View file

@ -1,7 +1,7 @@
#pragma once
#include <Geode/DefaultInclude.hpp>
#include <Geode/utils/types.hpp>
#include <Geode/utils/general.hpp>
#include <fs/filesystem.hpp>
#include <functional>
#include <string>

View file

@ -5,7 +5,7 @@
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Log.hpp>
#include <Geode/utils/fetch.hpp>
#include <Geode/utils/web.hpp>
#include <Geode/utils/file.hpp>
#include <fmt/format.h>
#include <hash.hpp>

View file

@ -6,7 +6,7 @@
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Log.hpp>
#include <Geode/utils/Result.hpp>
#include <Geode/utils/json.hpp>
#include <Geode/external/json/json.hpp>
#include <mutex>
#include <optional>
#include <unordered_map>

View file

@ -1,11 +1,10 @@
#include <FileWatcher.hpp>
#include <Geode/utils/platform.hpp>
#ifdef GEODE_IS_IOS
#import <UIKit/UIKit.h>
#include <fcntl.h>
#include <iostream>
#import <UIKit/UIKit.h>
#include <fcntl.h>
#include <iostream>
// static constexpr const auto notifyAttributes = FILE_NOTIFY_CHANGE_LAST_WRITE |
// FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE;

View file

@ -1,5 +1,4 @@
#include <FileWatcher.hpp>
#include <Geode/utils/platform.hpp>
#ifdef GEODE_IS_MACOS

View file

@ -2,7 +2,7 @@
#ifdef GEODE_IS_MACOS
#include "../../../../filesystem/fs/filesystem.hpp"
#include <fs/filesystem.hpp>
#include <Foundation/Foundation.h>

View file

@ -1,5 +1,4 @@
#include <Geode/loader/Event.hpp>
#include <Geode/utils/vector.hpp>
USE_GEODE_NAMESPACE();

View file

@ -3,7 +3,6 @@
#include <Geode/loader/Mod.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/vector.hpp>
#include <vector>
// #include <hook/hook.hpp>
#include "InternalLoader.hpp"

View file

@ -2,11 +2,9 @@
#include <Geode/loader/Loader.hpp>
#include <Geode/loader/Log.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/utils/conststring.hpp>
#include <Geode/utils/file.hpp>
#include <Geode/utils/map.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/types.hpp>
#include <InternalLoader.hpp>
#include <InternalMod.hpp>
#include <about.hpp>

View file

@ -5,12 +5,10 @@
#include <Geode/loader/Mod.hpp>
#include <Geode/loader/Setting.hpp>
#include <Geode/utils/JsonValidation.hpp>
#include <Geode/utils/conststring.hpp>
#include <Geode/utils/file.hpp>
#include <Geode/utils/map.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/string.hpp>
#include <Geode/utils/vector.hpp>
#include <InternalMod.hpp>
#include <about.hpp>

View file

@ -3,7 +3,6 @@
#include <Geode/loader/Mod.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/vector.hpp>
#include <InternalLoader.hpp>
#include <lilac/include/geode/core/hook/hook.hpp>
#include <vector>

View file

@ -1,4 +1,3 @@
#include <Geode/utils/platform.hpp>
#ifdef GEODE_IS_IOS

View file

@ -1,5 +1,4 @@
#include <Geode/c++stl/gdstdlib.hpp>
#include <Geode/utils/platform.hpp>
#ifdef GEODE_IS_MACOS

View file

@ -18,7 +18,6 @@
#include <Geode/ui/MDPopup.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/vector.hpp>
#include <InternalLoader.hpp>
// TODO: die

View file

@ -4,7 +4,6 @@
#include <Geode/binding/CCTextInputNode.hpp>
#include <Geode/binding/ColorChannelSprite.hpp>
#include <Geode/binding/Slider.hpp>
#include <Geode/utils/platform.hpp>
// BoolSettingNode

View file

@ -11,8 +11,6 @@
#include <Geode/ui/InputNode.hpp>
#include <Geode/ui/Popup.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/convert.hpp>
#include <Geode/utils/operators.hpp>
#include <Geode/utils/string.hpp>
USE_GEODE_NAMESPACE();

View file

@ -5,7 +5,6 @@
#include <Geode/loader/Setting.hpp>
#include <Geode/ui/ScrollLayer.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/convert.hpp>
bool ModSettingsPopup::setup(Mod* mod) {
m_noElasticity = true;

View file

@ -2,7 +2,7 @@
#include <Geode/loader/SettingNode.hpp>
#include <Geode/ui/Popup.hpp>
#include <Geode/utils/Ref.hpp>
#include <Geode/utils/cocos.hpp>
USE_GEODE_NAMESPACE();

View file

@ -3,7 +3,7 @@
#include <Geode/binding/Slider.hpp>
#include <Geode/binding/SliderThumb.hpp>
#include <Geode/ui/ColorPickPopup.hpp>
#include <Geode/utils/operators.hpp>
#include <Geode/utils/cocos.hpp>
USE_GEODE_NAMESPACE();

View file

@ -3,9 +3,7 @@
#include <Geode/ui/MDTextArea.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/convert.hpp>
#include <Geode/utils/fetch.hpp>
#include <Geode/utils/platform.hpp>
#include <Geode/utils/web.hpp>
#include <Geode/utils/ranges.hpp>
#include <Geode/utils/string.hpp>
#include <md4c.h>

View file

@ -3,7 +3,6 @@
#include <Geode/ui/Notification.hpp>
#include <Geode/ui/TextRenderer.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/container.hpp>
#include <Geode/utils/ranges.hpp>
USE_GEODE_NAMESPACE();

View file

@ -1,6 +1,5 @@
#include <Geode/ui/Scrollbar.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/operators.hpp>
// TODO: die
#undef min

View file

@ -1,7 +1,6 @@
#include <Geode/ui/TextRenderer.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/operators.hpp>
#include <Geode/utils/string.hpp>
#undef max
#undef min

View file

@ -1,10 +1,245 @@
#include <Geode/utils/cocos.hpp>
#include <Geode/utils/operators.hpp>
#include <Geode/utils/WackyGeodeMacros.hpp>
#include <Geode/modify/LoadingLayer.hpp>
USE_GEODE_NAMESPACE();
void cocos2d::to_json(nlohmann::json& json, ccColor3B const& color) {
json = nlohmann::json {
{ "r", color.r },
{ "g", color.g },
{ "b", color.b },
};
}
void cocos2d::from_json(nlohmann::json const& json, ccColor3B& color) {
// array
if (json.is_array()) {
if (json.size() == 3) {
json.at(0).get_to(color.r);
json.at(1).get_to(color.g);
json.at(2).get_to(color.b);
}
else {
throw nlohmann::json::type_error::create(
0, "Expected color array to have 3 items", json
);
}
}
// object
else if (json.is_object()) {
json.at("r").get_to(color.r);
json.at("g").get_to(color.g);
json.at("b").get_to(color.b);
}
// hex string
else if (json.is_string()) {
std::string str = json;
if (str[0] == '#') {
str.erase(str.begin());
}
if (str.size() > 6) {
throw nlohmann::json::type_error::create(0, "Hex string for color too long", json);
}
auto c = cc3bFromHexString(str);
if (!c) {
throw nlohmann::json::type_error::create(
0, "Invalid color hex string: " + c.unwrapErr(), json
);
}
color = c.unwrap();
}
// bad
else {
throw nlohmann::json::type_error::create(
0, "Expected color to be array, object or hex string", json
);
}
}
void cocos2d::to_json(nlohmann::json& json, ccColor4B const& color) {
json = nlohmann::json {
{ "r", color.r },
{ "g", color.g },
{ "b", color.b },
{ "a", color.a },
};
}
void cocos2d::from_json(nlohmann::json const& json, ccColor4B& color) {
// array
if (json.is_array()) {
if (json.size() == 4) {
json.at(0).get_to(color.r);
json.at(1).get_to(color.g);
json.at(2).get_to(color.b);
json.at(3).get_to(color.a);
}
else {
throw nlohmann::json::type_error::create(
0, "Expected color array to have 4 items", json
);
}
}
// object
else if (json.is_object()) {
json.at("r").get_to(color.r);
json.at("g").get_to(color.g);
json.at("b").get_to(color.b);
json.at("a").get_to(color.a);
}
// hex string
else if (json.is_string()) {
std::string str = json;
if (str[0] == '#') {
str.erase(str.begin());
}
if (str.size() > 8) {
throw nlohmann::json::type_error::create(0, "Hex string for color too long", json);
}
auto c = cc4bFromHexString(str);
if (!c) {
throw nlohmann::json::type_error::create(
0, "Invalid color hex string: " + c.unwrapErr(), json
);
}
color = c.unwrap();
}
// bad
else {
throw nlohmann::json::type_error::create(
0, "Expected color to be array, object or hex string", json
);
}
}
Result<ccColor3B> geode::cocos::cc3bFromHexString(std::string const& hexValue) {
if (hexValue.empty()) {
return Ok(ccc3(255, 255, 255));
}
if (hexValue.size() > 6) {
return Err("Hex value too large");
}
int numValue;
try {
numValue = std::stoi(hexValue, 0, 16);
}
catch (...) {
return Err("Invalid hex value");
}
switch (hexValue.size()) {
case 6: {
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
auto g = static_cast<uint8_t>((numValue & 0x00FF00) >> 8);
auto b = static_cast<uint8_t>((numValue & 0x0000FF));
return Ok(ccc3(r, g, b));
} break;
case 3: {
auto r = static_cast<uint8_t>(((numValue & 0xF00) >> 8) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F0) >> 4) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F)) * 17);
return Ok(ccc3(r, g, b));
} break;
case 2: {
auto num = static_cast<uint8_t>(numValue);
return Ok(ccc3(num, num, num));
} break;
case 1: {
auto num = static_cast<uint8_t>(numValue) * 17;
return Ok(ccc3(num, num, num));
} break;
default: return Err("Invalid hex size, expected 1, 2, 3, or 6");
}
}
Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue) {
if (hexValue.empty()) {
return Ok(ccc4(255, 255, 255, 255));
}
if (hexValue.size() > 8) {
return Err("Hex value too large");
}
int numValue;
try {
numValue = std::stoi(hexValue, 0, 16);
}
catch (...) {
return Err("Invalid hex value");
}
switch (hexValue.size()) {
case 8: {
auto r = static_cast<uint8_t>((numValue & 0xFF000000) >> 24);
auto g = static_cast<uint8_t>((numValue & 0x00FF0000) >> 16);
auto b = static_cast<uint8_t>((numValue & 0x0000FF00) >> 8);
auto a = static_cast<uint8_t>((numValue & 0x000000FF));
return Ok(ccc4(r, g, b, a));
} break;
case 6: {
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
auto g = static_cast<uint8_t>((numValue & 0x00FF00) >> 8);
auto b = static_cast<uint8_t>((numValue & 0x0000FF));
return Ok(ccc4(r, g, b, 255));
} break;
case 4: {
auto r = static_cast<uint8_t>(((numValue & 0xF000) >> 12) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F00) >> 8) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F0) >> 4) * 17);
auto a = static_cast<uint8_t>(((numValue & 0x000F)) * 17);
return Ok(ccc4(r, g, b, a));
} break;
case 3: {
auto r = static_cast<uint8_t>(((numValue & 0xF00) >> 8) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F0) >> 4) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F)) * 17);
return Ok(ccc4(r, g, b, 255));
} break;
case 2: {
auto num = static_cast<uint8_t>(numValue);
return Ok(ccc4(num, num, num, 255));
} break;
case 1: {
auto num = static_cast<uint8_t>(numValue) * 17;
return Ok(ccc4(num, num, num, 255));
} break;
default: return Err("Invalid hex size, expected 1, 2, 3, 4, 6, or 8");
}
}
std::string geode::cocos::cc3bToHexString(ccColor3B const& color) {
static constexpr auto digits = "0123456789ABCDEF";
std::string output;
output += digits[color.r >> 4 & 0xF];
output += digits[color.r & 0xF];
output += digits[color.g >> 4 & 0xF];
output += digits[color.g & 0xF];
output += digits[color.b >> 4 & 0xF];
output += digits[color.b & 0xF];
return output;
}
std::string geode::cocos::cc4bToHexString(ccColor4B const& color) {
static constexpr auto digits = "0123456789ABCDEF";
std::string output;
output += digits[color.r >> 4 & 0xF];
output += digits[color.r & 0xF];
output += digits[color.g >> 4 & 0xF];
output += digits[color.g & 0xF];
output += digits[color.b >> 4 & 0xF];
output += digits[color.b & 0xF];
output += digits[color.a >> 4 & 0xF];
output += digits[color.a & 0xF];
return output;
}
CCRect geode::cocos::calculateNodeCoverage(std::vector<CCNode*> const& nodes) {
CCRect coverage;
for (auto child : nodes) {

View file

@ -1,240 +0,0 @@
#include <Geode/utils/convert.hpp>
USE_GEODE_NAMESPACE();
void cocos2d::to_json(nlohmann::json& json, ccColor3B const& color) {
json = nlohmann::json {
{ "r", color.r },
{ "g", color.g },
{ "b", color.b },
};
}
void cocos2d::from_json(nlohmann::json const& json, ccColor3B& color) {
// array
if (json.is_array()) {
if (json.size() == 3) {
json.at(0).get_to(color.r);
json.at(1).get_to(color.g);
json.at(2).get_to(color.b);
}
else {
throw nlohmann::json::type_error::create(
0, "Expected color array to have 3 items", json
);
}
}
// object
else if (json.is_object()) {
json.at("r").get_to(color.r);
json.at("g").get_to(color.g);
json.at("b").get_to(color.b);
}
// hex string
else if (json.is_string()) {
std::string str = json;
if (str[0] == '#') {
str.erase(str.begin());
}
if (str.size() > 6) {
throw nlohmann::json::type_error::create(0, "Hex string for color too long", json);
}
auto c = cc3bFromHexString(str);
if (!c) {
throw nlohmann::json::type_error::create(
0, "Invalid color hex string: " + c.unwrapErr(), json
);
}
color = c.unwrap();
}
// bad
else {
throw nlohmann::json::type_error::create(
0, "Expected color to be array, object or hex string", json
);
}
}
void cocos2d::to_json(nlohmann::json& json, ccColor4B const& color) {
json = nlohmann::json {
{ "r", color.r },
{ "g", color.g },
{ "b", color.b },
{ "a", color.a },
};
}
void cocos2d::from_json(nlohmann::json const& json, ccColor4B& color) {
// array
if (json.is_array()) {
if (json.size() == 4) {
json.at(0).get_to(color.r);
json.at(1).get_to(color.g);
json.at(2).get_to(color.b);
json.at(3).get_to(color.a);
}
else {
throw nlohmann::json::type_error::create(
0, "Expected color array to have 4 items", json
);
}
}
// object
else if (json.is_object()) {
json.at("r").get_to(color.r);
json.at("g").get_to(color.g);
json.at("b").get_to(color.b);
json.at("a").get_to(color.a);
}
// hex string
else if (json.is_string()) {
std::string str = json;
if (str[0] == '#') {
str.erase(str.begin());
}
if (str.size() > 8) {
throw nlohmann::json::type_error::create(0, "Hex string for color too long", json);
}
auto c = cc4bFromHexString(str);
if (!c) {
throw nlohmann::json::type_error::create(
0, "Invalid color hex string: " + c.unwrapErr(), json
);
}
color = c.unwrap();
}
// bad
else {
throw nlohmann::json::type_error::create(
0, "Expected color to be array, object or hex string", json
);
}
}
Result<ccColor3B> geode::cocos::cc3bFromHexString(std::string const& hexValue) {
if (hexValue.empty()) {
return Ok(ccc3(255, 255, 255));
}
if (hexValue.size() > 6) {
return Err("Hex value too large");
}
int numValue;
try {
numValue = std::stoi(hexValue, 0, 16);
}
catch (...) {
return Err("Invalid hex value");
}
switch (hexValue.size()) {
case 6: {
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
auto g = static_cast<uint8_t>((numValue & 0x00FF00) >> 8);
auto b = static_cast<uint8_t>((numValue & 0x0000FF));
return Ok(ccc3(r, g, b));
} break;
case 3: {
auto r = static_cast<uint8_t>(((numValue & 0xF00) >> 8) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F0) >> 4) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F)) * 17);
return Ok(ccc3(r, g, b));
} break;
case 2: {
auto num = static_cast<uint8_t>(numValue);
return Ok(ccc3(num, num, num));
} break;
case 1: {
auto num = static_cast<uint8_t>(numValue) * 17;
return Ok(ccc3(num, num, num));
} break;
default: return Err("Invalid hex size, expected 1, 2, 3, or 6");
}
}
Result<ccColor4B> geode::cocos::cc4bFromHexString(std::string const& hexValue) {
if (hexValue.empty()) {
return Ok(ccc4(255, 255, 255, 255));
}
if (hexValue.size() > 8) {
return Err("Hex value too large");
}
int numValue;
try {
numValue = std::stoi(hexValue, 0, 16);
}
catch (...) {
return Err("Invalid hex value");
}
switch (hexValue.size()) {
case 8: {
auto r = static_cast<uint8_t>((numValue & 0xFF000000) >> 24);
auto g = static_cast<uint8_t>((numValue & 0x00FF0000) >> 16);
auto b = static_cast<uint8_t>((numValue & 0x0000FF00) >> 8);
auto a = static_cast<uint8_t>((numValue & 0x000000FF));
return Ok(ccc4(r, g, b, a));
} break;
case 6: {
auto r = static_cast<uint8_t>((numValue & 0xFF0000) >> 16);
auto g = static_cast<uint8_t>((numValue & 0x00FF00) >> 8);
auto b = static_cast<uint8_t>((numValue & 0x0000FF));
return Ok(ccc4(r, g, b, 255));
} break;
case 4: {
auto r = static_cast<uint8_t>(((numValue & 0xF000) >> 12) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F00) >> 8) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F0) >> 4) * 17);
auto a = static_cast<uint8_t>(((numValue & 0x000F)) * 17);
return Ok(ccc4(r, g, b, a));
} break;
case 3: {
auto r = static_cast<uint8_t>(((numValue & 0xF00) >> 8) * 17);
auto g = static_cast<uint8_t>(((numValue & 0x0F0) >> 4) * 17);
auto b = static_cast<uint8_t>(((numValue & 0x00F)) * 17);
return Ok(ccc4(r, g, b, 255));
} break;
case 2: {
auto num = static_cast<uint8_t>(numValue);
return Ok(ccc4(num, num, num, 255));
} break;
case 1: {
auto num = static_cast<uint8_t>(numValue) * 17;
return Ok(ccc4(num, num, num, 255));
} break;
default: return Err("Invalid hex size, expected 1, 2, 3, 4, 6, or 8");
}
}
std::string geode::cocos::cc3bToHexString(ccColor3B const& color) {
static constexpr auto digits = "0123456789ABCDEF";
std::string output;
output += digits[color.r >> 4 & 0xF];
output += digits[color.r & 0xF];
output += digits[color.g >> 4 & 0xF];
output += digits[color.g & 0xF];
output += digits[color.b >> 4 & 0xF];
output += digits[color.b & 0xF];
return output;
}
std::string geode::cocos::cc4bToHexString(ccColor4B const& color) {
static constexpr auto digits = "0123456789ABCDEF";
std::string output;
output += digits[color.r >> 4 & 0xF];
output += digits[color.r & 0xF];
output += digits[color.g >> 4 & 0xF];
output += digits[color.g & 0xF];
output += digits[color.b >> 4 & 0xF];
output += digits[color.b & 0xF];
output += digits[color.a >> 4 & 0xF];
output += digits[color.a & 0xF];
return output;
}

View file

@ -1,8 +1,7 @@
#include <Geode/cocos/platform/IncludeCurl.h>
#include <Geode/loader/Loader.hpp>
#include <Geode/utils/casts.hpp>
#include <Geode/utils/fetch.hpp>
#include <Geode/utils/vector.hpp>
#include <Geode/utils/web.hpp>
#include <thread>
USE_GEODE_NAMESPACE();

View file

@ -5,36 +5,6 @@
USE_GEODE_NAMESPACE();
Result<std::string> utils::file::readString(std::string const& path) {
std::ifstream in(path, std::ios::in | std::ios::binary);
if (in) {
std::string contents;
in.seekg(0, std::ios::end);
contents.resize((const size_t)in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
in.close();
return Ok(contents);
}
return Err("Unable to open file");
}
#if _WIN32
Result<std::string> utils::file::readString(std::wstring const& path) {
std::ifstream in(path, std::ios::in | std::ios::binary);
if (in) {
std::string contents;
in.seekg(0, std::ios::end);
contents.resize((const size_t)in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
in.close();
return Ok(contents);
}
return Err("Unable to open file");
}
#endif
Result<std::string> utils::file::readString(ghc::filesystem::path const& path) {
#if _WIN32
std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
@ -53,24 +23,6 @@ Result<std::string> utils::file::readString(ghc::filesystem::path const& path) {
return Err("Unable to open file");
}
Result<byte_array> utils::file::readBinary(std::string const& path) {
std::ifstream in(path, std::ios::in | std::ios::binary);
if (in) {
return Ok(byte_array(std::istreambuf_iterator<char>(in), {}));
}
return Err("Unable to open file");
}
#if _WIN32
Result<byte_array> utils::file::readBinary(std::wstring const& path) {
std::ifstream in(path, std::ios::in | std::ios::binary);
if (in) {
return Ok(byte_array(std::istreambuf_iterator<char>(in), {}));
}
return Err("Unable to open file");
}
#endif
Result<byte_array> utils::file::readBinary(ghc::filesystem::path const& path) {
#if _WIN32
std::ifstream in(path.wstring(), std::ios::in | std::ios::binary);
@ -83,34 +35,6 @@ Result<byte_array> utils::file::readBinary(ghc::filesystem::path const& path) {
return Err("Unable to open file");
}
Result<> utils::file::writeString(std::string const& path, std::string const& data) {
std::ofstream file;
file.open(path);
if (file.is_open()) {
file << data;
file.close();
return Ok();
}
file.close();
return Err("Unable to open file");
}
#if _WIN32
Result<> utils::file::writeString(std::wstring const& path, std::string const& data) {
std::ofstream file;
file.open(path);
if (file.is_open()) {
file << data;
file.close();
return Ok();
}
file.close();
return Err("Unable to open file");
}
#endif
Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string const& data) {
std::ofstream file;
#if _WIN32
@ -128,34 +52,6 @@ Result<> utils::file::writeString(ghc::filesystem::path const& path, std::string
return Err("Unable to open file");
}
Result<> utils::file::writeBinary(std::string const& path, byte_array const& data) {
std::ofstream file;
file.open(path, std::ios::out | std::ios::binary);
if (file.is_open()) {
file.write(reinterpret_cast<char const*>(data.data()), data.size());
file.close();
return Ok();
}
file.close();
return Err("Unable to open file");
}
#if _WIN32
Result<> utils::file::writeBinary(std::wstring const& path, byte_array const& data) {
std::ofstream file;
file.open(path, std::ios::out | std::ios::binary);
if (file.is_open()) {
file.write(reinterpret_cast<char const*>(data.data()), data.size());
file.close();
return Ok();
}
file.close();
return Err("Unable to open file");
}
#endif
Result<> utils::file::writeBinary(ghc::filesystem::path const& path, byte_array const& data) {
std::ofstream file;
#if _WIN32
@ -173,17 +69,6 @@ Result<> utils::file::writeBinary(ghc::filesystem::path const& path, byte_array
return Err("Unable to open file");
}
Result<> utils::file::createDirectory(std::string const& path) {
try {
if (ghc::filesystem::create_directory(path)) {
return Ok();
}
}
catch (...) {
}
return Err("Unable to create directory");
}
Result<> utils::file::createDirectory(ghc::filesystem::path const& path) {
try {
if (ghc::filesystem::create_directory(path)) {
@ -195,17 +80,6 @@ Result<> utils::file::createDirectory(ghc::filesystem::path const& path) {
return Err("Unable to create directory");
}
Result<> utils::file::createDirectoryAll(std::string const& path) {
try {
if (ghc::filesystem::create_directories(path)) {
return Ok();
}
}
catch (...) {
}
return Err("Unable to create directories");
}
Result<> utils::file::createDirectoryAll(ghc::filesystem::path const& path) {
try {
if (ghc::filesystem::create_directories(path)) {

View file

@ -1,4 +1,3 @@
#include <Geode/utils/platform.hpp>
#ifdef GEODE_IS_IOS

View file

@ -1,4 +1,3 @@
#include <Geode/utils/platform.hpp>
#ifdef GEODE_IS_MACOS

View file

@ -1,4 +1,4 @@
#include <Geode/utils/ext.hpp>
#include <Geode/utils/string.hpp>
#include <algorithm>
USE_GEODE_NAMESPACE();

View file

@ -3,7 +3,6 @@
#endif
#include <Geode/utils/VersionInfo.hpp>
#include <Geode/utils/ext.hpp>
#include <Geode/utils/general.hpp>
USE_GEODE_NAMESPACE();

View file

@ -8,7 +8,7 @@
* Modified to be modern Geode-fitting C++
*/
#include <Geode/utils/platform.hpp>
#include <Geode/DefaultInclude.hpp>
#ifdef GEODE_IS_WINDOWS

View file

@ -1,17 +1,17 @@
#include <Geode/utils/platform.hpp>
#include <fs/filesystem.hpp>
#ifdef GEODE_IS_WINDOWS
USE_GEODE_NAMESPACE();
#include "nfdwin.hpp"
#include "nfdwin.hpp"
#include <Windows.h>
#include <iostream>
#include <shlwapi.h>
#include <shobjidl.h>
#include <sstream>
#include <Windows.h>
#include <iostream>
#include <shlwapi.h>
#include <shobjidl.h>
#include <sstream>
#include <Geode/utils/web.hpp>
bool utils::clipboard::write(std::string const& data) {
if (!OpenClipboard(nullptr)) return false;