🧑‍💻 Simplify action creation and management

This commit is contained in:
Manuel Cillero 2023-11-04 02:23:43 +01:00
parent 81b1877799
commit 23dc58c2ac
10 changed files with 106 additions and 118 deletions

View file

@ -1,6 +1,6 @@
use crate::prelude::*; use crate::prelude::*;
pub type FnAction<C> = fn(component: &C, cx: &mut Context); pub type FnAction<C> = fn(component: &mut C, cx: &mut Context);
mod before_prepare_component; mod before_prepare_component;
pub use before_prepare_component::*; pub use before_prepare_component::*;

View file

@ -3,24 +3,21 @@ use crate::prelude::*;
use super::FnAction; use super::FnAction;
pub struct AfterPrepareComponent<C: ComponentTrait> { pub struct AfterPrepareComponent<C: ComponentTrait> {
action: Option<FnAction<C>>, f: Option<FnAction<C>>,
referer: Option<Handle>, referer_handle: Option<Handle>,
referer_id: OptionId,
weight: Weight, weight: Weight,
} }
impl_handle!(ACTION_AFTER_PREPARE_COMPONENT for AfterPrepareComponent<ComponentTrait>); impl_handle!(ACTION_AFTER_PREPARE_COMPONENT for AfterPrepareComponent<ComponentTrait>);
impl<C: ComponentTrait> ActionTrait for AfterPrepareComponent<C> { impl<C: ComponentTrait> ActionTrait for AfterPrepareComponent<C> {
fn new() -> Self { fn referer_handle(&self) -> Option<Handle> {
AfterPrepareComponent { self.referer_handle
action: None,
referer: Some(C::static_handle()),
weight: 0,
}
} }
fn referer_handle(&self) -> Option<Handle> { fn referer_id(&self) -> Option<String> {
self.referer self.referer_id.get()
} }
fn weight(&self) -> Weight { fn weight(&self) -> Weight {
@ -29,33 +26,34 @@ impl<C: ComponentTrait> ActionTrait for AfterPrepareComponent<C> {
} }
impl<C: ComponentTrait> AfterPrepareComponent<C> { impl<C: ComponentTrait> AfterPrepareComponent<C> {
pub fn with(action: FnAction<C>) -> Self { pub fn with(f: FnAction<C>) -> Self {
AfterPrepareComponent { AfterPrepareComponent {
action: Some(action), f: Some(f),
referer: Some(C::static_handle()), referer_handle: Some(C::static_handle()),
referer_id: OptionId::default(),
weight: 0, weight: 0,
} }
} }
pub fn filtering_id(mut self, id: impl Into<String>) -> Self {
self.referer_id.alter_value(id);
self
}
pub fn with_weight(mut self, value: Weight) -> Self { pub fn with_weight(mut self, value: Weight) -> Self {
self.weight = value; self.weight = value;
self self
} }
pub(crate) fn run(&self, component: &mut C, cx: &mut Context) { #[inline(always)]
if let Some(action) = self.action { pub(crate) fn dispatch(component: &mut C, cx: &mut Context, id: Option<String>) {
action(component, cx) dispatch_actions(
} (ACTION_AFTER_PREPARE_COMPONENT, Some(component.handle()), id),
|action| {
if let Some(f) = action_ref::<AfterPrepareComponent<C>>(&**action).f {
f(component, cx)
}
},
);
} }
} }
#[inline(always)]
pub(crate) fn run_actions_after_prepare_component<C: ComponentTrait>(
component: &mut C,
cx: &mut Context,
) {
run_actions(
(ACTION_AFTER_PREPARE_COMPONENT, Some(component.handle())),
|action| action_ref::<AfterPrepareComponent<C>>(&**action).run(component, cx),
);
}

View file

@ -3,24 +3,21 @@ use crate::prelude::*;
use super::FnAction; use super::FnAction;
pub struct BeforePrepareComponent<C: ComponentTrait> { pub struct BeforePrepareComponent<C: ComponentTrait> {
action: Option<FnAction<C>>, f: Option<FnAction<C>>,
referer: Option<Handle>, referer_handle: Option<Handle>,
referer_id: OptionId,
weight: Weight, weight: Weight,
} }
impl_handle!(ACTION_BEFORE_PREPARE_COMPONENT for BeforePrepareComponent<ComponentTrait>); impl_handle!(ACTION_BEFORE_PREPARE_COMPONENT for BeforePrepareComponent<ComponentTrait>);
impl<C: ComponentTrait> ActionTrait for BeforePrepareComponent<C> { impl<C: ComponentTrait> ActionTrait for BeforePrepareComponent<C> {
fn new() -> Self { fn referer_handle(&self) -> Option<Handle> {
BeforePrepareComponent { self.referer_handle
action: None,
referer: Some(C::static_handle()),
weight: 0,
}
} }
fn referer_handle(&self) -> Option<Handle> { fn referer_id(&self) -> Option<String> {
self.referer self.referer_id.get()
} }
fn weight(&self) -> Weight { fn weight(&self) -> Weight {
@ -29,33 +26,38 @@ impl<C: ComponentTrait> ActionTrait for BeforePrepareComponent<C> {
} }
impl<C: ComponentTrait> BeforePrepareComponent<C> { impl<C: ComponentTrait> BeforePrepareComponent<C> {
pub fn with(action: FnAction<C>) -> Self { pub fn with(f: FnAction<C>) -> Self {
BeforePrepareComponent { BeforePrepareComponent {
action: Some(action), f: Some(f),
referer: Some(C::static_handle()), referer_handle: Some(C::static_handle()),
referer_id: OptionId::default(),
weight: 0, weight: 0,
} }
} }
pub fn filtering_id(mut self, id: impl Into<String>) -> Self {
self.referer_id.alter_value(id);
self
}
pub fn with_weight(mut self, value: Weight) -> Self { pub fn with_weight(mut self, value: Weight) -> Self {
self.weight = value; self.weight = value;
self self
} }
pub(crate) fn run(&self, component: &mut C, cx: &mut Context) { #[inline(always)]
if let Some(action) = self.action { pub(crate) fn dispatch(component: &mut C, cx: &mut Context, id: Option<String>) {
action(component, cx) dispatch_actions(
} (
ACTION_BEFORE_PREPARE_COMPONENT,
Some(component.handle()),
id,
),
|action| {
if let Some(f) = action_ref::<BeforePrepareComponent<C>>(&**action).f {
f(component, cx)
}
},
);
} }
} }
#[inline(always)]
pub(crate) fn run_actions_before_prepare_component<C: ComponentTrait>(
component: &mut C,
cx: &mut Context,
) {
run_actions(
(ACTION_BEFORE_PREPARE_COMPONENT, Some(component.handle())),
|action| action_ref::<BeforePrepareComponent<C>>(&**action).run(component, cx),
);
}

View file

@ -3,29 +3,22 @@ use crate::prelude::*;
use super::FnActionPage; use super::FnActionPage;
pub struct AfterPrepareBody { pub struct AfterPrepareBody {
action: Option<FnActionPage>, f: Option<FnActionPage>,
weight: Weight, weight: Weight,
} }
impl_handle!(ACTION_AFTER_PREPARE_BODY for AfterPrepareBody); impl_handle!(ACTION_AFTER_PREPARE_BODY for AfterPrepareBody);
impl ActionTrait for AfterPrepareBody { impl ActionTrait for AfterPrepareBody {
fn new() -> Self {
AfterPrepareBody {
action: None,
weight: 0,
}
}
fn weight(&self) -> Weight { fn weight(&self) -> Weight {
self.weight self.weight
} }
} }
impl AfterPrepareBody { impl AfterPrepareBody {
pub fn with(action: FnActionPage) -> Self { pub fn with(f: FnActionPage) -> Self {
AfterPrepareBody { AfterPrepareBody {
action: Some(action), f: Some(f),
weight: 0, weight: 0,
} }
} }
@ -35,16 +28,12 @@ impl AfterPrepareBody {
self self
} }
pub(crate) fn run(&self, page: &mut Page) { #[inline(always)]
if let Some(action) = self.action { pub(crate) fn dispatch(page: &mut Page) {
action(page) dispatch_actions((ACTION_AFTER_PREPARE_BODY, None, None), |action| {
} if let Some(f) = action_ref::<AfterPrepareBody>(&**action).f {
f(page)
}
});
} }
} }
#[inline(always)]
pub(crate) fn run_actions_after_prepare_body(page: &mut Page) {
run_actions((ACTION_AFTER_PREPARE_BODY, None), |action| {
action_ref::<AfterPrepareBody>(&**action).run(page)
});
}

View file

@ -3,29 +3,22 @@ use crate::prelude::*;
use super::FnActionPage; use super::FnActionPage;
pub struct BeforePrepareBody { pub struct BeforePrepareBody {
action: Option<FnActionPage>, f: Option<FnActionPage>,
weight: Weight, weight: Weight,
} }
impl_handle!(ACTION_BEFORE_PREPARE_BODY for BeforePrepareBody); impl_handle!(ACTION_BEFORE_PREPARE_BODY for BeforePrepareBody);
impl ActionTrait for BeforePrepareBody { impl ActionTrait for BeforePrepareBody {
fn new() -> Self {
BeforePrepareBody {
action: None,
weight: 0,
}
}
fn weight(&self) -> Weight { fn weight(&self) -> Weight {
self.weight self.weight
} }
} }
impl BeforePrepareBody { impl BeforePrepareBody {
pub fn with(action: FnActionPage) -> Self { pub fn with(f: FnActionPage) -> Self {
BeforePrepareBody { BeforePrepareBody {
action: Some(action), f: Some(f),
weight: 0, weight: 0,
} }
} }
@ -35,16 +28,12 @@ impl BeforePrepareBody {
self self
} }
pub(crate) fn run(&self, page: &mut Page) { #[inline(always)]
if let Some(action) = self.action { pub(crate) fn dispatch(page: &mut Page) {
action(page) dispatch_actions((ACTION_BEFORE_PREPARE_BODY, None, None), |action| {
} if let Some(f) = action_ref::<BeforePrepareBody>(&**action).f {
f(page)
}
});
} }
} }
#[inline(always)]
pub(crate) fn run_actions_before_prepare_body(page: &mut Page) {
run_actions((ACTION_BEFORE_PREPARE_BODY, None), |action| {
action_ref::<BeforePrepareBody>(&**action).run(page)
});
}

View file

@ -7,4 +7,4 @@ use list::ActionsList;
mod all; mod all;
pub(crate) use all::add_action; pub(crate) use all::add_action;
pub use all::run_actions; pub use all::dispatch_actions;

View file

@ -4,7 +4,7 @@ use crate::{Handle, LazyStatic};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::RwLock; use std::sync::RwLock;
type KeyHandles = (Handle, Option<Handle>); type KeyHandles = (Handle, Option<Handle>, Option<String>);
// Registered actions. // Registered actions.
static ACTIONS: LazyStatic<RwLock<HashMap<KeyHandles, ActionsList>>> = static ACTIONS: LazyStatic<RwLock<HashMap<KeyHandles, ActionsList>>> =
@ -12,7 +12,11 @@ static ACTIONS: LazyStatic<RwLock<HashMap<KeyHandles, ActionsList>>> =
pub fn add_action(action: Action) { pub fn add_action(action: Action) {
let mut actions = ACTIONS.write().unwrap(); let mut actions = ACTIONS.write().unwrap();
let action_handle = (action.handle(), action.referer_handle()); let action_handle = (
action.handle(),
action.referer_handle(),
action.referer_id(),
);
if let Some(list) = actions.get_mut(&action_handle) { if let Some(list) = actions.get_mut(&action_handle) {
list.add(action); list.add(action);
} else { } else {
@ -20,7 +24,7 @@ pub fn add_action(action: Action) {
} }
} }
pub fn run_actions<B, F>(action_handle: (Handle, Option<Handle>), f: F) pub fn dispatch_actions<B, F>(action_handle: (Handle, Option<Handle>, Option<String>), f: F)
where where
F: FnMut(&Action) -> B, F: FnMut(&Action) -> B,
{ {

View file

@ -7,14 +7,14 @@ pub trait ActionBase: Any {
} }
pub trait ActionTrait: ActionBase + HasHandle + Send + Sync { pub trait ActionTrait: ActionBase + HasHandle + Send + Sync {
fn new() -> Self
where
Self: Sized;
fn referer_handle(&self) -> Option<Handle> { fn referer_handle(&self) -> Option<Handle> {
None None
} }
fn referer_id(&self) -> Option<String> {
None
}
fn weight(&self) -> Weight { fn weight(&self) -> Weight {
0 0
} }

View file

@ -1,5 +1,4 @@
use crate::base::action::component::run_actions_after_prepare_component; use crate::base::action;
use crate::base::action::component::run_actions_before_prepare_component;
use crate::core::component::Context; use crate::core::component::Context;
use crate::html::{html, Markup, PrepareMarkup}; use crate::html::{html, Markup, PrepareMarkup};
use crate::{util, HasHandle, Weight}; use crate::{util, HasHandle, Weight};
@ -62,8 +61,12 @@ impl<C: ComponentTrait> ComponentBase for C {
cx.theme().before_prepare_component(self, cx); cx.theme().before_prepare_component(self, cx);
// Acciones de los módulos antes de preparar el componente. // Acciones de los módulos antes de preparar el componente.
run_actions_before_prepare_component(self, cx); action::component::BeforePrepareComponent::dispatch(self, cx, None);
if let Some(id) = self.id() {
action::component::BeforePrepareComponent::dispatch(self, cx, Some(id));
}
// Renderiza el componente.
let markup = match cx.theme().render_component(self, cx) { let markup = match cx.theme().render_component(self, cx) {
Some(html) => html, Some(html) => html,
None => match self.prepare_component(cx) { None => match self.prepare_component(cx) {
@ -80,7 +83,10 @@ impl<C: ComponentTrait> ComponentBase for C {
cx.theme().after_prepare_component(self, cx); cx.theme().after_prepare_component(self, cx);
// Acciones de los módulos después de preparar el componente. // Acciones de los módulos después de preparar el componente.
run_actions_after_prepare_component(self, cx); action::component::AfterPrepareComponent::dispatch(self, cx, None);
if let Some(id) = self.id() {
action::component::AfterPrepareComponent::dispatch(self, cx, Some(id));
}
markup markup
} else { } else {

View file

@ -1,4 +1,4 @@
use crate::base::action::page::{run_actions_after_prepare_body, run_actions_before_prepare_body}; use crate::base::action;
use crate::core::component::{ArcComponent, ArcComponents as RegionComponents, ComponentTrait}; use crate::core::component::{ArcComponent, ArcComponents as RegionComponents, ComponentTrait};
use crate::core::component::{Context, ContextOp}; use crate::core::component::{Context, ContextOp};
use crate::core::theme::ComponentsRegions; use crate::core::theme::ComponentsRegions;
@ -150,21 +150,21 @@ impl Page {
// Page RENDER. // Page RENDER.
pub fn render(&mut self) -> ResultPage<Markup, FatalError> { pub fn render(&mut self) -> ResultPage<Markup, FatalError> {
// Module actions before preparing the page body.
run_actions_before_prepare_body(self);
// Theme actions before preparing the page body. // Theme actions before preparing the page body.
self.context.theme().before_prepare_body(self); self.context.theme().before_prepare_body(self);
// Module actions before preparing the page body.
action::page::BeforePrepareBody::dispatch(self);
// Prepare page body. // Prepare page body.
let body = self.context.theme().prepare_body(self); let body = self.context.theme().prepare_body(self);
// Module actions after preparing the page body.
run_actions_after_prepare_body(self);
// Theme actions after preparing the page body. // Theme actions after preparing the page body.
self.context.theme().after_prepare_body(self); self.context.theme().after_prepare_body(self);
// Module actions after preparing the page body.
action::page::AfterPrepareBody::dispatch(self);
// Prepare page head. // Prepare page head.
let head = self.context.theme().prepare_head(self); let head = self.context.theme().prepare_head(self);