That’s the ‘documentation’ part I was referring to when I mentioned I was being lazy
I’ll try to post a couple of simple illustrative examples in the meantime though. Both of these objects are very powerful and there is a surprising amount of things you can accomplish with them.
Callbacks() returns an object that manages a list of callbacks. It has several options which you can read about in jQuery’s documentation (‘once’, ‘memory’, ‘stopOnFalse’, ‘unique’), but one practical application I can see for a callback list with default options is an event callback system. For example:
local onTouched = Callbacks()
function setup()
onTouched:add(function(touch)
print('Touch callback 1', touch)
end)
onTouched:add(function(touch)
print('Touch callback 2', touch)
end)
end
function touched(touch)
onTouched:fire(touch)
end
Every time touched() is called, all of the callbacks in the onTouched list will be executed. Using the options provides some interesting possibilities; for example, Deferred() uses 3 callback lists, all with the ‘memory’ option, and 2 with the ‘once’ option
Deferred() is useful for managing asynchronous operations, especially when there are many, and they are dependent upon each other. Generally for asynchronous operations you provide callback functions for when the operation is completed. Deferred provides an easy way to specify callbacks for success/failure cases, as well as progress updates, without bloating your function’s call signature (among other things). Here’s an example function called Request that wraps Codea’s http.request and returns a deferred object, as well as an example of specifying the callbacks:
function Request(url, paramTable)
local deferred = Deferred()
local function _success(data) deferred:resolve(data) end
local function _fail(err) deferred:reject(err) end
http.request(url, _success, _fail, paramTable)
return deferred:promise()
end
function setup()
myRequest = Request('http://twolivesleft.com/Codea/logo.png')
:done(function(img)
myImage = img
end)
:fail(function(err)
print('image download failed:', err)
end)
:always(function()
print('always called, regardless of success or failure')
end)
end
function draw()
if myImage then
sprite(myImage, WIDTH/2, HEIGHT/2)
end
end
Another useful feature is that if you add your callback after the deferred has been resolved, your callback will be fired immediately:
local def = Deferred()
def:done(function(str)
print(str)
end)
def:resolve('hello!') -- callback above will be executed now
-- will be executed immediately since deferred has been resolved
def:done(function(str)
print(str .. ' after the fact!');
end)
There’s actually a ton more you can do with deferreds; you can use when() to create a deferred that is resolved when several other deferreds are resolved, or you can use deferred:pipe() to filter/chain operations. Hopefully I’ll be able to find some time in the next few days to provide some more detailed and practical examples.