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 677)
674fn demo_dialog() {
675    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
676    let provider = HelloConfig::new();
677    let mut engine = DialogEngine::new(provider);
678    let mut buffer = TileBuffer::new(20, 18);
679
680    // "Greetings, young hero!" + DONE
681    let text: &[u8] = b"Greetings, young hero!";
682    let mut full = text.to_vec();
683    full.push(0xFF); // DONE
684
685    engine.open_dialog(&full);
686    while engine.is_active() {
687        engine.update(&mut buffer);
688    }
689
690    print!("║ Merlin: \"");
691    for i in 0..20usize {
692        let t = buffer.tiles[i].tile_id;
693        if (0x20..=0x7E).contains(&t) {
694            print!("{}", t as u8 as char);
695        }
696    }
697    println!("\"");
698    println!("╚══════════════════════════════════════════╝");
699}
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 685)
674fn demo_dialog() {
675    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
676    let provider = HelloConfig::new();
677    let mut engine = DialogEngine::new(provider);
678    let mut buffer = TileBuffer::new(20, 18);
679
680    // "Greetings, young hero!" + DONE
681    let text: &[u8] = b"Greetings, young hero!";
682    let mut full = text.to_vec();
683    full.push(0xFF); // DONE
684
685    engine.open_dialog(&full);
686    while engine.is_active() {
687        engine.update(&mut buffer);
688    }
689
690    print!("║ Merlin: \"");
691    for i in 0..20usize {
692        let t = buffer.tiles[i].tile_id;
693        if (0x20..=0x7E).contains(&t) {
694            print!("{}", t as u8 as char);
695        }
696    }
697    println!("\"");
698    println!("╚══════════════════════════════════════════╝");
699}
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 687)
674fn demo_dialog() {
675    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
676    let provider = HelloConfig::new();
677    let mut engine = DialogEngine::new(provider);
678    let mut buffer = TileBuffer::new(20, 18);
679
680    // "Greetings, young hero!" + DONE
681    let text: &[u8] = b"Greetings, young hero!";
682    let mut full = text.to_vec();
683    full.push(0xFF); // DONE
684
685    engine.open_dialog(&full);
686    while engine.is_active() {
687        engine.update(&mut buffer);
688    }
689
690    print!("║ Merlin: \"");
691    for i in 0..20usize {
692        let t = buffer.tiles[i].tile_id;
693        if (0x20..=0x7E).contains(&t) {
694            print!("{}", t as u8 as char);
695        }
696    }
697    println!("\"");
698    println!("╚══════════════════════════════════════════╝");
699}
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 686)
674fn demo_dialog() {
675    println!("\n╔══ NPC DIALOG ═══════════════════════════╗");
676    let provider = HelloConfig::new();
677    let mut engine = DialogEngine::new(provider);
678    let mut buffer = TileBuffer::new(20, 18);
679
680    // "Greetings, young hero!" + DONE
681    let text: &[u8] = b"Greetings, young hero!";
682    let mut full = text.to_vec();
683    full.push(0xFF); // DONE
684
685    engine.open_dialog(&full);
686    while engine.is_active() {
687        engine.update(&mut buffer);
688    }
689
690    print!("║ Merlin: \"");
691    for i in 0..20usize {
692        let t = buffer.tiles[i].tile_id;
693        if (0x20..=0x7E).contains(&t) {
694            print!("{}", t as u8 as char);
695        }
696    }
697    println!("\"");
698    println!("╚══════════════════════════════════════════╝");
699}

Auto Trait Implementations§

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.