use crate::binding::interfaces::{BindingDirection, IReactiveBinding};
use crate::IViewFor;
use ferroui_system::{IDisposable, IObservable};
use std::cell::Cell;
use std::fmt;
use std::rc::Rc;
pub struct ReactiveBinding<V: IViewFor + ?Sized, T> {
view: Rc<V>,
changed: Rc<dyn IObservable<T>>,
direction: BindingDirection,
subscription: Rc<dyn IDisposable>,
disposed: Cell<bool>,
}
impl<V: IViewFor + ?Sized, T> ReactiveBinding<V, T> {
pub fn new(view: Rc<V>, changed: Rc<dyn IObservable<T>>, direction: BindingDirection, subscription: Rc<dyn IDisposable>) -> Rc<Self> {
Rc::new(Self { view, changed, direction, subscription, disposed: Cell::new(false) })
}
}
impl<V: IViewFor + ?Sized, T> IDisposable for ReactiveBinding<V, T> {
fn dispose(&self) {
if self.disposed.replace(true) {
return;
}
self.subscription.dispose();
}
}
impl<V: IViewFor + ?Sized, T> IReactiveBinding<V, T> for ReactiveBinding<V, T> {
fn view_model_expression(&self) -> Option<&str> {
None
}
fn view(&self) -> &Rc<V> {
&self.view
}
fn view_expression(&self) -> Option<&str> {
None
}
fn changed(&self) -> Rc<dyn IObservable<T>> {
self.changed.clone()
}
fn direction(&self) -> BindingDirection {
self.direction
}
}
impl<V: IViewFor + ?Sized, T> fmt::Debug for ReactiveBinding<V, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ReactiveBinding: {:?} binding", self.direction)
}
}