use super::traits::*;
use std::sync::*;
pub struct ReleasableNotifiable {
keep_alive: bool,
target: Arc<Mutex<Option<Arc<dyn Notifiable>>>>
}
impl ReleasableNotifiable {
pub fn new(target: Arc<dyn Notifiable>) -> ReleasableNotifiable {
ReleasableNotifiable {
keep_alive: false,
target: Arc::new(Mutex::new(Some(target)))
}
}
pub fn mark_as_changed(&self) -> bool {
let target = self.target.lock().unwrap().clone();
if let Some(ref target) = target {
target.mark_as_changed();
true
} else {
false
}
}
pub fn is_in_use(&self) -> bool {
self.target.lock().unwrap().is_some()
}
pub fn clone_as_owned(&self) -> ReleasableNotifiable {
ReleasableNotifiable {
keep_alive: self.keep_alive,
target: Arc::clone(&self.target)
}
}
pub fn clone_for_inspection(&self) -> ReleasableNotifiable {
ReleasableNotifiable {
keep_alive: true,
target: Arc::clone(&self.target)
}
}
}
impl Releasable for ReleasableNotifiable {
fn done(&mut self) {
let mut target = self.target.lock().unwrap();
*target = None;
}
fn keep_alive(&mut self) {
self.keep_alive = true;
}
}
impl Notifiable for ReleasableNotifiable {
fn mark_as_changed(&self) {
let target = {
let target = self.target.lock().unwrap();
target.clone()
};
if let Some(target) = target {
target.mark_as_changed();
}
}
}
impl Drop for ReleasableNotifiable {
fn drop(&mut self) {
if !self.keep_alive {
self.done();
}
}
}
impl Releasable for Vec<Box<dyn Releasable>> {
fn done(&mut self) {
for item in self.iter_mut() {
item.done();
}
}
fn keep_alive(&mut self) {
for item in self.iter_mut() {
item.keep_alive();
}
}
}