General Information
LibAsyncTextures makes it possible to have all your textures loaded in the background asynchronously, thus enabling you to load texture-rich frames without risking the Watchdog barking at you and lifts you of the burdon of having to deal with coroutines and stuff.
New Texture methods
The library adds two new functions to every Texture
widget:
Texture:SetTextureAsync(source, texture[, callback])
This method enqueues the given frame for asynchronous texture loading. The function is non-blocking and returns immediately, loading the texture content at a later time. Thesource
andtexture
parameters are the same as inSetTexture
. You can optionally add a callback to get called when the texture finished loading. It receivesframe
as its only parameter. You should not perform time intensive tasks in the callback.Texture:CancelSetTextureAsync()
This method cancels a previous call toSetTextureAsync
. If no load is enqueued the error is silently ignored.
Both mentioned methods are also available as library methods:
LibAsyncTextures.SetTextureAsync(frame, source, texture[, callback])
LibAsyncTextures.CancelSetTextureAsync(frame)
Additionally you get:
LibAsyncTextures.CancelAllPendingTextures()
to cancel all asynchronous loads of the current addon.LibAsyncTextures.GetNumPendingTextures()
to retrieve how many textures are queued for asynchronous loading in the current addon.LibAsyncTextures.EnqueueCallback(callback)
to enqueue any arbitrary callback which is called after all the textures have been loaded which are queued up for your addon up to now.
How it works
Behind the scene the library manages a queue of pending texture loads and schedules those in Event.System.Update.End
. All addons are dealt with in round-robin fashion, meaning the library switches between addons in order to balance loading amongst them all. This prevents a single addon from putting so much pressure on the loading queue that it dominates the loading process.
The textures are loaded in the same order they were initiated (within each addon). However, if you initiate an asynchronous load for a frame which has already an asynchronous load in the queue, the previous task is automatically canceled.
Internally the addon tracks the loading time of the textures and gives a maximum time slice for the loading process per frame. This is currently set to 10 miliseconds per frame (about a third of the time a frame takes to render at 30 fps).
Caveats
Because the texture is not loaded immediately when SetTextureAsync()
returns you have to keep in mind that you do not have access to the texture's dimensions before loading finishes (use the callback if required). You can SetWidth
and SetHeight
on the Texture
widget if you know its dimensions in advance. It is also possible to SetPoint
other frames to it, but (if width or height is not set) it may result in the attached frames to move across the screen until all textures are loaded.
Keep also in mind, that if you do not cancel an asynchronous load, it may overwrite any texture you load manually using the blocking variant SetTexture()
after initiating SetTextureAsync()
but before it finishes.
Example
local texture = UI.CreateFrame("Texture", "Example texture", parent) texture:SetTextureAsync("MyAddon", "textures/example.png",function(frame) print("done", frame) end)