use std::fmt::Debug;
use std::hash::Hash;
use after_effects::{InData, OutData, Parameters};
use crate::effect::HostCapabilities;
use crate::params::SetupParams;
pub type ActionCallback = Box<dyn Fn(&mut ActionContext) -> Result<(), &'static str> + Send + Sync + 'static>;
pub struct ActionContext {
pub(crate) hot_reload_shaders: bool,
}
impl ActionContext {
pub(crate) fn new() -> Self {
Self { hot_reload_shaders: false }
}
pub fn hot_reload_shaders(&mut self) {
self.hot_reload_shaders = true;
}
}
pub(crate) struct VisibilityRule<P>
where
P: Eq + Hash + Copy + Debug + 'static,
{
pub param: P,
pub predicate: Box<dyn Fn(&Parameters<P>, HostCapabilities) -> bool + Send + Sync + 'static>,
}
pub(crate) struct ActionRule<P> {
pub param: P,
pub callback: ActionCallback,
}
pub struct ParamApi<'a, P>
where
P: SetupParams + Eq + Hash + Copy + Debug + Into<usize> + 'static,
{
params: &'a mut Parameters<'a, P>,
in_data: InData,
out_data: OutData,
visibility: Vec<VisibilityRule<P>>,
actions: Vec<ActionRule<P>>,
}
impl<'a, P> ParamApi<'a, P>
where
P: SetupParams + Eq + Hash + Copy + Debug + Into<usize> + 'static,
{
pub fn new(params: &'a mut Parameters<'a, P>, in_data: InData, out_data: OutData) -> Self {
Self {
params,
in_data,
out_data,
visibility: Vec::new(),
actions: Vec::new(),
}
}
pub fn raw_setup_mut(&mut self) -> &mut Parameters<'a, P> {
self.params
}
pub fn in_data(&self) -> &InData {
&self.in_data
}
pub fn out_data(&mut self) -> &mut OutData {
&mut self.out_data
}
pub fn visibility<F>(&mut self, f: F)
where
F: FnOnce(&mut VisibilityBuilder<P>),
{
let mut builder = VisibilityBuilder { rules: Vec::new() };
f(&mut builder);
self.visibility.extend(builder.rules);
}
pub fn actions<F>(&mut self, f: F)
where
F: FnOnce(&mut ActionBuilder<P>),
{
let mut builder = ActionBuilder { rules: Vec::new() };
f(&mut builder);
self.actions.extend(builder.rules);
}
pub(crate) fn into_rules(self) -> (Vec<VisibilityRule<P>>, Vec<ActionRule<P>>) {
(self.visibility, self.actions)
}
}
pub struct VisibilityBuilder<P>
where
P: Eq + Hash + Copy + Debug + 'static,
{
rules: Vec<VisibilityRule<P>>,
}
impl<P> VisibilityBuilder<P>
where
P: Eq + Hash + Copy + Debug + Into<usize> + 'static,
{
pub fn show<F>(&mut self, param: P, predicate: F) -> &mut Self
where
F: Fn(&Parameters<P>, HostCapabilities) -> bool + Send + Sync + 'static,
{
self.rules.push(VisibilityRule {
param,
predicate: Box::new(predicate),
});
self
}
pub fn show_all<I, F>(&mut self, params: I, predicate: F) -> &mut Self
where
I: IntoIterator<Item = P>,
F: Fn(&Parameters<P>, HostCapabilities) -> bool + Clone + Send + Sync + 'static,
{
for p in params {
let pred = predicate.clone();
self.rules.push(VisibilityRule {
param: p,
predicate: Box::new(pred),
});
}
self
}
}
pub struct ActionBuilder<P> {
rules: Vec<ActionRule<P>>,
}
impl<P> ActionBuilder<P>
where
P: Eq + Hash + Copy + Debug + Into<usize> + 'static,
{
pub fn on_click<F>(&mut self, param: P, callback: F) -> &mut Self
where
F: Fn(&mut ActionContext) -> Result<(), &'static str> + Send + Sync + 'static,
{
self.rules.push(ActionRule { param, callback: Box::new(callback) });
self
}
}