mirror of
https://github.com/hannobraun/Fornjot
synced 2025-02-26 00:55:50 +00:00
commit
bbca606f56
@ -1,3 +1,10 @@
|
|||||||
|
//! Plugin host for Fornjot models
|
||||||
|
//!
|
||||||
|
//! Fornjot models are loaded into the Fornjot application as plugins. This
|
||||||
|
//! crate contains the code required to host plugins.
|
||||||
|
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
@ -11,6 +18,7 @@ use std::{
|
|||||||
use notify::Watcher as _;
|
use notify::Watcher as _;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Represents a Fornjot model
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
src_path: PathBuf,
|
src_path: PathBuf,
|
||||||
lib_path: PathBuf,
|
lib_path: PathBuf,
|
||||||
@ -18,6 +26,11 @@ pub struct Model {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Model {
|
impl Model {
|
||||||
|
/// Initialize the model from a path
|
||||||
|
///
|
||||||
|
/// Optionally, the target directory where plugin files are compiled to can
|
||||||
|
/// be provided. If it is not provided, the target directory is assumed to
|
||||||
|
/// be located within the model path.
|
||||||
pub fn from_path(
|
pub fn from_path(
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
target_dir: Option<PathBuf>,
|
target_dir: Option<PathBuf>,
|
||||||
@ -56,6 +69,13 @@ impl Model {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load the model once
|
||||||
|
///
|
||||||
|
/// The passed arguments are provided to the model. Returns the shape that
|
||||||
|
/// the model returns.
|
||||||
|
///
|
||||||
|
/// Please refer to [`Model::load_and_watch`], if you want to watch the
|
||||||
|
/// model for changes, reloading it continually.
|
||||||
pub fn load_once(
|
pub fn load_once(
|
||||||
&self,
|
&self,
|
||||||
arguments: &HashMap<String, String>,
|
arguments: &HashMap<String, String>,
|
||||||
@ -96,6 +116,12 @@ impl Model {
|
|||||||
Ok(shape)
|
Ok(shape)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Load the model, then watch it for changes
|
||||||
|
///
|
||||||
|
/// Whenever a change is detected, the model is being reloaded.
|
||||||
|
///
|
||||||
|
/// Consumes this instance of `Model` and returns a [`Watcher`], which can
|
||||||
|
/// be queried for changes to the model.
|
||||||
pub fn load_and_watch(
|
pub fn load_and_watch(
|
||||||
self,
|
self,
|
||||||
parameters: HashMap<String, String>,
|
parameters: HashMap<String, String>,
|
||||||
@ -175,6 +201,7 @@ impl Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Watches a model for changes, reloading it continually
|
||||||
pub struct Watcher {
|
pub struct Watcher {
|
||||||
_watcher: Box<dyn notify::Watcher>,
|
_watcher: Box<dyn notify::Watcher>,
|
||||||
channel: mpsc::Receiver<()>,
|
channel: mpsc::Receiver<()>,
|
||||||
@ -183,6 +210,10 @@ pub struct Watcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Watcher {
|
impl Watcher {
|
||||||
|
/// Receive an updated shape that the reloaded model created
|
||||||
|
///
|
||||||
|
/// Returns `None`, if the model has not changed since the last time this
|
||||||
|
/// method was called.
|
||||||
pub fn receive(&self) -> Option<fj::Shape> {
|
pub fn receive(&self) -> Option<fj::Shape> {
|
||||||
match self.channel.try_recv() {
|
match self.channel.try_recv() {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
@ -216,17 +247,22 @@ impl Watcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An error that can occur when loading or reloading a model
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
/// Model failed to compile
|
||||||
#[error("Error compiling model")]
|
#[error("Error compiling model")]
|
||||||
Compile,
|
Compile,
|
||||||
|
|
||||||
|
/// I/O error while loading the model
|
||||||
#[error("I/O error while loading model")]
|
#[error("I/O error while loading model")]
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
|
|
||||||
|
/// Failed to load the model's dynamic library
|
||||||
#[error("Error loading model from dynamic library")]
|
#[error("Error loading model from dynamic library")]
|
||||||
LibLoading(#[from] libloading::Error),
|
LibLoading(#[from] libloading::Error),
|
||||||
|
|
||||||
|
/// Error while watching the model code for changes
|
||||||
#[error("Error watching model for changes")]
|
#[error("Error watching model for changes")]
|
||||||
Notify(#[from] notify::Error),
|
Notify(#[from] notify::Error),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user