Skip to content

Instantly share code, notes, and snippets.

@TuckerBMorgan
Created April 2, 2022 20:05
Show Gist options
  • Select an option

  • Save TuckerBMorgan/c1ecb110edecc4cdb28ed8a5678287fc to your computer and use it in GitHub Desktop.

Select an option

Save TuckerBMorgan/c1ecb110edecc4cdb28ed8a5678287fc to your computer and use it in GitHub Desktop.
Component object safe error
use cgmath::*;
use crate::*;
use std::fmt::Debug;
use serde::{Serialize, Deserialize};
#[derive(Hash, Eq, PartialEq, Copy, Clone, Serialize, Deserialize, Debug)]
#[repr(u64)]
pub enum ComponentType {
TransformComponent = 1,//The first one needs to be 1
}
//This is the trait that I want all components to implement
pub trait Component<'a> : Debug + Deserialize<'a> + Serialize {
fn component_type(&self) -> ComponentType;
}
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct TransformComponent {
pub transform: Matrix4<f32>
}
impl TransformComponent {
pub fn new(transform: Matrix4<f32>) -> TransformComponent {
TransformComponent {
transform
}
}
}
impl<'a> Component<'a> for TransformComponent {
fn component_type(&self) -> ComponentType {
return ComponentType::TransformComponent;
}
}
//The struct that all components with live inside
#[derive(Serialize, Deserialize, PartialEq, Debug, Default)]
pub struct World<'a> {
pub frame_number: usize,
//and entity it just a EntityId(a defaultkey) and component_mask, which is just a bitmask
//stating which components they have
pub entities: SlotMap<DefaultKey, Entity>,
//This array should be the place where all components are kept, reguardless of their type
pub components: HashMap<ComponentType, SecondaryMap<DefaultKey, Box<dyn Component<'a>>>>,
pub input: u8,
pub is_moving: bool,
pub desired_x: u32,
pub desired_y: u32
}
impl<'a> World {
pub fn add_component(&mut self, entity: EntityId, component: Box<dyn Component<'a>>) {
if self.entities.contains_key(entity) {
if self.components.contains_key(&component.component_type()) == false {
self.components.insert(component.component_type(), SecondaryMap::new());
}
let mut component_list = self.components.get_mut(&component.component_type());
let actual = component_list.as_mut().unwrap();
if actual.contains_key(entity) {
panic!("Tried to two of the same component to a entity");
}
//We do it before as component gets moved when we insert
//TODO: move this up a little early so we can use this as our bail condition
self.entities[entity].component_mask |= component.component_type() as u64;
actual.insert(entity, component);
}
else {
panic!("Tried to add a component to an entity that does not exists");
}
}
}
/*
error[E0038]: the trait `component::Component` cannot be made into an object
--> C:\Users\Tucker\source\agma\shared_code\src\world.rs:28:73
|
28 | pub components: HashMap<ComponentType, SecondaryMap<DefaultKey, Box<dyn Component<'a>>>>,
| ^^^^^^^^^^^^^^^^^ `component::Component` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> C:\Users\Tucker\source\agma\shared_code\src\component.rs:9:35
|
9 | pub trait Component<'a> : Debug + Deserialize<'a> + Serialize {
| --------- ^^^^^^^^^^^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
|
::: C:\Users\Tucker\.cargo\registry\src\github.com-1ecc6299db9ec823\serde-1.0.136\src\ser\mod.rs:247:8
|
247 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
| ^^^^^^^^^ ...because method `serialize` has generic type parameters
= help: consider moving `serialize` to another trait
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment