Commit cdedc051 authored by Gaëtan Renaudeau's avatar Gaëtan Renaudeau
parent f414e027
#import <React/RCTBridge.h>
#import <React/RCTImageLoader.h>
#import <React/RCTLog.h>
#import <React/RCTUtils.h>
#import "GLImage.h"
#import "GLImageData.h"
#import "GLTexture.h"
@implementation GLImage
{
RCTBridge *_bridge; // React's bridge allow to access the imageLoader
UIImage *_image; // The currently loaded image (nil if no image fully loaded yet)
GLImageData *_data; // Cache of the data related to this image (computed by getImageData)
GLTexture *_texture; // Cache of the texture
void (^_onload)(void); // called everytime an image loads
RCTImageLoaderCancellationBlock _loading; // the current loading cancellation function
}
- (instancetype)initWithBridge:(RCTBridge *)bridge withOnLoad:(void (^)(void))onload
{
if ((self = [super init])) {
_bridge = bridge;
_onload = onload;
_image = nil;
_loading = nil;
_texture = [[GLTexture alloc] init];
}
return self;
}
- (void)dealloc
{
[self clearImage];
if (_loading) _loading();
_onload = nil;
_loading = nil;
_bridge = nil;
_texture = nil;
}
RCT_NOT_IMPLEMENTED(-init)
- (void) clearImage
{
_image = nil;
_data = nil;
}
- (GLTexture *) getTexture
{
if (_image) {
if (!_data) {
_data = [GLImageData genPixelsWithImage:_image];
}
[_texture setPixels:_data];
}
else {
[_texture setPixels:nil];
}
return _texture;
}
- (void)setSource:(RCTImageSource *)source
{
if (![source isEqual:_source]) {
_source = source;
[self reloadImage];
}
}
- (void)reloadImage
{
RCTImageSource *source = _source;
if (_loading) _loading();
_loading = nil;
if (!source) {
[self clearImage];
}
else {
// Load the image (without resizing it)
__weak GLImage *weakSelf = self;
_loading = [_bridge.imageLoader loadImageWithURLRequest:source.request
size:CGSizeZero
scale:0
clipped:YES
resizeMode:RCTResizeModeStretch
progressBlock:nil
partialLoadBlock:nil
completionBlock:^(NSError *error, UIImage *loadedImage) {
GLImage *strongSelf = weakSelf;
void (^setImageBlock)(UIImage *) = ^(UIImage *image) {
if (![source isEqual:strongSelf.source]) {
// Bail out if source has changed since we started loading
return;
}
strongSelf.image = [UIImage imageWithCGImage:image.CGImage];
dispatch_async(dispatch_get_main_queue(), ^{
if (_onload) _onload();
});
};
_loading = nil;
[self clearImage];
if (error) {
NSLog(@"Image failed to load: %@", error);
} else {
if ([NSThread isMainThread]) {
setImageBlock(loadedImage);
} else {
RCTUnsafeExecuteOnMainQueueSync(^{
setImageBlock(loadedImage);
});
}
}
}];
}
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment