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

Metadata #301

Closed
wants to merge 6 commits into from
Closed

Metadata #301

wants to merge 6 commits into from

Conversation

Aceeri
Copy link
Member

@Aceeri Aceeri commented Nov 15, 2017

Moves the wrapper storages into their own separate "observing" structures. This is a breaking change due to no default associated types, but I think it might be better for ergonomics.

Checks won't pass right now, still need to update the docs and such. Somewhat of a proof of concept right now.

fixes #232


This change is Reviewable

@WaDelma
Copy link
Member

WaDelma commented Nov 15, 2017

Tracking issue for associated type defaults rust-lang/rust#29661

@@ -3,14 +3,16 @@
//!
//! [sp]: https://slide-rs.github.io/specs-website/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't review this file yet

/// // ...
/// }
///
/// // Clears the tracked storage every frame with this system.
/// (&mut comps).open().1.clear_flags();
/// comps.find_mut::<Flagged>().clear_flags();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent with the above style

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed this

///
/// Useful for things like tracking modifications to components, storing sorted lists related
/// to the storage, etc.
pub trait Metadata<T>: Default {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you have a TrackedStorage, doesn't that allow to do basically 99% of the meta stuff you need?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorted lists could be useful as well, as well as wanting to use something other than TrackedStorage.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorted lists can be built using TrackedStorage, that's one of my main motivations for adding it.

///
/// Useful for if you are using a tuple metadata and don't want to index each
/// sub-metadata using `metadata.0`, `metadata.1`, etc. as well as helping with
/// modelling generic APIs where something needs a specific metadata structure from
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about that, since the type does not really have a logical meaning.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, it's probably a bit inefficient

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doubt it is that inefficient, all it does is forward to self.field which is very likely to be inlined.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, you're right, I misunderstood first. I think the identifier find confused me.

@@ -148,6 +150,62 @@ impl<T: Component> Drop for MaskedStorage<T> {
}
}

#[derive(Derivative)]
#[derivative(Default(bound = ""))]
/// Associates the component's storage with its metadata.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please place docs before attribs

#[derive(Derivative)]
#[derivative(Default(bound = ""))]
/// Associates the component's storage with its metadata.
pub struct WrappedStorage<T: Component> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why we need such a type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better for implementation, otherwise I'd have to repeat myself for every usage of get, get_mut, insert, remove, etc.

&self.data.wrapped.meta
}

pub fn find<M>(&self) -> &M
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why this is immutable-only?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a mutable version find_mut

@@ -118,6 +118,7 @@ where
/// impl Component for Comp {
/// // Will use `DenseVecStorage` by default.
/// type Storage = TrackedStorage<Self>;
/// type Metadata = ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So TrackedStorage doesn't work with Metadata?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could work, I just haven't ported it over like the FlaggedStorage yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should proceed until TrackedStorage is ported

Copy link
Member

@kvark kvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Aceeri , great work!

I don't have a good feel of the possible metadata use-cases here. Assuming there are some, moving that definition out is a great step for clarity.

Also, ideally, I'd like to not have to derive Metadata, since it involves more magic code for us.

};

let count = field.iter().count();
let name_list = (0..count).map(|_| name).cloned().collect::<Vec<_>>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would vec![name; count] work instead?

@@ -1,5 +1,6 @@
#![deny(missing_docs)]
//#![deny(missing_docs)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason this is commented out?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just commented it out because I was removing/adding different structures often, I'll uncomment and document stuff once I figure out the final design for it.

@@ -216,10 +220,10 @@ pub use shred::{Dispatcher, DispatcherBuilder, Fetch, FetchId, FetchIdMut, Fetch
pub use shred::AsyncDispatcher;

pub use storage::{BTreeStorage, Change, ChangeEvents, DenseVecStorage, DistinctStorage, Entry,
FlaggedStorage, HashMapStorage, InsertResult, MaskedStorage, NormalRestriction,
Flagged, HashMapStorage, HasMeta, InsertResult, MaskedStorage, Metadata, NormalRestriction,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uh, that formatting doesn't work good for lots of uses


use Index;

/// Observes interactions with the component's storage and stores state alongside it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Metadata is too broad for this. Perhaps, something like Hook would do better? Or maybe Observer.

/// a component.
pub trait HasMeta<M> {
/// Immutably gets the sub-metadata.
fn find(&self) -> &M;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we rename the methods to meta and meta_mut? Will need to be adjusted if Metadata is renamed too.

/// sub-metadata using `metadata.0`, `metadata.1`, etc. as well as helping with
/// modelling generic APIs where something needs a specific metadata structure from
/// a component.
pub trait HasMeta<M> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, wouldn't this effectively be AsRef + AsMut?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose so yes, I was initially worried about it being confusing that you got the inner portions through .as_ref() but I guess that doesn't matter for a majority of usecases anyways.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, we kind of need this, I'm changing it very slightly though so it isn't really identical to AsRef/AsMut anymore.

@@ -401,6 +473,19 @@ where
data: &mut self.data,
}
}

/*
pub fn meta_mut(&mut self) -> &mut T::Metadata {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason this is commented out?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oop, that was a mistake, I wanted to make sure I changed most of the documentation to use find::<T>();.

@@ -118,6 +118,7 @@ where
/// impl Component for Comp {
/// // Will use `DenseVecStorage` by default.
/// type Storage = TrackedStorage<Self>;
/// type Metadata = ();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should proceed until TrackedStorage is ported

@torkleyy
Copy link
Member

I think it would be sufficient if there would be three "levels" for observing:

  • flagged
  • tracked
  • changed (meaning the tracked would only check insertions, changed stuff moved out)

where each item includes the information provided by the former. If there's anything we can't do with this, please tell me.

@torkleyy torkleyy mentioned this pull request Dec 3, 2017
@Aceeri
Copy link
Member Author

Aceeri commented Dec 6, 2017

I'll close this, since I like the Tracked api and think it is going to work out the way we want.

@Aceeri Aceeri closed this Dec 6, 2017
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

Successfully merging this pull request may close these issues.

Metadata
4 participants