Load user plugins on startup instead of lazily at snapshot time

This commit is contained in:
Lucien Greathouse
2019-10-12 23:27:12 -07:00
parent d1887c6cd3
commit 7077f0f1f3
3 changed files with 37 additions and 62 deletions

View File

@@ -41,8 +41,7 @@ pub fn start<F: VfsFetcher>(
// If the project file defines no plugins, then there's no need to
// initialize the snapshot plugin context.
if !project.plugins.is_empty() {
snapshot_context.plugin_context =
Some(SnapshotPluginContext::new(project.plugins.clone()));
snapshot_context.plugin_context = Some(SnapshotPluginContext::new(&project.plugins));
}
}

View File

@@ -1,7 +1,9 @@
use std::{fmt, ops::Deref, path::PathBuf};
use std::{fmt, fs, ops::Deref, path::Path};
use rlua::{Lua, RegistryKey};
use super::error::SnapshotError;
#[derive(Debug)]
pub struct InstanceSnapshotContext {
/// Holds all the state needed to run user plugins as part of the snapshot
@@ -23,22 +25,42 @@ impl Default for InstanceSnapshotContext {
pub struct SnapshotPluginContext {
pub state: IgnoreDebug<Lua>,
/// Paths to the user plugins files. These paths are generated by the root
/// project file, if there is one.
pub plugin_paths: Vec<PathBuf>,
/// Lazy-initialized registry keys pointing to the values returned by each
/// user plugin. When processing user plugins, these should be applied in
/// order.
pub plugin_functions: Option<Vec<RegistryKey>>,
/// Registry keys pointing to the values returned by each user plugin. When
/// processing user plugins, these should be applied in order.
pub plugin_functions: Vec<RegistryKey>,
}
impl SnapshotPluginContext {
pub fn new(plugin_paths: Vec<PathBuf>) -> Self {
pub fn new<P: AsRef<Path>>(plugin_paths: &[P]) -> Self {
let lua_state = Lua::new();
let plugin_functions = plugin_paths
.iter()
.map(|path| {
let path = path.as_ref();
let content =
fs::read_to_string(path).map_err(|err| SnapshotError::wrap(err, path))?;
lua_state.context(|lua_context| {
// Plugins are currently expected to return a function that will
// be run when a snapshot needs to be generated.
let result = lua_context
.load(&content)
.set_name(&path.display().to_string())?
.call::<_, rlua::Function>(())?;
let key = lua_context.create_registry_value(result)?;
Ok(key)
})
})
.collect::<Result<Vec<_>, SnapshotError>>()
.expect("Plugin initialization error");
Self {
state: IgnoreDebug(Lua::new()),
plugin_paths,
plugin_functions: None,
state: IgnoreDebug(lua_state),
plugin_functions,
}
}
}

View File

@@ -1,12 +1,7 @@
use std::{fs, path::Path};
use rlua::{Lua, RegistryKey};
use crate::vfs::{Vfs, VfsEntry, VfsFetcher};
use super::{
context::InstanceSnapshotContext,
error::SnapshotError,
middleware::{SnapshotInstanceResult, SnapshotMiddleware},
};
@@ -30,23 +25,9 @@ impl SnapshotMiddleware for SnapshotUserPlugins {
None => return Ok(None),
};
// If the plugins listed for use haven't been loaded yet, read them into
// memory, run them, and keep the result they return as a registry key
// into our Lua state.
let keys = match &plugin_context.plugin_functions {
Some(keys) => keys,
None => {
plugin_context.plugin_functions = Some(initialize_plugins(
&plugin_context.state,
&plugin_context.plugin_paths,
)?);
plugin_context.plugin_functions.as_ref().unwrap()
}
};
plugin_context.state.context(|lua_context| {
lua_context.scope(|_scope| {
for _key in keys {
for _key in &plugin_context.plugin_functions {
// TODO: Invoke plugin here and get result out.
// The current plan for plugins here is to make them work
@@ -85,30 +66,3 @@ impl SnapshotMiddleware for SnapshotUserPlugins {
Ok(None)
}
}
fn initialize_plugins<P: AsRef<Path>>(
lua_state: &Lua,
plugin_paths: &[P],
) -> Result<Vec<RegistryKey>, SnapshotError> {
plugin_paths
.iter()
.map(|path| {
let path = path.as_ref();
let content = fs::read_to_string(path).map_err(|err| SnapshotError::wrap(err, path))?;
lua_state.context(|lua_context| {
// Plugins are currently expected to return a function that will
// be run when a snapshot needs to be generated.
let result = lua_context
.load(&content)
.set_name(&path.display().to_string())?
.call::<_, rlua::Function>(())?;
let key = lua_context.create_registry_value(result)?;
Ok(key)
})
})
.collect::<Result<Vec<_>, _>>()
}