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

Add asset hot reloading #445

Merged
merged 14 commits into from Oct 24, 2017

Conversation

Projects
None yet
5 participants
@torkleyy
Member

torkleyy commented Oct 22, 2017

  • Adds a new resource to the world, Arc<rayon::ThreadPool> (or short: core::ThreadPool)
  • Adds WeakHandles
  • Automatically reloads assets (checked every second)

Fixes #266

Problems

  • If a file has been written only partially and the asset storage tries to load it, it fails :( I'm not sure if there's a check we can do Fixed by using fallback
@torkleyy

This comment has been minimized.

Show comment
Hide comment
@torkleyy

torkleyy Oct 22, 2017

Member

So as @Rhuagh pointed out, we need some sort of notification system, but I think it's better to do that in a follow-up.

Member

torkleyy commented Oct 22, 2017

So as @Rhuagh pointed out, we need some sort of notification system, but I think it's better to do that in a follow-up.

@torkleyy torkleyy requested review from Xaeroxe and Rhuagh Oct 22, 2017

struct Ron;
-impl Format<MeshAsset> for Ron {
+impl SimpleFormat<MeshAsset> for Ron {

This comment has been minimized.

@Rhuagh

Rhuagh Oct 22, 2017

Member

Good idea to simplify the simple formats :)

@Rhuagh

Rhuagh Oct 22, 2017

Member

Good idea to simplify the simple formats :)

amethyst_assets/src/loader.rs
@@ -25,6 +26,7 @@ impl Loader {
{
Loader {
directory: Arc::new(Directory::new(directory)),
+ hot_reload: true, // TODO: allow disabling

This comment has been minimized.

@Rhuagh

Rhuagh Oct 22, 2017

Member

Should we really default to true here? Even for the first iteration?

@Rhuagh

Rhuagh Oct 22, 2017

Member

Should we really default to true here? Even for the first iteration?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

No, I have to add configs to this; the param is just true to try it out.

@torkleyy

torkleyy Oct 23, 2017

Member

No, I have to add configs to this; the param is just true to try it out.

@omni-viral

I like the idea.
But I have concerns about overhead when you don't use the feature.
And I see it's hard to make all this feature-gated.

amethyst_renderer/src/formats/texture.rs
- ) -> Result<TextureData, BoxedErr> {
- imagefmt::bmp::read(&mut Cursor::new(source.load(&name)?), ColFmt::RGBA)
+ fn import(&self, bytes: Vec<u8>, options: TextureMetadata) -> Result<TextureData, BoxedErr> {
+ imagefmt::bmp::read(&mut Cursor::new(bytes), ColFmt::RGBA)

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

It's better to read BMP file directly into gpu visible memory.
But this can be addressed later. Just put a note, please.

@omni-viral

omni-viral Oct 23, 2017

Member

It's better to read BMP file directly into gpu visible memory.
But this can be addressed later. Just put a note, please.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Will do.

@torkleyy

torkleyy Oct 23, 2017

Member

Will do.

amethyst_assets/src/asset.rs
fn import(
&self,
name: String,
source: Arc<Source>,
options: Self::Options,
- ) -> Result<A::Data, BoxedErr>;
+ create_reload: bool,
+ ) -> Result<(A::Data, Option<Box<Reload<A>>>), BoxedErr>;

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

This result type looks sophisticated.
Maybe it's worth to make a structure.

@omni-viral

omni-viral Oct 23, 2017

Member

This result type looks sophisticated.
Maybe it's worth to make a structure.

+ source,
+ options,
+ ..
+ } = this;

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Can't you just write *self here?

@omni-viral

omni-viral Oct 23, 2017

Member

Can't you just write *self here?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

It seems to be an unsoundness w.r.t. the Box<Self> stuff.

@torkleyy

torkleyy Oct 23, 2017

Member

It seems to be an unsoundness w.r.t. the Box<Self> stuff.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

You mean that if you write *self here it will not compile?

@omni-viral

omni-viral Oct 23, 2017

Member

You mean that if you write *self here it will not compile?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Yep.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Weird.

+ /// The reload structure has metadata which allows the asset management
+ /// to reload assets if necessary (for hot reloading).
+ /// You should only create this if `create_reload` is `true`.
+ /// Also, the parameter is just a request, which means you can also return `None`.
fn import(
&self,
name: String,

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

name and options should be passed by reference to avoid unnecessary cloning.

@omni-viral

omni-viral Oct 23, 2017

Member

name and options should be passed by reference to avoid unnecessary cloning.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

And in SimpleFormat as well. Otherwise cloning will be necessary 😄

@omni-viral

omni-viral Oct 23, 2017

Member

And in SimpleFormat as well. Otherwise cloning will be necessary 😄

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

I'm aware of the fact that an allocation is not desirable, but we can't point to the stack in a multi-threaded system.

@torkleyy

torkleyy Oct 23, 2017

Member

I'm aware of the fact that an allocation is not desirable, but we can't point to the stack in a multi-threaded system.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

I don't follow. If you use those only locally in function (or nested function calls). It's perfectly ok to pass them as references. And if you need to save them for future-use (In returned Reload) you clone value and store it.

@omni-viral

omni-viral Oct 23, 2017

Member

I don't follow. If you use those only locally in function (or nested function calls). It's perfectly ok to pass them as references. And if you need to save them for future-use (In returned Reload) you clone value and store it.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Please point me to the exact location where I could just pass a reference.

@torkleyy

torkleyy Oct 23, 2017

Member

Please point me to the exact location where I could just pass a reference.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

name and options in Format::import and options in SimpleFormat.
And then in impl Reload for SingleFile you can reuse SingleFile value instead of creating new one

@omni-viral

omni-viral Oct 23, 2017

Member

name and options in Format::import and options in SimpleFormat.
And then in impl Reload for SingleFile you can reuse SingleFile value instead of creating new one

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

As I've explained, you can't do that.

@torkleyy

torkleyy Oct 23, 2017

Member

As I've explained, you can't do that.

+ ..
+ } = this;
+
+ format.import(path, source, options, true)

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Can't it ask not to create new Reload object and return self?

@omni-viral

omni-viral Oct 23, 2017

Member

Can't it ask not to create new Reload object and return self?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

No, imagine a GLTF file which points to other files; in case the GLTF file gets reloaded, new files might have been added which we also want to track.

@torkleyy

torkleyy Oct 23, 2017

Member

No, imagine a GLTF file which points to other files; in case the GLTF file gets reloaded, new files might have been added which we also want to track.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

I makes sense for multi file assets. But this is SingleFile.

@omni-viral

omni-viral Oct 23, 2017

Member

I makes sense for multi file assets. But this is SingleFile.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

So how would you do that?

@torkleyy

torkleyy Oct 23, 2017

Member

So how would you do that?

amethyst_assets/src/reload.rs
+ /// Returns the asset name.
+ fn name(&self) -> String;
+ /// Returns the format name.
+ fn format(&self) -> String;

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

All formats has it's name as associated &'static str. So you can contain and return &'static str.

@omni-viral

omni-viral Oct 23, 2017

Member

All formats has it's name as associated &'static str. So you can contain and return &'static str.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

I had this as &'static str first, but changed it back for an unknown reason. I'll try to change this later.

@torkleyy

torkleyy Oct 23, 2017

Member

I had this as &'static str first, but changed it back for an unknown reason. I'll try to change this later.

amethyst_assets/src/storage.rs
@@ -30,9 +33,11 @@ impl Allocator {
pub struct AssetStorage<A: Asset> {
assets: VecStorage<A>,
bitset: BitSet,
- handles: Vec<Handle<A>>,
+ handles: Vec<WeakHandle<A>>,

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

No need for using Weak inside AssetStorage

  • Upgrading Weak has more overhead than cloning Arc. There is possibly infinite loop with CAS.
  • You get nothing from Weak as you store simple u32 and you don't have to drop it asap to free some resource. No memory get freed until you drop last Weak.
  • And then you have to allocate new Arc after you finally drop Weak.

Using WeakHandle outside of AssetStorage may make some sense though.

@omni-viral

omni-viral Oct 23, 2017

Member

No need for using Weak inside AssetStorage

  • Upgrading Weak has more overhead than cloning Arc. There is possibly infinite loop with CAS.
  • You get nothing from Weak as you store simple u32 and you don't have to drop it asap to free some resource. No memory get freed until you drop last Weak.
  • And then you have to allocate new Arc after you finally drop Weak.

Using WeakHandle outside of AssetStorage may make some sense though.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

The biggest reason I used WeakHandle here is for consistency, since the AssetStorage does not in fact own a handle (logically). And for reloads it is indeed necessary.

@torkleyy

torkleyy Oct 23, 2017

Member

The biggest reason I used WeakHandle here is for consistency, since the AssetStorage does not in fact own a handle (logically). And for reloads it is indeed necessary.

amethyst_assets/src/storage.rs
- while let Some(i) = self.handles.iter().position(Handle::is_unused) {
- let old = self.handles.swap_remove(i);
- let id = i as u32;
+ while let Some(i) = self.handles.iter().position(Handle::is_unique) {

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

You shouldn't search from start each time.
Try this.

let mut iter = self.handles.iter();
let mut i = 0;
while let Some(next) = iter.by_ref().position(Handle::is_unique) {
    i += next;
@omni-viral

omni-viral Oct 23, 2017

Member

You shouldn't search from start each time.
Try this.

let mut iter = self.handles.iter();
let mut i = 0;
while let Some(next) = iter.by_ref().position(Handle::is_unique) {
    i += next;

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Sorry, I was being stupid during refactoring.

I'm not sure your solution works, but I'll change this. Anyway, I plan on changing that cleanup code as to make it more efficient.

@torkleyy

torkleyy Oct 23, 2017

Member

Sorry, I was being stupid during refactoring.

I'm not sure your solution works, but I'll change this. Anyway, I plan on changing that cleanup code as to make it more efficient.

- self.unused_handles.push(old);
+
+ // Can't reuse old handle here, because otherwise weak handles would still be valid.
+ // TODO: maybe just store u32?

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Can reuse again

@omni-viral

omni-viral Oct 23, 2017

Member

Can reuse again

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Sorry, I don't understand?

@torkleyy

torkleyy Oct 23, 2017

Member

Sorry, I don't understand?

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

You can reuse Handle. As it's not WeakHandle again.

@omni-viral

omni-viral Oct 23, 2017

Member

You can reuse Handle. As it's not WeakHandle again.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

I think what you're saying is that because I changed it back to Handle, I can reuse the handles again?

I don't think we'd want that, because:

  • Handle A gets allocated
  • Handle A has a downgraded version in a cache
  • Handle A gets dropped
  • Handle A gets added to the unused_handles queue
  • Another allocation is required; unused_handles gives us the "old" handle A
  • The cached value we stored before (using WeakHandle) is now valid again

That's why I added that comment and recreated the handle. Did a make a mistake in my reasoning?

@torkleyy

torkleyy Oct 23, 2017

Member

I think what you're saying is that because I changed it back to Handle, I can reuse the handles again?

I don't think we'd want that, because:

  • Handle A gets allocated
  • Handle A has a downgraded version in a cache
  • Handle A gets dropped
  • Handle A gets added to the unused_handles queue
  • Another allocation is required; unused_handles gives us the "old" handle A
  • The cached value we stored before (using WeakHandle) is now valid again

That's why I added that comment and recreated the handle. Did a make a mistake in my reasoning?

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Makes sense.

@omni-viral

omni-viral Oct 23, 2017

Member

Makes sense.

amethyst_assets/src/storage.rs
+ }
+
+ // Reload every seconds
+ // TODO: more configuration

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

You can add more details to TODO.
Configure timeout.
Configure automatic or only manual with special method in AssetStorage.

@omni-viral

omni-viral Oct 23, 2017

Member

You can add more details to TODO.
Configure timeout.
Configure automatic or only manual with special method in AssetStorage.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

I will add such a structure in this PR.

@torkleyy

torkleyy Oct 23, 2017

Member

I will add such a structure in this PR.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Cool!

amethyst_assets/src/storage.rs
- pub format: String,
- pub handle: Handle<A>,
- pub name: String,
+pub enum Processed<A: Asset> {

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

It pub necessary here?

@omni-viral

omni-viral Oct 23, 2017

Member

It pub necessary here?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Enums can't have private members.

@torkleyy

torkleyy Oct 23, 2017

Member

Enums can't have private members.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

I think I misunderstood your question. Yes, Processed needs to be pub, because Loader creates such a structure. It's not exported at crate root, though.

@torkleyy

torkleyy Oct 23, 2017

Member

I think I misunderstood your question. Yes, Processed needs to be pub, because Loader creates such a structure. It's not exported at crate root, though.

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Can you make it pub(crate) then?

@omni-viral

omni-viral Oct 23, 2017

Member

Can you make it pub(crate) then?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

There's no need for that and besides, I think that syntax is horrible. I try not to use it where possible.

@torkleyy

torkleyy Oct 23, 2017

Member

There's no need for that and besides, I think that syntax is horrible. I try not to use it where possible.

This comment has been minimized.

@Xaeroxe

Xaeroxe Oct 23, 2017

Member

Why? It's very straightforward and obvious. You don't need to look at other files to figure out it's not actually pub, and pub(crate) permits easy re-use of internal structures.

@Xaeroxe

Xaeroxe Oct 23, 2017

Member

Why? It's very straightforward and obvious. You don't need to look at other files to figure out it's not actually pub, and pub(crate) permits easy re-use of internal structures.

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Oct 23, 2017

Collaborator

So as @Rhuagh pointed out, we need some sort of notification system, but I think it's better to do that in a follow-up.

Events??? :P

Collaborator

jojolepro commented Oct 23, 2017

So as @Rhuagh pointed out, we need some sort of notification system, but I think it's better to do that in a follow-up.

Events??? :P

@torkleyy

This comment has been minimized.

Show comment
Hide comment
@torkleyy

torkleyy Oct 23, 2017

Member

@jojolepro Not really, more like watching a directory.

Member

torkleyy commented Oct 23, 2017

@jojolepro Not really, more like watching a directory.

@torkleyy torkleyy requested a review from Rhuagh Oct 23, 2017

amethyst_assets/src/reload.rs
+ /// The frame after calling this, all changed assets will be reloaded.
+ pub fn trigger(&mut self) {
+ let counter = match self.inner {
+ HotReloadStrategyInner::Trigger { counter } => counter.checked_add(1).unwrap_or(0),

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Just wrapping_add instead of checked_add and unwrap_or

@omni-viral

omni-viral Oct 23, 2017

Member

Just wrapping_add instead of checked_add and unwrap_or

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

That's what I've been searching for, thanks!

@torkleyy

torkleyy Oct 23, 2017

Member

That's what I've been searching for, thanks!

amethyst_assets/src/reload.rs
+ pub fn trigger(&mut self) {
+ let counter = match self.inner {
+ HotReloadStrategyInner::Trigger { counter } => counter.checked_add(1).unwrap_or(0),
+ _ => 0,

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

It shouldn't switch do another strategy.

@omni-viral

omni-viral Oct 23, 2017

Member

It shouldn't switch do another strategy.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

It probably shouldn't switch from Every.

@torkleyy

torkleyy Oct 23, 2017

Member

It probably shouldn't switch from Every.

+ source,
+ options,
+ ..
+ } = this;

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Weird.

+ /// The reload structure has metadata which allows the asset management
+ /// to reload assets if necessary (for hot reloading).
+ /// You should only create this if `create_reload` is `true`.
+ /// Also, the parameter is just a request, which means you can also return `None`.
fn import(
&self,
name: String,

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

name and options in Format::import and options in SimpleFormat.
And then in impl Reload for SingleFile you can reuse SingleFile value instead of creating new one

@omni-viral

omni-viral Oct 23, 2017

Member

name and options in Format::import and options in SimpleFormat.
And then in impl Reload for SingleFile you can reuse SingleFile value instead of creating new one

- self.unused_handles.push(old);
+
+ // Can't reuse old handle here, because otherwise weak handles would still be valid.
+ // TODO: maybe just store u32?

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

Makes sense.

@omni-viral

omni-viral Oct 23, 2017

Member

Makes sense.

amethyst_assets/src/storage.rs
+ fn hot_reload(&mut self, pool: &ThreadPool) {
+ let elapsed = self.last_reload.elapsed().as_secs();
+
+ if elapsed >= 1 {

This comment has been minimized.

@omni-viral

omni-viral Oct 23, 2017

Member

You've already checked that reload is required with strategy.

@omni-viral

omni-viral Oct 23, 2017

Member

You've already checked that reload is required with strategy.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Oops, forgot to remove the old code.

@torkleyy

torkleyy Oct 23, 2017

Member

Oops, forgot to remove the old code.

@Xaeroxe

Looks pretty good, although I'd be overall much happier if we provided a hot reload strategy that uses file system events to trigger hot reloading. Would probably help a lot for games with lots of file assets.

amethyst_assets/src/asset.rs
+/// This is a simplified version of `Format`, which doesn't give you as much as freedom,
+/// but in return is simpler to implement.
+/// All `SimpleFormat` types automatically implement `Format`.
+/// This format assumes that the asset name is the full path and also the only file.

This comment has been minimized.

@Xaeroxe

Xaeroxe Oct 23, 2017

Member

Minor grammar nit: Maybe this should end with "and the asset is only contained within one file."

@Xaeroxe

Xaeroxe Oct 23, 2017

Member

Minor grammar nit: Maybe this should end with "and the asset is only contained within one file."

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Makes sense, thanks.

@torkleyy

torkleyy Oct 23, 2017

Member

Makes sense, thanks.

amethyst_assets/src/storage.rs
- pub format: String,
- pub handle: Handle<A>,
- pub name: String,
+pub enum Processed<A: Asset> {

This comment has been minimized.

@Xaeroxe

Xaeroxe Oct 23, 2017

Member

Why? It's very straightforward and obvious. You don't need to look at other files to figure out it's not actually pub, and pub(crate) permits easy re-use of internal structures.

@Xaeroxe

Xaeroxe Oct 23, 2017

Member

Why? It's very straightforward and obvious. You don't need to look at other files to figure out it's not actually pub, and pub(crate) permits easy re-use of internal structures.

@torkleyy

This comment has been minimized.

Show comment
Hide comment
@torkleyy

torkleyy Oct 23, 2017

Member

Okay, all rebased, fixed, addressed and ready for a final review ;)

Member

torkleyy commented Oct 23, 2017

Okay, all rebased, fixed, addressed and ready for a final review ;)

@torkleyy

This comment has been minimized.

Show comment
Hide comment
@torkleyy

torkleyy Oct 23, 2017

Member

I'd be overall much happier if we provided a hot reload strategy that uses file system events to trigger hot reloading.

Me too, but I don't want to implement everything in one PR.

Member

torkleyy commented Oct 23, 2017

I'd be overall much happier if we provided a hot reload strategy that uses file system events to trigger hot reloading.

Me too, but I don't want to implement everything in one PR.

amethyst_assets/src/asset.rs
+ }
+}
+
+/// This is a simplified version of `Format`, which doesn't give you as much as freedom,

This comment has been minimized.

@Rhuagh

Rhuagh Oct 23, 2017

Member

"as much as freedom" should lose an "as".

@Rhuagh

Rhuagh Oct 23, 2017

Member

"as much as freedom" should lose an "as".

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

Oh ;P It's funny to see how crappy the docs I wrote are.

@torkleyy

torkleyy Oct 23, 2017

Member

Oh ;P It's funny to see how crappy the docs I wrote are.

+ /// If set to `true`, this `Loader` will ask formats to
+ /// generate "reload instructions" which *allow* reloading.
+ /// Calling `set_hot_reload(true)` does not actually enable
+ /// hot reloading; this is controlled by the `HotReloadStrategy`

This comment has been minimized.

@Rhuagh

Rhuagh Oct 23, 2017

Member

Ah, that's better :)

@Rhuagh

Rhuagh Oct 23, 2017

Member

Ah, that's better :)

amethyst_assets/src/reload.rs
+ }
+
+ /// No periodical hot-reloading is performed.
+ /// Instead, you can `trigger` it to check for changed assets

This comment has been minimized.

@Rhuagh

Rhuagh Oct 23, 2017

Member

This documentation seems to conflict with the documentation on trigger below.

@Rhuagh

Rhuagh Oct 23, 2017

Member

This documentation seems to conflict with the documentation on trigger below.

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

It does, and it's outdated.

@torkleyy

torkleyy Oct 23, 2017

Member

It does, and it's outdated.

-#[cfg(test)]
-#[cfg_attr(test, macro_use)]
-extern crate quickcheck;
+//#[cfg(test)]

This comment has been minimized.

@Rhuagh

Rhuagh Oct 23, 2017

Member

Why is this commented out ?

@Rhuagh

Rhuagh Oct 23, 2017

Member

Why is this commented out ?

This comment has been minimized.

@torkleyy

torkleyy Oct 23, 2017

Member

There's not a single usage in the whole crate, I'm not sure what @Aceeri did here.

@torkleyy

torkleyy Oct 23, 2017

Member

There's not a single usage in the whole crate, I'm not sure what @Aceeri did here.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 23, 2017

Member

Ah, seems he removed all the tests using it. Remove it altogether then I'd say.

@Rhuagh

Rhuagh Oct 23, 2017

Member

Ah, seems he removed all the tests using it. Remove it altogether then I'd say.

@Xaeroxe

LGTM, thanks!

amethyst_assets/src/reload.rs
Never,
}
+/// System for updating `HotReloadStrategy`.
+/// **NOTE:** You have to add this after all asset processing systems.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 23, 2017

Member

The RenderSystem which process Mesh and Texture will mess this up.

@Rhuagh

Rhuagh Oct 23, 2017

Member

The RenderSystem which process Mesh and Texture will mess this up.

bors bot added a commit that referenced this pull request Oct 24, 2017

Merge #446
446: Add frame_number to Time resource r=Xaeroxe a=Xaeroxe

This PR adds how many frames have been simulated to the Time resource, which may be helpful for execution order scheduling (such as what's needed in #445) and it also helps with timing for fixed framerate videogames.

Note: This won't overflow, if the game runs at 1000 FPS the u64 won't over flow for >500 million years.

2^64 / 1000 / 60 / 60 / 24 / 365  >500 million

@torkleyy torkleyy requested review from Rhuagh and omni-viral Oct 24, 2017

@omni-viral

Looks great!

@Xaeroxe

Xaeroxe approved these changes Oct 24, 2017 edited

Looks great! I'm glad the frame numbers were helpful.

Pro tip: There is no frame 0, as the number is incremented at the beginning of the frame rather than the end, so if you need a special value in the future 0 works just as well as MAX.

@torkleyy

This comment has been minimized.

Show comment
Hide comment
@torkleyy

torkleyy Oct 24, 2017

Member

Assigning @Rhuagh to merge in case of an approval.

Member

torkleyy commented Oct 24, 2017

Assigning @Rhuagh to merge in case of an approval.

@Rhuagh

Rhuagh approved these changes Oct 24, 2017

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 24, 2017

Member

bors r+

Member

Rhuagh commented Oct 24, 2017

bors r+

bors bot added a commit that referenced this pull request Oct 24, 2017

Merge #445
445: Add asset hot reloading r=Rhuagh a=torkleyy

* Adds a new resource to the world, `Arc<rayon::ThreadPool>` (or short: `core::ThreadPool`)
* Adds `WeakHandle`s
* Automatically reloads assets (checked every second)

Fixes #266 

## Problems

* ~~If a file has been written only partially and the asset storage tries to load it, it fails :( I'm not sure if there's a check we can do~~ Fixed by using fallback
@bors

This comment has been minimized.

Show comment
Hide comment

@bors bors bot merged commit 51ae37f into amethyst:develop Oct 24, 2017

3 checks passed

bors Build succeeded
continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@Xaeroxe

This comment has been minimized.

Show comment
Hide comment
@Xaeroxe

Xaeroxe Oct 24, 2017

Member

Yay! No more rebasing! :P

Member

Xaeroxe commented Oct 24, 2017

Yay! No more rebasing! :P

@torkleyy torkleyy deleted the torkleyy:hot branch Oct 24, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment