Compare commits

..

1 commit

Author SHA1 Message Date
TheSillyDoggo
50be1dacc3
Merge bd6bfb661f into 07d92a34ad 2024-11-19 12:03:00 +01:00
9 changed files with 33 additions and 47 deletions

View file

@ -1,10 +1,5 @@
# Geode Changelog # Geode Changelog
## v4.0.0
* Make chosen display type in mod list be saved between startups (07d92a3)
* Fix `Task::all` not returning results in order (227adb0)
* Fix bugs with changing display type (555ebe3, f90461f)
## v4.0.0-beta.2 ## v4.0.0-beta.2
* Add grid view to mod list (7bcf50d, 1ff24f0) * Add grid view to mod list (7bcf50d, 1ff24f0)
* Add safe mode tip to windows crashlog window (38f3385) * Add safe mode tip to windows crashlog window (38f3385)

View file

@ -1 +1 @@
4.0.0 4.0.0-beta.2

View file

@ -114,6 +114,7 @@
namespace geode { namespace geode {
class PlatformID { class PlatformID {
public: public:
// todo in v4: make these flags and add archless Mac and Android as well as Desktop and Mobile and remove Linux
enum { enum {
Unknown = 0b000000, Unknown = 0b000000,
Windows = 0b000001, Windows = 0b000001,
@ -183,11 +184,11 @@ namespace geode {
/** /**
* Returns the list of platforms covered by this string name. For * Returns the list of platforms covered by this string name. For
* example, "android" would return both Android32 and Android64 * example, "android" would return both Android32 and Android64
* todo in v5: deprecate this as the flagged version deals with this * todo in v4: deprecate this as the flagged version deals with this
*/ */
static GEODE_DLL std::vector<PlatformID> getCovered(std::string_view str); static GEODE_DLL std::vector<PlatformID> getCovered(std::string_view str);
// todo in v5: this does not need to be constexpr in the header. dllexport it // todo in v4: this does not need to be constexpr in the header. dllexport it
static constexpr char const* toString(Type lp) { static constexpr char const* toString(Type lp) {
switch (lp) { switch (lp) {
case Unknown: return "Unknown"; case Unknown: return "Unknown";
@ -202,7 +203,7 @@ namespace geode {
return "Undefined"; return "Undefined";
} }
// todo in v5: this does not need to be constexpr in the header. dllexport it // todo in v4: this does not need to be constexpr in the header. dllexport it
static constexpr char const* toShortString(Type lp, bool ignoreArch = false) { static constexpr char const* toShortString(Type lp, bool ignoreArch = false) {
switch (lp) { switch (lp) {
case Unknown: return "unknown"; case Unknown: return "unknown";

View file

@ -13,6 +13,12 @@ namespace geode {
virtual void updateColor(cocos2d::ccColor4B const& color) {} virtual void updateColor(cocos2d::ccColor4B const& color) {}
}; };
// todo in v4: maybe use events over the delegate?
// thing with events is that if you just filter via ColorPickPopup* it
// won't work unless you automatically detach the filter when closing the
// popup (otherwise opening another popup really quickly will just be
// allocated into the same memory and now the old filter is catching the
// new popup too)
class GEODE_DLL ColorPickPopup : class GEODE_DLL ColorPickPopup :
public Popup<cocos2d::ccColor4B const&, bool>, public Popup<cocos2d::ccColor4B const&, bool>,
public cocos2d::extension::ColorPickerDelegate, public cocos2d::extension::ColorPickerDelegate,

View file

@ -539,18 +539,12 @@ namespace geode {
} }
); );
// Make sure the taskResults vector is large enough to fit all the
// results. By default, any cancelled Task becomes nullptr.
// Order of results must be preserved so when a Task finishes, it
// replaces the nullptr in the results vector at its place
static_cast<Waiting*>(task.m_handle->m_extraData->ptr)->taskResults.resize(tasks.size());
// Store the task count in case some tasks finish immediately during the loop // Store the task count in case some tasks finish immediately during the loop
static_cast<Waiting*>(task.m_handle->m_extraData->ptr)->taskCount = tasks.size(); static_cast<Waiting*>(task.m_handle->m_extraData->ptr)->taskCount = tasks.size();
// Make sure to only give a weak pointer to avoid circular references! // Make sure to only give a weak pointer to avoid circular references!
// (Tasks should NEVER own themselves!!) // (Tasks should NEVER own themselves!!)
auto markAsDone = [handle = std::weak_ptr(task.m_handle)](size_t index, T* result) { auto markAsDone = [handle = std::weak_ptr(task.m_handle)](T* result) {
auto lock = handle.lock(); auto lock = handle.lock();
// If this task handle has expired, consider the task cancelled // If this task handle has expired, consider the task cancelled
@ -562,21 +556,13 @@ namespace geode {
// Get the waiting handle from the task handle // Get the waiting handle from the task handle
auto waiting = static_cast<Waiting*>(lock->m_extraData->ptr); auto waiting = static_cast<Waiting*>(lock->m_extraData->ptr);
// Mark the task as done by decrementing amount of tasks left
// (making sure not to underflow, even though that should 100%
// be impossible and if that happened something has gone
// extremely catastrophically wrong)
if (waiting->taskCount > 0) {
waiting->taskCount -= 1;
}
// SAFETY: The lifetime of result pointer is the same as the task that // SAFETY: The lifetime of result pointer is the same as the task that
// produced that pointer, so as long as we have an owning reference to // produced that pointer, so as long as we have an owning reference to
// the tasks through `taskListeners` we can be sure `result` is valid // the tasks through `taskListeners` we can be sure `result` is valid
waiting->taskResults[index] = result; waiting->taskResults.push_back(result);
// If all tasks are done, finish // If all tasks are done, finish
if (waiting->taskCount == 0) { if (waiting->taskResults.size() >= waiting->taskCount) {
// SAFETY: The task results' lifetimes are tied to the tasks // SAFETY: The task results' lifetimes are tied to the tasks
// which could have their only owner be `waiting->taskListeners`, // which could have their only owner be `waiting->taskListeners`,
// but since Waiting is owned by the returned AllTask it should // but since Waiting is owned by the returned AllTask it should
@ -586,17 +572,15 @@ namespace geode {
}; };
// Iterate the tasks & start listening to them using // Iterate the tasks & start listening to them using
size_t index = 0;
for (auto& taskToWait : tasks) { for (auto& taskToWait : tasks) {
static_cast<Waiting*>(task.m_handle->m_extraData->ptr)->taskListeners.emplace_back(taskToWait.map( static_cast<Waiting*>(task.m_handle->m_extraData->ptr)->taskListeners.emplace_back(taskToWait.map(
[index, markAsDone](auto* result) { [markAsDone](auto* result) {
markAsDone(index, result); markAsDone(result);
return std::monostate(); return std::monostate();
}, },
[](auto*) { return std::monostate(); }, [](auto*) { return std::monostate(); },
[index, markAsDone]() { markAsDone(index, nullptr); } [markAsDone]() { markAsDone(nullptr); }
)); ));
index += 1;
} }
return task; return task;
} }

View file

@ -172,6 +172,16 @@ ModSettingsManager::ModSettingsManager(ModMetadata const& metadata)
auto root = checkJson(json, "setting"); auto root = checkJson(json, "setting");
root.needs("type").into(setting.type); root.needs("type").into(setting.type);
if (root) { if (root) {
if (setting.type == "custom") {
log::warn(
"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 "
"https://docs.geode-sdk.org/mods/settings/#custom-settings",
key, m_impl->modID
);
}
m_impl->settings.emplace(key, setting); m_impl->settings.emplace(key, setting);
} }
else { else {

View file

@ -15,9 +15,9 @@ static size_t getDisplayPageSize(ModListSource* src, ModListDisplay display) {
$execute { $execute {
listenForSettingChanges("infinite-local-mods-list", [](bool value) { listenForSettingChanges("infinite-local-mods-list", [](bool value) {
InstalledModListSource::get(InstalledModListType::All)->clearCache(); InstalledModListSource::get(InstalledModListType::All)->reset();
InstalledModListSource::get(InstalledModListType::OnlyErrors)->clearCache(); InstalledModListSource::get(InstalledModListType::OnlyErrors)->reset();
InstalledModListSource::get(InstalledModListType::OnlyOutdated)->clearCache(); InstalledModListSource::get(InstalledModListType::OnlyOutdated)->reset();
// Updates is technically a server mod list :-) So I left it out here // Updates is technically a server mod list :-) So I left it out here
}); });
} }
@ -601,16 +601,6 @@ void ModList::updateDisplay(ModListDisplay display) {
); );
} }
// Make sure list isn't too small
// NOTE: Do NOT call `updateLayout` on m_list, it'll undo this!
if (m_list->m_contentLayer->getContentHeight() < m_list->getContentHeight()) {
auto diff = m_list->getContentHeight() - m_list->m_contentLayer->getContentHeight();
m_list->m_contentLayer->setContentHeight(m_list->getContentHeight());
for (auto child : CCArrayExt<CCNode*>(m_list->m_contentLayer->getChildren())) {
child->setPositionY(child->getPositionY() + diff);
}
}
// Preserve relative scroll position // Preserve relative scroll position
m_list->m_contentLayer->setPositionY(( m_list->m_contentLayer->setPositionY((
m_list->m_contentLayer->getContentHeight() - m_list->getContentHeight() m_list->m_contentLayer->getContentHeight() - m_list->getContentHeight()

View file

@ -64,7 +64,7 @@ std::optional<size_t> ModListSource::getItemCount() const {
void ModListSource::setPageSize(size_t size) { void ModListSource::setPageSize(size_t size) {
if (m_pageSize != size) { if (m_pageSize != size) {
m_pageSize = size; m_pageSize = size;
this->clearCache(); this->reset();
} }
} }

View file

@ -6,7 +6,7 @@
using namespace geode::prelude; using namespace geode::prelude;
PlatformID PlatformID::from(const char* str) { PlatformID PlatformID::from(const char* str) {
// todo in v5: this should just be // todo in v4: this should just be
// "win" -> Windows // "win" -> Windows
// "mac", "mac-intel", "mac-arm" -> Mac // "mac", "mac-intel", "mac-arm" -> Mac
// "ios" -> iOS // "ios" -> iOS
@ -38,7 +38,7 @@ PlatformID PlatformID::from(const char* str) {
} }
bool PlatformID::coveredBy(const char* str, PlatformID t) { bool PlatformID::coveredBy(const char* str, PlatformID t) {
// todo in v5: this is ridiculously inefficient currently - in v5 just use a flag check! // todo in v4: this is ridiculously inefficient currently - in v4 just use a flag check!
return ranges::contains(getCovered(str), t); return ranges::contains(getCovered(str), t);
} }