altair_emu/src/card.rs

101 lines
2.5 KiB
Rust
Raw Normal View History

2024-02-03 22:22:39 -06:00
use anyhow::anyhow;
use eframe::egui::Ui;
pub struct Type {
name: &'static str,
new: fn(settings: ron::Value) -> anyhow::Result<Box<dyn Card>>,
settings_ui: fn(settings: ron::Value) -> anyhow::Result<Box<dyn SettingsUi>>,
2024-02-07 11:18:38 -06:00
default_settings: fn() -> String,
2024-02-03 22:22:39 -06:00
}
impl Type {
pub const fn new<T: Card + 'static>(name: &'static str) -> Self {
Self {
name,
new: T::new_dyn,
settings_ui: T::settings_ui_dyn,
2024-02-07 11:18:38 -06:00
default_settings: T::default_settings,
2024-02-03 22:22:39 -06:00
}
}
2024-02-07 11:18:38 -06:00
pub fn new_card(&self, settings: ron::Value) -> anyhow::Result<Box<dyn Card>> {
2024-02-03 22:22:39 -06:00
(self.new)(settings)
}
2024-02-07 11:18:38 -06:00
pub fn settings_ui(&self, settings: ron::Value) -> anyhow::Result<Box<dyn SettingsUi>> {
2024-02-03 22:22:39 -06:00
(self.settings_ui)(settings)
}
2024-02-07 11:18:38 -06:00
pub fn default_settings(&self) -> String {
(self.default_settings)()
}
pub fn get(name: &str) -> anyhow::Result<&'static Self> {
inventory::iter::<Type>
.into_iter()
.find(|card_type| card_type.name == name)
.ok_or_else(|| anyhow!("Invalid card type {}", name))
}
pub fn name(&self) -> &'static str {
self.name
}
2024-02-03 22:22:39 -06:00
}
inventory::collect!(Type);
2023-08-10 13:58:34 -05:00
pub trait Card {
2024-02-03 22:22:39 -06:00
fn new(_settings: ron::Value) -> anyhow::Result<Self>
where
Self: Sized;
2024-01-31 15:23:48 -06:00
#[allow(clippy::new_ret_no_self)]
2024-02-03 22:22:39 -06:00
fn new_dyn(settings: ron::Value) -> anyhow::Result<Box<dyn Card>>
where
Self: Sized + 'static,
{
let card = Self::new(settings)?;
Ok(Box::new(card))
}
2023-08-10 13:58:34 -05:00
2024-02-07 11:18:38 -06:00
fn default_settings() -> String
where
Self: Sized;
2023-08-10 13:58:34 -05:00
fn read_mem(&mut self, _address: u16) -> Option<u8> {
None
}
fn write_mem(&mut self, _address: u16, _data: u8) -> Option<()> {
None
}
fn read_io(&mut self, _address: u8) -> Option<u8> {
None
}
fn write_io(&mut self, _address: u8, _data: u8) -> Option<()> {
None
}
2024-02-03 22:22:39 -06:00
fn settings_ui(_settings: ron::Value) -> anyhow::Result<impl SettingsUi>
where
Self: Sized;
#[allow(clippy::settings_ui_ret_no_self)]
fn settings_ui_dyn(settings: ron::Value) -> anyhow::Result<Box<dyn SettingsUi>>
where
Self: Sized + 'static,
{
let settings_ui = Self::settings_ui(settings)?;
Ok(Box::new(settings_ui))
}
}
pub trait SettingsUi {
fn draw_ui(&mut self, ui: &mut Ui);
2023-08-10 13:58:34 -05:00
fn serialize_settings(&self) -> String;
}
2024-02-03 22:22:39 -06:00
#[macro_export]
macro_rules! register {
($typ: ty, $name: literal) => {
inventory::submit!($crate::card::Type::new::<$typ>($name));
};
}