1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
// MIT/Apache2 License
use super::{Completer, Directive};
use orphan_crippler::Sender;
use std::{fmt::Debug, num::NonZeroUsize};
/// This object dictates what the `BreadThread` will do, exactly.
pub trait Controller {
/// The type representing a directive for this controller. Essentially, this represents something that tells
/// the controller what to do.
type Directive: Directive;
/// The type representing a thread-safe handle to this controller's event mechanism.
type DirectiveAdaptor: DirectiveAdaptor<Self::Directive> + Send + 'static;
/// The error type of the loop cycle.
type Error: Debug;
/// The type representing an event that may be produced by the loop cycle.
type Event;
/// The collection type used to tell how we should add or remove pointers.
///
/// If the iterator's size is not exact, it may cause panics down the line.
type Pointers: IntoIterator<Item = AddOrRemovePtr>;
/// Get a directive adaptor.
fn directive_adaptor(&self) -> Self::DirectiveAdaptor;
/// Run an event loop cycle. Do not process any directives during this time.
fn loop_cycle(&self) -> Result<LoopCycle<Self::Event, Self::Directive>, Self::Error>;
/// Process a directive and send the result down a `Sender`. Returns the list of pointers to add or remove
/// from the verified pointers list.
///
/// Since this may be used re-entrantly, it has to be immutable.
fn process_directive<C: Completer>(
&self,
directive: Self::Directive,
completer: &mut C,
) -> Self::Pointers;
}
/// Add or remove a pointer from the verified pointers list.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum AddOrRemovePtr {
/// Do nothing. This only exists so this enum can have a `Default` impl.
DoNothing,
/// Add a pointer to the verified list.
AddPtr(NonZeroUsize, usize),
/// Remove a pointer from the verified list.
RemovePtr(NonZeroUsize),
}
impl Default for AddOrRemovePtr {
#[inline]
fn default() -> Self {
AddOrRemovePtr::DoNothing
}
}
/// The result of a loop cycle.
pub enum LoopCycle<Event, Directive> {
/// Stop the loop.
Break,
/// We got an event.
Continue(Event),
/// We got a directive.
Directive(Sender<Directive>),
}
/// This object sends events to the main `Controller`.
pub trait DirectiveAdaptor<Directive> {
/// Send a directive over this `DirectiveAdaptor`.
fn send(&mut self, directive: Sender<Directive>);
}