diff --git a/lib/mod_list.dart b/lib/mod_list.dart index 1c7809b..7fa93d7 100644 --- a/lib/mod_list.dart +++ b/lib/mod_list.dart @@ -184,27 +184,15 @@ class ModList { } } - // List of mod ids - List sort() { - final sortedMods = activeMods.keys.toList(); - sortedMods.sort((a, b) { - final aIndex = mods[a]!.loadBefore.length; - final bIndex = mods[b]!.loadBefore.length; - return aIndex.compareTo(bIndex); - }); - return sortedMods; - } - List> checkIncompatibilities() { List> conflicts = []; List activeModIds = activeMods.keys.toList(); // Only check each pair once - for (int i = 0; i < activeModIds.length; i++) { - String modId = activeModIds[i]; + for (final modId in activeModIds) { Mod mod = mods[modId]!; - for (String incompId in mod.incompatibilities) { + for (final incompId in mod.incompatibilities) { // Only process if other mod is active and we haven't checked this pair yet if (activeMods.containsKey(incompId) && modId.compareTo(incompId) < 0) { conflicts.add([modId, incompId]); @@ -217,7 +205,7 @@ class ModList { /// Generate a load order for active mods List generateLoadOrder() { // Check for incompatibilities first - List> conflicts = checkIncompatibilities(); + final conflicts = checkIncompatibilities(); if (conflicts.isNotEmpty) { throw Exception( "Incompatible mods selected: ${conflicts.map((c) => "${c[0]} and ${c[1]}").join(', ')}", @@ -225,19 +213,23 @@ class ModList { } // Reset all marks for topological sort - for (Mod mod in mods.values) { + for (final mod in mods.values) { mod.visited = false; mod.mark = false; mod.position = -1; } - List result = []; + final result = []; int position = 0; // Topological sort void visit(Mod mod) { + if (!mod.enabled) { + mod.visited = true; + return; + } if (mod.mark) { - List cyclePath = + final cyclePath = mods.values.where((m) => m.mark).map((m) => m.name).toList(); throw Exception( "Cyclic dependency detected: ${cyclePath.join(' -> ')}", diff --git a/test/mod_list_test.dart b/test/mod_list_test.dart index 169f9b3..6453280 100644 --- a/test/mod_list_test.dart +++ b/test/mod_list_test.dart @@ -50,13 +50,26 @@ void main() { id: 'disabledDummy', enabled: false, ), + 'yuuuge': dummyMod.copyWith( + name: 'Yuuuge', + id: 'yuuuge', + enabled: true, + size: 1000000, + ), + 'smol': dummyMod.copyWith( + name: 'Smol', + id: 'smol', + enabled: true, + size: 1, + ), }; final dummyList = ModList(configPath: configPath, modsPath: modsRoot); dummyList.mods.addAll(dummyMods); for (final mod in dummyMods.keys) { - dummyList.activeMods[mod] = true; + dummyList.setEnabled(mod, true); } + dummyList.setEnabled('disabledDummy', false); final sortedMods = dummyList.generateLoadOrder(); group('Test sorting', () { @@ -74,5 +87,10 @@ void main() { final disabledIndex = sortedMods.indexOf('disabledDummy'); expect(disabledIndex, isNegative); }); + test("yuuuge mod should load before smol", () { + final smolIndex = sortedMods.indexOf('smol'); + final yuuugeIndex = sortedMods.indexOf('yuuuge'); + expect(yuuugeIndex, lessThan(smolIndex)); + }); }); }