From e7fd7904e2787f42bd5f4ff1956471c3fc6344b3 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Sat, 18 Feb 2023 18:44:07 +0000 Subject: [PATCH] Refactor how plugins are counted To reduce a little duplication. --- src/load_order/mutable.rs | 40 --------------------- src/load_order/writable.rs | 71 +++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 56 deletions(-) diff --git a/src/load_order/mutable.rs b/src/load_order/mutable.rs index 07be459..22eb1ab 100644 --- a/src/load_order/mutable.rs +++ b/src/load_order/mutable.rs @@ -30,28 +30,11 @@ use crate::enums::Error; use crate::game_settings::GameSettings; use crate::plugin::{trim_dot_ghost, Plugin}; -pub const MAX_ACTIVE_NORMAL_PLUGINS: usize = 255; -pub const MAX_ACTIVE_LIGHT_PLUGINS: usize = 4096; - pub trait MutableLoadOrder: ReadableLoadOrder + ReadableLoadOrderBase + Sync { fn plugins_mut(&mut self) -> &mut Vec; fn insert_position(&self, plugin: &Plugin) -> Option; - fn count_active_normal_plugins(&self) -> usize { - self.plugins() - .iter() - .filter(|p| !p.is_light_plugin() && p.is_active()) - .count() - } - - fn count_active_light_plugins(&self) -> usize { - self.plugins() - .iter() - .filter(|p| p.is_light_plugin() && p.is_active()) - .count() - } - fn find_plugins_in_dir(&self) -> Vec { let entries = match read_dir(self.game_settings().plugins_directory()) { Ok(x) => x, @@ -95,18 +78,6 @@ pub trait MutableLoadOrder: ReadableLoadOrder + ReadableLoadOrderBase + Sync { .collect() } - fn count_normal_plugins(&mut self, existing_plugin_indices: &[usize]) -> usize { - count_plugins(self.plugins(), existing_plugin_indices, false) - } - - fn count_light_plugins(&mut self, existing_plugin_indices: &[usize]) -> usize { - if self.game_settings().id().supports_light_plugins() { - count_plugins(self.plugins(), existing_plugin_indices, true) - } else { - 0 - } - } - fn move_or_insert_plugin_with_index( &mut self, plugin_name: &str, @@ -293,17 +264,6 @@ fn to_plugin( } } -fn count_plugins( - existing_plugins: &[Plugin], - existing_plugin_indices: &[usize], - count_light_plugins: bool, -) -> usize { - existing_plugin_indices - .iter() - .filter(|i| existing_plugins[**i].is_light_plugin() == count_light_plugins) - .count() -} - fn validate_master_file_index( plugins: &[Plugin], plugin: &Plugin, diff --git a/src/load_order/writable.rs b/src/load_order/writable.rs index 169b8d0..4176db2 100644 --- a/src/load_order/writable.rs +++ b/src/load_order/writable.rs @@ -22,11 +22,14 @@ use std::path::Path; use unicase::eq; -use super::mutable::{MutableLoadOrder, MAX_ACTIVE_LIGHT_PLUGINS, MAX_ACTIVE_NORMAL_PLUGINS}; -use super::readable::ReadableLoadOrder; +use super::mutable::MutableLoadOrder; +use super::readable::{ReadableLoadOrder, ReadableLoadOrderBase}; use crate::enums::Error; use crate::plugin::Plugin; +const MAX_ACTIVE_NORMAL_PLUGINS: usize = 255; +const MAX_ACTIVE_LIGHT_PLUGINS: usize = 4096; + pub trait WritableLoadOrder: ReadableLoadOrder { fn load(&mut self) -> Result<(), Error>; @@ -123,11 +126,42 @@ pub fn remove(load_order: &mut T, plugin_name: &str) -> Res } } +#[derive(Clone, Copy, Debug, Default)] +struct PluginCounts { + light: usize, + normal: usize, +} + +fn count_active_plugins(load_order: &T) -> PluginCounts { + let mut counts = PluginCounts::default(); + + for plugin in load_order.plugins().iter().filter(|p| p.is_active()) { + if plugin.is_light_plugin() { + counts.light += 1; + } else { + counts.normal += 1; + } + } + + counts +} + +fn count_plugins(existing_plugins: &[Plugin], existing_plugin_indexes: &[usize]) -> PluginCounts { + let mut counts = PluginCounts::default(); + + for index in existing_plugin_indexes { + if existing_plugins[*index].is_light_plugin() { + counts.light += 1; + } else { + counts.normal += 1; + } + } + + counts +} + pub fn activate(load_order: &mut T, plugin_name: &str) -> Result<(), Error> { - let at_max_active_normal_plugins = - load_order.count_active_normal_plugins() == MAX_ACTIVE_NORMAL_PLUGINS; - let at_max_active_light_plugins = - load_order.count_active_light_plugins() == MAX_ACTIVE_LIGHT_PLUGINS; + let counts = count_active_plugins(load_order); let plugin = match load_order .plugins_mut() @@ -138,14 +172,19 @@ pub fn activate(load_order: &mut T, plugin_name: &str) -> R None => return Err(Error::PluginNotFound(plugin_name.to_string())), }; - if !plugin.is_active() - && ((!plugin.is_light_plugin() && at_max_active_normal_plugins) - || (plugin.is_light_plugin() && at_max_active_light_plugins)) - { - Err(Error::TooManyActivePlugins) - } else { - plugin.activate() + if !plugin.is_active() { + let is_light = plugin.is_light_plugin(); + + if (is_light && counts.light == MAX_ACTIVE_LIGHT_PLUGINS) + || (!is_light && counts.normal == MAX_ACTIVE_NORMAL_PLUGINS) + { + return Err(Error::TooManyActivePlugins); + } else { + plugin.activate()?; + } } + + Ok(()) } pub fn deactivate(load_order: &mut T, plugin_name: &str) -> Result<(), Error> { @@ -167,9 +206,9 @@ pub fn set_active_plugins( ) -> Result<(), Error> { let existing_plugin_indices = load_order.lookup_plugins(active_plugin_names)?; - if load_order.count_normal_plugins(&existing_plugin_indices) > MAX_ACTIVE_NORMAL_PLUGINS - || load_order.count_light_plugins(&existing_plugin_indices) > MAX_ACTIVE_LIGHT_PLUGINS - { + let counts = count_plugins(load_order.plugins(), &existing_plugin_indices); + + if counts.normal > MAX_ACTIVE_NORMAL_PLUGINS || counts.light > MAX_ACTIVE_LIGHT_PLUGINS { return Err(Error::TooManyActivePlugins); }