get rid of "component id" business
This commit is contained in:
parent
f1a9f7dd23
commit
2ff0444854
|
@ -5,13 +5,15 @@ use std::os::raw::c_uint;
|
|||
use std::path::{PathBuf, Path};
|
||||
use std::pin::Pin;
|
||||
use std::io::Read;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct RetroComponentBase {
|
||||
retro: LibretroWrapper,
|
||||
libretro_path: PathBuf,
|
||||
|
||||
// TODO: control when things get added to this with lifetime constraints defined by implementers
|
||||
components: Vec<Pin<Box<dyn RetroComponent>>>,
|
||||
component_ptrs: Vec<(TypeId, *mut ())>,
|
||||
component_ptrs: HashMap<TypeId, *mut ()>,
|
||||
|
||||
// replaying env calls for late-added components
|
||||
cached_rom_path: Option<PathBuf>,
|
||||
|
@ -27,9 +29,6 @@ pub struct RetroComponentBase {
|
|||
cached_geometry: Option<GameGeometry>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct RetroComponentId(usize);
|
||||
|
||||
// TODO: replace with std::ops::ControlFlow when it becomes stable
|
||||
pub enum ControlFlow {
|
||||
Continue,
|
||||
|
@ -59,8 +58,8 @@ impl RetroComponentBase {
|
|||
let emu = RetroComponentBase {
|
||||
retro,
|
||||
libretro_path: core_path.as_ref().to_path_buf(),
|
||||
components: Vec::new(),
|
||||
component_ptrs: Vec::new(),
|
||||
components: Default::default(),
|
||||
component_ptrs: Default::default(),
|
||||
cached_rom_path: None,
|
||||
cached_pixel_format: None,
|
||||
cached_input_descriptors: None,
|
||||
|
@ -93,11 +92,14 @@ impl RetroComponentBase {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn register_component<T>(&mut self, comp: T) -> Result<RetroComponentId>
|
||||
pub fn register_component<T>(&mut self, comp: T) -> Result<()>
|
||||
where T: RetroComponent + Any
|
||||
{
|
||||
// TODO: match comp.schedule { BeforeInit, BeforeLoad, BeforeFirstRun, Anytime }
|
||||
let comp_type = comp.type_id();
|
||||
if self.component_ptrs.contains_key(&comp_type) {
|
||||
return Err(format!("A component of type {:?} has already been registered.", comp_type).into())
|
||||
}
|
||||
let mut comp = Box::pin(comp);
|
||||
let comp_ptr = comp.as_mut().get_mut() as *mut T;
|
||||
if let Some(cached) = &self.cached_pixel_format {
|
||||
|
@ -138,32 +140,27 @@ impl RetroComponentBase {
|
|||
}
|
||||
|
||||
self.components.push(comp);
|
||||
self.component_ptrs.push((comp_type, comp_ptr as *mut ()));
|
||||
self.component_ptrs.insert(comp_type, comp_ptr as *mut ());
|
||||
|
||||
Ok(RetroComponentId(self.components.len() - 1))
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn component_ref<T: RetroComponent>(&self, id: RetroComponentId) -> Result<&T> {
|
||||
self.component_ptr(id)
|
||||
pub fn component_ref<T: RetroComponent>(&self) -> Result<&T> {
|
||||
self.component_ptr()
|
||||
.map(|x| unsafe { &*x })
|
||||
}
|
||||
|
||||
pub fn component_mut<T: RetroComponent>(&mut self, id: RetroComponentId) -> Result<&mut T> {
|
||||
self.component_ptr(id)
|
||||
pub fn component_mut<T: RetroComponent>(&mut self) -> Result<&mut T> {
|
||||
self.component_ptr()
|
||||
.map(|x| unsafe { &mut *x })
|
||||
}
|
||||
|
||||
fn component_ptr<T: RetroComponent>(&self, id: RetroComponentId) -> Result<*mut T> {
|
||||
let (comp_type, comp_ptr) = self.component_ptrs.get(id.0)
|
||||
.ok_or_else(|| format!("Invalid ID given to component_mut: {:?}", id))?;
|
||||
if *comp_type == TypeId::of::<T>() {
|
||||
Ok(*comp_ptr as *mut T)
|
||||
} else {
|
||||
Err(format!(
|
||||
"Invalid downcast for {:?}: {:?} != {:?}",
|
||||
id, comp_type, TypeId::of::<T>()
|
||||
).into())
|
||||
}
|
||||
fn component_ptr<T: RetroComponent>(&self) -> Result<*mut T> {
|
||||
let id = TypeId::of::<T>();
|
||||
let comp_ptr = self.component_ptrs
|
||||
.get(&id)
|
||||
.ok_or_else(|| format!("No component of type {:?} has been registered.", id))?;
|
||||
Ok(*comp_ptr as *mut T)
|
||||
}
|
||||
|
||||
pub fn load_game(&mut self, rom: impl AsRef<Path>) -> Result<()> {
|
||||
|
|
|
@ -2,7 +2,7 @@ pub mod provided;
|
|||
pub mod base;
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::base::{RetroComponent, RetroComponentBase, RetroComponentId};
|
||||
pub use crate::base::{RetroComponent, RetroComponentBase};
|
||||
pub use ferretro_base::retro::constants::*;
|
||||
pub use ferretro_base::retro::wrapped_types::*;
|
||||
pub use ferretro_base::retro::wrapper::{RetroCallbacks, LibretroWrapper, LibretroWrapperAccess};
|
||||
|
|
Loading…
Reference in New Issue