Skip to main content

DialogEngine

Struct DialogEngine 

Source
pub struct DialogEngine<P: TextProvider> {
    pub provider: P,
    pub stream: Option<TextStream<P::Char>>,
    pub state: DialogState,
}
Expand description

A general-purpose dialog engine that drives text display one character per frame.

P is the TextProvider implementation that supplies the game’s character encoding and rendering logic.

§Usage

let provider = MyProvider::new();
let mut engine = DialogEngine::new(provider);
let mut buffer = TileBuffer::new(20, 18);

engine.open_dialog(&[0x48, 0x45, 0x4C, 0x4C, 0x4F]); // "HELLO"

while engine.is_active() {
    engine.update(&mut buffer); // one char per frame
}

engine.advance(); // close dialog

Fields§

§provider: P

The text provider (charmap, rendering, control codes).

§stream: Option<TextStream<P::Char>>

Active character stream, or None if no dialog is open.

§state: DialogState

Current dialog state.

Implementations§

Source§

impl<P: TextProvider> DialogEngine<P>

Source

pub fn new(provider: P) -> Self

Creates a new dialog engine with the given text provider.

Examples found in repository?
examples/hello_dotzuki.rs (line 463)
460fn demo_dialog() {
461    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
462    let provider = HelloConfig::new();
463    let mut engine = DialogEngine::new(provider);
464    let mut buffer = TileBuffer::new(20, 18);
465
466    // "Greetings, young hero!" + DONE
467    let text: &[u8] = b"Greetings, young hero!";
468    let mut full = text.to_vec();
469    full.push(0xFF); // DONE
470
471    engine.open_dialog(&full);
472    while engine.is_active() { engine.update(&mut buffer); }
473
474    print!("║ Merlin: \"");
475    for i in 0..20usize {
476        let t = buffer.tiles[i].tile_id;
477        if (0x20..=0x7E).contains(&t) { print!("{}", t as u8 as char); }
478    }
479    println!("\"");
480    println!("╚══════════════════════════════════════════╝");
481}
Source

pub fn open_dialog(&mut self, text: &[u8])

Opens a dialog with the given raw byte text.

The bytes are decoded via the provider’s TextProvider::decode_stream and the state is reset to the initial typing mode.

Examples found in repository?
examples/hello_dotzuki.rs (line 471)
460fn demo_dialog() {
461    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
462    let provider = HelloConfig::new();
463    let mut engine = DialogEngine::new(provider);
464    let mut buffer = TileBuffer::new(20, 18);
465
466    // "Greetings, young hero!" + DONE
467    let text: &[u8] = b"Greetings, young hero!";
468    let mut full = text.to_vec();
469    full.push(0xFF); // DONE
470
471    engine.open_dialog(&full);
472    while engine.is_active() { engine.update(&mut buffer); }
473
474    print!("║ Merlin: \"");
475    for i in 0..20usize {
476        let t = buffer.tiles[i].tile_id;
477        if (0x20..=0x7E).contains(&t) { print!("{}", t as u8 as char); }
478    }
479    println!("\"");
480    println!("╚══════════════════════════════════════════╝");
481}
Source

pub fn update(&mut self, buffer: &mut TileBuffer)

Processes one character from the current dialog stream.

Call this once per frame to achieve the classic typewriter effect. Control codes are dispatched to the provider’s TextProvider::process_control; printable characters are drawn via TextProvider::render_char.

If the engine is not in DialogMode::Typing, this call is a no-op. If the stream is exhausted or a Done control action is returned, the dialog state transitions to DialogMode::Done.

Examples found in repository?
examples/hello_dotzuki.rs (line 472)
460fn demo_dialog() {
461    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
462    let provider = HelloConfig::new();
463    let mut engine = DialogEngine::new(provider);
464    let mut buffer = TileBuffer::new(20, 18);
465
466    // "Greetings, young hero!" + DONE
467    let text: &[u8] = b"Greetings, young hero!";
468    let mut full = text.to_vec();
469    full.push(0xFF); // DONE
470
471    engine.open_dialog(&full);
472    while engine.is_active() { engine.update(&mut buffer); }
473
474    print!("║ Merlin: \"");
475    for i in 0..20usize {
476        let t = buffer.tiles[i].tile_id;
477        if (0x20..=0x7E).contains(&t) { print!("{}", t as u8 as char); }
478    }
479    println!("\"");
480    println!("╚══════════════════════════════════════════╝");
481}
Source

pub fn advance(&mut self)

Advances the dialog past the current page or closes it.

  • If paused, resumes typing.
  • If waiting for input or scrolling, resumes typing.
  • If the dialog is done, clears the stream and resets state (so [is_active] returns false).

Call this in response to the player pressing the A button.

Source

pub fn is_active(&self) -> bool

Returns true if a dialog is currently active.

A dialog is active when a stream is loaded and the mode is not DialogMode::Done.

Examples found in repository?
examples/hello_dotzuki.rs (line 472)
460fn demo_dialog() {
461    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
462    let provider = HelloConfig::new();
463    let mut engine = DialogEngine::new(provider);
464    let mut buffer = TileBuffer::new(20, 18);
465
466    // "Greetings, young hero!" + DONE
467    let text: &[u8] = b"Greetings, young hero!";
468    let mut full = text.to_vec();
469    full.push(0xFF); // DONE
470
471    engine.open_dialog(&full);
472    while engine.is_active() { engine.update(&mut buffer); }
473
474    print!("║ Merlin: \"");
475    for i in 0..20usize {
476        let t = buffer.tiles[i].tile_id;
477        if (0x20..=0x7E).contains(&t) { print!("{}", t as u8 as char); }
478    }
479    println!("\"");
480    println!("╚══════════════════════════════════════════╝");
481}

Auto Trait Implementations§

§

impl<P> Freeze for DialogEngine<P>
where P: Freeze,

§

impl<P> RefUnwindSafe for DialogEngine<P>

§

impl<P> Send for DialogEngine<P>
where P: Send, <P as TextProvider>::Char: Send,

§

impl<P> Sync for DialogEngine<P>
where P: Sync, <P as TextProvider>::Char: Sync,

§

impl<P> Unpin for DialogEngine<P>
where P: Unpin, <P as TextProvider>::Char: Unpin,

§

impl<P> UnsafeUnpin for DialogEngine<P>
where P: UnsafeUnpin,

§

impl<P> UnwindSafe for DialogEngine<P>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.