Add the basic observer pattern

This commit is contained in:
LI Qing 2023-03-28 01:11:20 -04:00 committed by Tate, Hongliang Tian
parent 0b15be894b
commit db449d4697
9 changed files with 71 additions and 12 deletions

View File

@ -0,0 +1,2 @@
/// A trait to represent any events.
pub trait Events: Copy + Clone + Send + Sync + 'static {}

View File

@ -0,0 +1,7 @@
mod events;
mod observer;
mod subject;
pub use self::events::Events;
pub use self::observer::Observer;
pub use self::subject::Subject;

View File

@ -0,0 +1,11 @@
use super::Events;
/// An observer for events.
///
/// In a sense, event observers are just a fancy form of callback functions.
/// An observer's `on_events` methods are supposed to be called when
/// some events that are interesting to the observer happen.
pub trait Observer<E: Events>: Send + Sync {
/// Notify the observer that some interesting events happen.
fn on_events(&self, events: &E);
}

View File

@ -0,0 +1,43 @@
use crate::prelude::*;
use super::{Events, Observer};
/// A Subject notify interesting events to registered observers.
pub struct Subject<E: Events> {
observers: Mutex<Vec<Weak<dyn Observer<E>>>>,
}
impl<E: Events> Subject<E> {
pub fn new() -> Self {
Self {
observers: Mutex::new(Vec::new()),
}
}
/// Register an observer.
pub fn register_observer(&self, observer: Weak<dyn Observer<E>>) {
let mut observers = self.observers.lock();
observers.push(observer);
}
/// Unregister an observer.
pub fn unregister_observer(&self, observer: Weak<dyn Observer<E>>) {
let mut observers = self.observers.lock();
observers.retain(|e| !Weak::ptr_eq(&e, &observer));
}
/// Notify events to all registered observers.
/// It will remove the observers which have been freed.
pub fn notify_observers(&self, events: &E) {
let mut observers = self.observers.lock();
let mut idx = 0;
while idx < observers.len() {
if let Some(observer) = observers[idx].upgrade() {
observer.on_events(events);
idx += 1;
} else {
observers.remove(idx);
}
}
}
}

View File

@ -1,8 +1,8 @@
use crate::fs::utils::{IoEvents, IoctlCmd, Metadata, SeekFrom};
use crate::prelude::*;
use crate::tty::get_n_tty;
use core::any::Any;
use crate::fs::utils::{IoEvents, IoctlCmd, Metadata, SeekFrom};
use core::any::Any;
/// The basic operations defined on a file
pub trait File: Send + Sync + Any {

View File

@ -1,6 +1,4 @@
use crate::prelude::*;
bitflags! {
crate::bitflags! {
pub struct IoEvents: u32 {
const POLLIN = 0x0001;
const POLLPRI = 0x0002;

View File

@ -4,11 +4,11 @@ pub use access_mode::AccessMode;
pub use creation_flags::CreationFlags;
pub use dentry_cache::Dentry;
pub use dirent_visitor::DirentVisitor;
pub use events::IoEvents;
pub use fcntl::FcntlCmd;
pub use file_creation_mask::FileCreationMask;
pub use fs::{FileSystem, SuperBlock};
pub use inode::{Inode, InodeMode, InodeType, Metadata};
pub use io_events::IoEvents;
pub use ioctl::IoctlCmd;
pub use page_cache::PageCacheManager;
pub use poll::{c_nfds, c_pollfd, PollFd};
@ -19,11 +19,11 @@ mod access_mode;
mod creation_flags;
mod dentry_cache;
mod dirent_visitor;
mod events;
mod fcntl;
mod file_creation_mask;
mod fs;
mod inode;
mod io_events;
mod ioctl;
mod page_cache;
mod poll;

View File

@ -31,6 +31,7 @@ extern crate controlled;
pub mod driver;
pub mod error;
pub mod events;
pub mod fs;
pub mod prelude;
mod process;

View File

@ -1,10 +1,7 @@
use self::line_discipline::LineDiscipline;
use crate::driver::tty::TtyDriver;
use crate::fs::utils::{InodeMode, InodeType, Metadata};
use crate::fs::{
file_handle::File,
utils::{IoEvents, IoctlCmd},
};
use crate::fs::utils::{InodeMode, InodeType, IoEvents, Metadata};
use crate::fs::{file_handle::File, utils::IoctlCmd};
use crate::prelude::*;
use crate::process::{process_table, Pgid};
use crate::util::{read_val_from_user, write_val_to_user};