Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generics programming using soa-derive #66

Open
Alexandre425 opened this issue May 7, 2024 · 3 comments
Open

Generics programming using soa-derive #66

Alexandre425 opened this issue May 7, 2024 · 3 comments

Comments

@Alexandre425
Copy link

Hi, apologies for not being able to infer this from the documentation and code, I am not very experienced with these topics. Also, sorry if I get any terms wrong, either way, my question is the following:

Say I have a generic struct that is meant to include various types of SoAs. What trait bounds am I meant to use? Should T be a Cheese or a CheeseVec?

pub struct SparseSet<T: ?> {
    dense: Vec<EntID>,
    sparse: Vec<u32>,
    data: ?,
}

From my understanding of the documentation, you are meant to apply the trait bound StructOfArray, making T a CheeseVec. However, that trait does not implement the usual methods (insert, pop, etc.), which would mean I can't do generic implementations. Is that the case, or did I miss something?

If T is a SoA, how do I get the original type, for declaring function parameter types? For example, the function get makes use of the sparse array to determine if an entity exists, after which it's meant to return the associated data, in this case a Cheese. What should ? be here, i.e. how do I get Cheese from CheeseVec in a generic way?

/// Gets the data associated with the entity from the set
pub fn get(&self, ent_id: EntID) -> Result<&?, Error> {
    self.ent_exists(ent_id)
        .then(|| &self.data[self.sparse[ent_id] as usize])
        .ok_or(Error::EntityNotInSet)
}

Thank you.

@Alexandre425 Alexandre425 changed the title Generics programming using SOA Generics programming using soa-derive May 7, 2024
@Alexandre425
Copy link
Author

I made some progress in realizing the type refers to the derived CheeseVec, and so my implementation now looks like this:

pub struct SparseSet<T: StructOfArray> {
    dense: Vec<EntID>,
    sparse: Vec<u32>,
    data: <T as StructOfArray>::Type,
}

However, this still will not allow me to have generic implementations, as the following errors:

pub fn new() -> Self {
    Self {
        dense: Vec::new(),
        sparse: Vec::new(),
        data: <T as StructOfArray>::Type::new(),
    }
}

error[E0599]: no function or associated item named new found for associated type <T as StructOfArray>::Type in the current scope

Do I have any alternatives? Any trait that implements the methods I need, so that I can have generic implementations?

@Luthaf
Copy link
Member

Luthaf commented May 8, 2024

Hey! I never used this code in a generic context, so I'm not sure if there is a workaround for the lack of associated methods.

StructOfArray::Type was added by @mikialex who wanted to do something similar in #24/#25. Maybe they have more idea about how to achieve this?

@Alexandre425
Copy link
Author

I see, I did find that PR, that commit was what helped me figure out part of it. If @mikialex can let me know if they've ever done generic implementations using their contribution, that would be really helpful. Otherwise I suppose I will look for an alternative, macros perhaps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants