163 Commits
Author SHA1 Message Date
Oliver Hamlet 356749df21 Update changelog and version for 0.27.0 2025-06-08 18:01:43 +01:00
Oliver Hamlet 3744908265 Remove ConditionalMetadata
While it makes sense, it doesn't really add any value and there is value in having all the relevant data and methods in a single class
2025-06-07 17:33:24 +01:00
Oliver Hamlet e90dffd518 Replace how esplugin errors are thrown
Throw std::runtime_error for all esplugin errors except ESP_ERROR_PLUGIN_METADATA_NOT_FOUND, which causes a PluginNotLoadedError to be thrown, since LOOT needs to be able to distinguish that error.
2025-06-07 17:05:48 +01:00
Oliver Hamlet ce729f8d76 Remove libloadorder_category()
Throw errors from libloadorder as std::runtime_error instead of std::system_error.
2025-06-07 17:05:47 +01:00
Oliver Hamlet f6e9954219 Remove ConditionSyntaxError
It's not usefully different from throwing std::runtime_error.
2025-06-07 17:05:47 +01:00
Oliver Hamlet 98234cc9cc Remove FileAccessError
It wasn't usefully different from just throwing std::runtime_error.
2025-06-07 17:05:42 +01:00
Oliver Hamlet 54c3f1a485 Update changelog and version for 0.26.3 2025-05-28 21:22:07 +01:00
Oliver Hamlet 20d583ba43 Update changelog and version for 0.26.2 2025-05-13 20:41:15 +01:00
Oliver Hamlet 766b4af256 Fix Breathe function parsing errors 2025-05-12 07:47:41 +01:00
Oliver Hamlet 856fae4912 Fix some incorrect Doxygen config 2025-05-12 07:47:24 +01:00
Oliver Hamlet 070822f37f Update changelog and version for 0.26.1 2025-05-01 21:48:52 +01:00
Oliver Hamlet 7bbf55cbb7 Update changelogs and version for 0.26.0 2025-04-19 21:58:39 +01:00
Oliver Hamlet 2d96ba13d9 Update changelog and version for 0.25.5 2025-03-15 21:16:08 +00:00
Oliver Hamlet 59901d2318 Update changelog and version for 0.25.4 2025-03-04 19:22:51 +00:00
Oliver Hamlet db6d39bd93 Update changelog and version for 0.25.3 2025-02-23 16:10:35 +00:00
Oliver Hamlet a49075aaa9 Update changelog and version for 0.25.2 2025-02-10 09:48:32 +00:00
Oliver Hamlet f865167997 Update changelog and version for 0.25.1 2025-02-03 21:19:07 +00:00
Oliver Hamlet 06937ffc83 Update changelog and version for 0.25.0 2025-02-02 21:32:30 +00:00
Oliver Hamlet c26b495c03 Update libloadorder to 18.2.1 2025-02-02 21:32:06 +00:00
Oliver Hamlet c8381617a8 Make plugin loading and sorting more granular
- Don't clear the cache in LoadPlugins()
- Don't load plugins in SortPlugins(), and make it take a vector of strings, not paths.
- Add a ClearLoadedPlugins() method to clear the loaded plugins cache.
- Remove IdentifyMainMasterFile()

Instead of calling IdentifyMainMasterFile(), callers can use LoadPlugins() to initially load all plugin headers only, then omit the main master file when calling LoadPlugins() to fully load plugins.
2025-02-02 18:01:19 +00:00
Oliver Hamlet d8a3604b0c Update changelog 2025-02-01 22:00:00 +00:00
Oliver Hamlet 84c0cca534 Implement support for OpenMW
Most of the complexity is handled by libloadorder, but it's worth noting that:

- The game path is OpenMW's install path, not Morrowind's
- OpenMW doesn't force master-flagged plugins to load before others
- OpenMW doesn't provide a way to record the load order of inactive plugins
- .omwgame and .omwaddon plugins are equivalent to .esm and .esp respectively, while .omwscripts plugins have a completely different format with none of the metadata that libloot uses.
- OpenMW effectively relies on additional data paths to load Morrowind's (and mods') files, and the last directory listed that contains a given filename is used to load a file with that filename, with the main data path effectively being the first listed.
- I've disabled support for ghosted plugins for OpenMW because it makes the multi-path stuff more confusing and may not provide any benefit.
2025-02-01 21:36:03 +00:00
Oliver Hamlet 1532c932af Update sorting doc to reflect groups changes 2025-01-18 22:29:50 +00:00
Oliver HamletandOliver Hamlet 997631667f Overhaul how group edges are added during sorting
The new logic is conceptually simpler, with fewer special cases to
handle. Unlike the old implementation, the new approach avoids cycles.

It basically does depth-first searches through the group graph, adding
edges from each group's plugins to the plugins in the group's
successors.

This involved reversing the direction of edges in the group graph, as
this switches the logic from trying to find predecessors to trying to
successors: the new direction matches that of plugin graph edges, so
it's less confusing.

I can't think of a situation in which the iteration order of plugins
within a group matters. I tested it manually with my test load order of
~1600 plugins, and saw no difference when the order was randomly
shuffled. I've added a test case but it's a relatively simple scenario
and there may be a more complex scenario where it would matter that I
haven't thought of.

A buffer is used to hold the plugins in the previous groups in the
current path, because that's noticeably faster than just recording the
path and looking up the plugins for each group in the path. It does
duplicate the group vectors, but that's an insignificant amount of
memory used.

The new approach has a negative performance impact, with sorting now 15%
slower than before.

A more efficient solution could be to implement a custom DFS algorithm
that doesn't stop when it reaches a vertex it's already visited (which
would be fine since the graph has already been validated to be acyclic),
as then only the root vertices would need to be searched from.
2025-01-17 23:36:02 +00:00
Oliver Hamlet 44008ea720 Update changelog and version for 0.24.5 2024-10-24 10:40:20 +01:00