Skip to content

Commit

Permalink
Add support to hs.image.imageFromURL() for loading resources asynchro…
Browse files Browse the repository at this point in the history
…nously. Closes #2224
  • Loading branch information
cmsj committed Nov 1, 2019
1 parent 3fe9fb4 commit ca1c353
Showing 1 changed file with 36 additions and 9 deletions.
45 changes: 36 additions & 9 deletions extensions/image/internal.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
@import AVFoundation;

#define USERDATA_TAG "hs.image"
int refTable = LUA_NOREF;

// NSWorkspace iconForFile: logs a warning every time you try to query when the path is nil. Since
// this happens a lot when trying to query based on a file bundle it means anything using spotlight
Expand Down Expand Up @@ -1006,24 +1007,50 @@ static int imageFromName(lua_State *L) {
return 1 ;
}

/// hs.image.imageFromURL(url) -> object
/// hs.image.imageFromURL(url[, callbackFn]) -> object
/// Constructor
/// Creates an `hs.image` object from the contents of the specified URL.
///
/// Parameters:
/// * url - a web url specifying the location of the image to retrieve
/// * callbackFn - an optional callback function to be called when the image fetching is complete
///
/// Returns:
/// * An `hs.image` object or nil, if the url does not specify image contents or is unreachable
/// * An `hs.image` object or nil, if the url does not specify image contents or is unreachable, or if a callback function is supplied
///
/// Notes:
/// * If a callback function is supplied, this function will return nil immediately and the image will be fetched asynchronously
static int imageFromURL(lua_State *L) {
LuaSkin *skin = [LuaSkin shared] ;
[skin checkArgs:LS_TSTRING, LS_TBREAK] ;
[skin checkArgs:LS_TSTRING, LS_TFUNCTION|LS_TOPTIONAL, LS_TBREAK] ;
NSURL *theURL = [NSURL URLWithString:[skin toNSObjectAtIndex:1]] ;
if (theURL) {
if (!theURL) {
lua_pushnil(L);
return 1;
}

if (lua_type(L, 2) != LUA_TFUNCTION) {
[skin pushNSObject:[[NSImage alloc] initWithContentsOfURL:theURL]] ;
} else {
lua_pushnil(L) ;
int fnRef = [skin luaRef:refTable atIndex:2];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
NSImage *image = [[NSImage alloc] initWithContentsOfURL:theURL];

dispatch_async(dispatch_get_main_queue(), ^(void){
LuaSkin *bgSkin = [LuaSkin shared];
_lua_stackguard_entry(bgSkin.L);

[bgSkin pushLuaRef:refTable ref:fnRef];
[bgSkin pushNSObject:image];
[bgSkin protectedCallAndTraceback:1 nresults:0];
[bgSkin luaUnref:refTable ref:fnRef];

_lua_stackguard_exit(bgSkin.L);
});
});
lua_pushnil(L);
}

return 1 ;
}

Expand Down Expand Up @@ -1675,10 +1702,10 @@ static int userdata_gc(lua_State* L) {

int luaopen_hs_image_internal(lua_State* L) {
LuaSkin *skin = [LuaSkin shared] ;
[skin registerLibraryWithObject:USERDATA_TAG
functions:moduleLib
metaFunctions:nil
objectFunctions:userdata_metaLib];
refTable = [skin registerLibraryWithObject:USERDATA_TAG
functions:moduleLib
metaFunctions:nil
objectFunctions:userdata_metaLib];

pushNSImageNameTable(L); lua_setfield(L, -2, "systemImageNames") ;
additionalImages(L) ; lua_setfield(L, -2, "additionalImageNames") ;
Expand Down

0 comments on commit ca1c353

Please sign in to comment.