mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-21 05:06:29 +00:00
Load user plugins on startup instead of lazily at snapshot time
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<_>, _>>()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user