refactor emulator to use generics with trait constraint

This commit is contained in:
Denis-Cosmin Nutiu 2024-11-24 21:50:19 +02:00
parent 668d2a18d5
commit 3c6aad798c
2 changed files with 9 additions and 8 deletions

View file

@ -3,7 +3,7 @@ use log::{debug, info};
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::path::{Path}; use std::path::{Path};
use crate::display::{Display, TerminalDisplay}; use crate::display::{Display};
const MEMORY_SIZE: usize = 4096; const MEMORY_SIZE: usize = 4096;
const NUMBER_OF_REGISTERS: usize = 16; const NUMBER_OF_REGISTERS: usize = 16;
@ -27,7 +27,7 @@ const FONT_SPRITES: [u8; 80] = [
]; ];
/// Emulator emulates the Chip8 CPU. /// Emulator emulates the Chip8 CPU.
pub struct Emulator { pub struct Emulator<D> where D: Display {
/// Memory represents the emulator's memory. /// Memory represents the emulator's memory.
memory: [u8; MEMORY_SIZE], memory: [u8; MEMORY_SIZE],
/// Registers holds the general purpose registers. /// Registers holds the general purpose registers.
@ -44,13 +44,13 @@ pub struct Emulator {
/// The stack pointer register. /// The stack pointer register.
stack_pointer: u8, stack_pointer: u8,
/// The display_data holds all the data associated with the display /// The display_data holds all the data associated with the display
display: Box<dyn Display> display: D
} }
impl Emulator { impl <D> Emulator<D> where D: Display {
/// Creates a new `Emulator` instance. /// Creates a new `Emulator` instance.
/// ///
pub fn new(display: Box<dyn Display>) -> Emulator { pub fn new(display: D) -> Emulator<D> {
let mut emulator = Emulator { let mut emulator = Emulator {
memory: [0; MEMORY_SIZE], memory: [0; MEMORY_SIZE],
registers: [0; NUMBER_OF_REGISTERS], registers: [0; NUMBER_OF_REGISTERS],
@ -113,11 +113,12 @@ impl Emulator {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::display::{TerminalDisplay};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
#[test] #[test]
fn test_load_font_data() { fn test_load_font_data() {
let emulator = Emulator::new(Box::from(TerminalDisplay::new())); let emulator = Emulator::new(TerminalDisplay::new());
assert_eq!(emulator.memory[0xf0..0xf0 + 80], FONT_SPRITES) assert_eq!(emulator.memory[0xf0..0xf0 + 80], FONT_SPRITES)
} }
@ -130,7 +131,7 @@ mod tests {
.expect("Failed to read test ROM"); .expect("Failed to read test ROM");
// Test // Test
let mut emulator = Emulator::new(Box::from(TerminalDisplay::new())); let mut emulator = Emulator::new(TerminalDisplay::new());
emulator emulator
.load_rom("roms/ibm-logo.ch8") .load_rom("roms/ibm-logo.ch8")
.expect("failed to load ROM"); .expect("failed to load ROM");

View file

@ -8,7 +8,7 @@ mod display;
fn main() -> Result<(), anyhow::Error> { fn main() -> Result<(), anyhow::Error> {
env_logger::init(); env_logger::init();
let mut emulator = Emulator::new(Box::from(TerminalDisplay::new())); let mut emulator = Emulator::new(TerminalDisplay::new());
emulator.emulate(String::from("./roms/ibm-logo.ch8"))?; emulator.emulate(String::from("./roms/ibm-logo.ch8"))?;