Skip to content

Commit

Permalink
core refactor done
Browse files Browse the repository at this point in the history
  • Loading branch information
Pistonight committed Mar 22, 2024
1 parent 9463de6 commit 664371f
Show file tree
Hide file tree
Showing 26 changed files with 495 additions and 407 deletions.
4 changes: 2 additions & 2 deletions compiler-core/src/comp/comp_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use instant::Instant;

use crate::lang::{DocDiagnostic, DocRichText, IntoDiagnostic};
use crate::pack::CompileContext;
use crate::plugin::PluginRuntime;
use crate::plugin;
use crate::prep::{CompilerMetadata, PrepError, RouteConfig, RouteMetadata};

use super::CompSection;
Expand All @@ -25,7 +25,7 @@ pub struct CompDoc<'p> {
/// Plugins
///
/// CompDoc holds this to pass it to the next phase. It does not uses it directly.
pub plugin_runtimes: Vec<Box<dyn PluginRuntime>>,
pub plugin_runtimes: Vec<plugin::BoxedRuntime>,
}

impl<'p> Deref for CompDoc<'p> {
Expand Down
6 changes: 3 additions & 3 deletions compiler-core/src/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use crate::comp::CompDoc;
use crate::lang::IntoDiagnostic;
use crate::macros::derive_wasm;
use crate::plugin::{PluginMetadata, PluginRuntime};
use crate::plugin;

mod error;
pub use error::*;
Expand All @@ -36,11 +36,11 @@ pub struct ExecContext<'p> {
/// The exec doc
pub exec_doc: ExecDoc<'p>,
/// Plugin information collected, including disabled plugins
pub plugin_metadata: Vec<PluginMetadata>,
pub plugin_metadata: Vec<plugin::Metadata>,
/// The plugin runtimes at this point
/// which can be used to run exporters
#[serde(skip)]
pub plugin_runtimes: Vec<Box<dyn PluginRuntime>>,
pub plugin_runtimes: Vec<plugin::BoxedRuntime>,
}

impl ExecContext<'static> {
Expand Down
2 changes: 0 additions & 2 deletions compiler-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,4 @@ pub use expo::{ExpoContext, ExpoDoc, ExportRequest};
pub use pack::{CompileContext, Compiler};
pub use prep::{ContextBuilder, PreparedContext};

pub use plugin::{PluginOptions, PluginOptionsRaw};

pub use celerb::*;
67 changes: 27 additions & 40 deletions compiler-core/src/pack/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@
//! The output is a [`Compiler`]

use std::borrow::Cow;
use std::collections::BTreeSet;
use std::ops::{Deref, DerefMut};

use instant::Instant;

use crate::env::yield_budget;
use crate::json::RouteBlob;
use crate::plugin::{PluginList, PluginInstance, PluginMetadata, PluginOptions, PluginRuntime};
use crate::plugin;
use crate::prep::{self, CompilerMetadata, PrepDoc, PreparedContext, RouteConfig, Setting};
use crate::res::Loader;

Expand All @@ -44,7 +43,7 @@ pub struct Compiler<'p> {
/// Reference to the built route
pub route: Cow<'p, RouteBlob>,
/// Runtime of the plugins
pub plugin_runtimes: Vec<Box<dyn PluginRuntime>>,
pub plugin_runtimes: Vec<plugin::BoxedRuntime>,
}

impl<'p> Deref for Compiler<'p> {
Expand Down Expand Up @@ -82,67 +81,55 @@ pub struct CompileContext<'p> {
/// The metadata
pub meta: Cow<'p, CompilerMetadata>,
/// Plugin instances, does not include disabled plugins
pub plugins: Vec<PluginInstance>,
pub plugins: Vec<plugin::Instance>,
/// Plugin metadata, including disabled plugins
pub plugin_meta: Vec<PluginMetadata>,
pub plugin_meta: Vec<plugin::Metadata>,
/// Compiler settings
pub setting: &'p Setting,
}

impl<'p> CompileContext<'p> {
/// Configure the plugin list according to the options
pub async fn configure_plugins(&mut self, options: Option<PluginOptions>) -> PackResult<()> {
self.plugin_meta.clear();
pub async fn configure_plugins(&mut self, options: Option<plugin::Options>) -> PackResult<()> {
// apply options
let plugin::OptionsApply { metadata, user_plugins } = match options {
None => plugin::Options::apply_none(&self.plugins),
Some(options) => options.apply(&self.plugins),
};

// take the plugins out for processing
// new plugins will be put into self.plugins
let old_instances = std::mem::take(&mut self.plugins);

let mut list = PluginList::default();

// we don't know how many plugins the users specify
// so using a set to check for remove
// even it's less efficient for small sizes
// TODO #226: this will be a BTreeMap with ordinal
// let (remove, add) = match options {
// None => (BTreeSet::new(), None),
// Some(options) => (options.remove.into_iter().collect(), Some(options.add)),
// };
let (remove, add) = match options {
_ => (BTreeSet::<String>::new(), None::<Vec<PluginInstance>>),
};
// temporary storage of plugins
// plugins will load actual instances into this list
let mut list = plugin::LoadList::default();

// load plugins from route into the list
for plugin in old_instances {
// disabled plugins are removed
for (meta, plugin) in metadata.iter().zip(old_instances.into_iter()) {
yield_budget(4).await;
let meta = PluginMetadata::new(&plugin);
if !remove.contains(&meta.display_id) {
if meta.is_enabled {
let early_rt = plugin.create_early_runtime()?;
early_rt.on_load_plugin(plugin, &mut list).await?;
}

self.plugin_meta.push(meta);
}

// load plugins from options into the list
if let Some(add) = add {
for plugin in add {
yield_budget(4).await;
let meta = PluginMetadata::new_from_user(&plugin);

// don't need to check remove for user-added plugins
let early_rt = plugin.create_early_runtime()?;
early_rt.on_load_plugin(plugin, &mut list).await?;

self.plugin_meta.push(meta);
}
// load user plugins
// disabled plugins are already removed
for plugin in user_plugins {
yield_budget(4).await;
let early_rt = plugin.create_early_runtime()?;
early_rt.on_load_plugin(plugin, &mut list).await?;
}

// transfer new plugin list and meta
self.plugins.extend(list);
todo!(); // figure out if plugin added by other plugins should be visible in plugin setting
self.plugin_meta = metadata;

Ok(())
}

pub async fn create_plugin_runtimes(&self) -> PackResult<Vec<Box<dyn PluginRuntime>>> {
pub async fn create_plugin_runtimes(&self) -> PackResult<Vec<plugin::BoxedRuntime>> {
let mut output = Vec::with_capacity(self.plugins.len());
for plugin in &self.plugins {
yield_budget(4).await;
Expand Down
45 changes: 23 additions & 22 deletions compiler-core/src/plugin/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@ use std::collections::BTreeMap;

use crate::macros::async_trait;

use super::{PluginError, PluginInstance, PluginMetadata, PluginResult};
use super::{PluginError, Instance, PluginResult};

/// Early plugin runtime are ran to initialize the plugin instance list
#[async_trait(auto)]
pub trait EarlyPluginRuntime {
pub trait EarlyRuntime {
/// Called when a plugin is attempted to be loaded
///
/// Plugins that wish to define their own loading behavior should implement this method,
/// such as augment an existing plugin when a duplicate is found, or add immediate or deferred plugins for
/// tasks depending on other plugins. Note that plugins added here are not visible to the user
/// through plugin settings to be disabled
async fn on_load_plugin(&self, instance: PluginInstance, plugins: &mut PluginList) -> PluginResult<()> {
async fn on_load_plugin(&self, instance: Instance, plugins: &mut LoadList) -> PluginResult<()> {
if !instance.allow_duplicate {
let id = instance.get_id();
if plugins.contains_immediate(&id) {
Expand All @@ -25,44 +25,45 @@ pub trait EarlyPluginRuntime {
}
}

pub struct DefaultEarlyPluginRuntime;
impl EarlyPluginRuntime for DefaultEarlyPluginRuntime {}
pub type BoxedEarlyRuntime = Box<dyn EarlyRuntime>;

pub struct DefaultEarlyRuntime;
impl EarlyRuntime for DefaultEarlyRuntime {}

#[derive(Debug, Default)]
pub struct PluginList {
pub struct LoadList {
/// Plugins that are queued to be added immediately
immediate: Vec<InstanceEntry>,

immediate_first: BTreeMap<String, PluginInstance>,

meta: Vec<PluginMetadata>,
immediate_first: BTreeMap<String, Instance>,

/// Plugins that are queued to be added after the immediate plugins are added
///
/// In this list, plugins are added in the reverse order. These are also invisible to the user
/// and other plugins, and cannot be disabled individually
deferred: Vec<PluginInstance>,
deferred: Vec<Instance>,
}

#[derive(Debug)]
enum InstanceEntry {
First(String),
NotFirst(PluginInstance),
}

struct PluginMetaTree {
NotFirst(Instance),
}

impl PluginList {
pub fn get_first_immediate_by_id(&self, id: &str) -> Option<&PluginInstance> {
impl LoadList {
pub fn get_first_immediate(&self, id: &str) -> Option<&Instance> {
self.immediate_first.get(id)
}

pub fn get_first_immediate_mut(&mut self, id: &str) -> Option<&mut Instance> {
self.immediate_first.get_mut(id)
}

pub fn contains_immediate(&self, id: &str) -> bool {
self.immediate_first.contains_key(id)
}

pub fn add_immediate(&mut self, instance: PluginInstance) {
pub fn add_immediate(&mut self, instance: Instance) {
let id = instance.get_id();
let id_ref: &str = id.as_ref();
if self.immediate_first.contains_key(id_ref) {
Expand All @@ -75,8 +76,8 @@ impl PluginList {
}
}

impl IntoIterator for PluginList {
type Item = PluginInstance;
impl IntoIterator for LoadList {
type Item = Instance;
type IntoIter = PluginListIntoIter;

fn into_iter(self) -> Self::IntoIter {
Expand All @@ -90,12 +91,12 @@ impl IntoIterator for PluginList {

pub struct PluginListIntoIter {
immediate_iter: std::vec::IntoIter<InstanceEntry>,
immediate_first: BTreeMap<String, PluginInstance>,
deferred_iter: std::iter::Rev<std::vec::IntoIter<PluginInstance>>,
immediate_first: BTreeMap<String, Instance>,
deferred_iter: std::iter::Rev<std::vec::IntoIter<Instance>>,
}

impl Iterator for PluginListIntoIter {
type Item = PluginInstance;
type Item = Instance;

fn next(&mut self) -> Option<Self::Item> {
match self.immediate_iter.next() {
Expand Down
Loading

0 comments on commit 664371f

Please sign in to comment.