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.