It is common to pass Texture instances around, but there is no API on Texture that allows code that receives a Texture to detect when the texture is loaded.
This leads to 3rd-party code needing hacks like polling loops to detect when a texture is loaded, for example here:
(cc @marcofugaro)
It would be nice if Texture, seeing as it already extends from EventDispatcher, would emit load event (when .image goes from null to a value that doesn’t need to load like a data array or ImageBitmap, otherwise for something like HTMLImageElement dispatches if the image is .complete otherwise waits for the image load event, etc) to tell people when the texture is loaded.
Real-world problem scenario
Not even using TextureLoader’s load event in my code was good enough to re-draw my scene with a texture after three-projected-material detected the load event with its poll loop:
This caused an issue in my app: it renders the scene only when necessary (not an infinite render loop), and due to three-projected-material having an internal poll loop, I had no idea when to re-draw the scene after passing it a texture.
Despite me using on TextureLoader’s load event (noting that three-projected-texture received a Texture and not a TextureLoader), I was re-drawing the scene too early. The setInterval within three-projected-material turned out to fire after my animation frame triggered from TextureLoader’s load event, hence my re-draw would not include the texture because an internal state within three-projected-material was not toggled until after my frame fired.
Having a load event for Texture would make things easy: both my code and three-projected-material code can do what they both want in the load event, then my animation frame would come next and would not miss any state change that setInterval otherwise caused.
There are a bunch of APIs that accept textures, and they have no ability to run logic on load, which makes coordination difficult in certain cases.
Had all APIs been designed to instead accept TextureLoader instances, that would solve the problem, but it doesn’t seem like a good semantic solution: objects want textures, not loaders. Would it be strange if mesh.map accepted a TextureLoader? Perhaps it wouldn’t be although it could work.
I personally think that either Texture can fire load events depending on internal image type, or subclasses like ImageTexture, etc, can specifically fire events as needed.
Having a class with async data within it, but not having any clue as to when it is ready, is something we don’t see in any regular web APIs, and perhaps it is good to follow a queue from web APIs here.
An alternative is to recommend for authors making Texture-containing classes to always provide needsUpdate methods and let all end users always have to worry about when to update.
It seems cleaner to have the update event be in the shared common class (f.e. Texture), and allowing authors to opt into the events without their end users having to always be aware of calling a needsUpdate methods.