Skip to content

Commit

Permalink
Refactor how plugins are counted
Browse files Browse the repository at this point in the history
To reduce a little duplication.
  • Loading branch information
Ortham committed Feb 18, 2023
1 parent d42d36c commit e7fd790
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 56 deletions.
40 changes: 0 additions & 40 deletions src/load_order/mutable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Plugin>;

fn insert_position(&self, plugin: &Plugin) -> Option<usize>;

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<String> {
let entries = match read_dir(self.game_settings().plugins_directory()) {
Ok(x) => x,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
71 changes: 55 additions & 16 deletions src/load_order/writable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>;

Expand Down Expand Up @@ -123,11 +126,42 @@ pub fn remove<T: MutableLoadOrder>(load_order: &mut T, plugin_name: &str) -> Res
}
}

#[derive(Clone, Copy, Debug, Default)]
struct PluginCounts {
light: usize,
normal: usize,
}

fn count_active_plugins<T: ReadableLoadOrderBase>(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<T: MutableLoadOrder>(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()
Expand All @@ -138,14 +172,19 @@ pub fn activate<T: MutableLoadOrder>(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<T: MutableLoadOrder>(load_order: &mut T, plugin_name: &str) -> Result<(), Error> {
Expand All @@ -167,9 +206,9 @@ pub fn set_active_plugins<T: MutableLoadOrder>(
) -> 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);
}

Expand Down

0 comments on commit e7fd790

Please sign in to comment.