GLImage.m 2.7 KB
Newer Older
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
1

2 3
#import "GLImage.h"
#import "GLImageData.h"
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
4 5 6
#import "RCTBridge.h"
#import "RCTImageLoader.h"
#import "RCTLog.h"
7
#import "GLTexture.h"
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
8

9
@implementation GLImage
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
10 11 12
{
  RCTBridge *_bridge; // React's bridge allow to access the imageLoader
  UIImage *_image; // The currently loaded image (nil if no image fully loaded yet)
13 14
  GLImageData *_data; // Cache of the data related to this image (computed by getImageData)
  GLTexture *_texture; // Cache of the texture
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
15 16 17 18 19 20 21 22 23 24 25
  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;
26
    _texture = [[GLTexture alloc] init];
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
27 28 29 30 31 32 33 34 35 36 37
  }
  return self;
}

- (void)dealloc
{
  [self clearImage];
  if (_loading) _loading();
  _onload = nil;
  _loading = nil;
  _bridge = nil;
38
  _texture = nil;
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
39 40 41 42 43 44 45 46 47 48
}

RCT_NOT_IMPLEMENTED(-init)

- (void) clearImage
{
  _image = nil;
  _data = nil;
}

49
- (GLTexture *) getTexture
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
50
{
51 52 53 54 55 56 57 58
  if (_image) {
    if (!_data) {
      _data = genPixelsWithImage(_image);
    }
    [_texture setPixels:_data];
  }
  else {
    [_texture setPixelsEmpty];
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
59
  }
60
  return _texture;
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
61 62 63 64
}

- (void)setSrc:(NSString *)src
{
65
  if (![src isEqualToString:_src]) {
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
66 67 68 69 70 71 72 73 74 75 76 77
    _src = [src copy];
    [self reloadImage];
  }
}

- (void)reloadImage
{
  if (_loading) _loading();
  _loading = nil;
  if (!_src) {
    [self clearImage];
  } else {
78

Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
79
    // Load the image (without resizing it)
80

Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
81
    if (![_src hasPrefix:@"http://"] && ![_src hasPrefix:@"https://"]) {
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
82
      self.image = [UIImage imageNamed:_src];
83 84 85
      dispatch_async(dispatch_get_main_queue(), ^{
        if (_onload) _onload();
      });
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
86 87 88 89 90 91
    } else {
      _loading = [_bridge.imageLoader loadImageWithTag:_src
                                       size:CGSizeZero
                                      scale:0
                                 resizeMode:UIViewContentModeScaleToFill
                              progressBlock:nil
92
                            completionBlock:^(NSError *error, UIImage *image) {
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
93 94 95 96 97
                              _loading = nil;
                              [self clearImage];
                              if (error) {
                                NSLog(@"Image failed to load: %@", error);
                              } else {
98 99
                                // we need to copy the image because it seems the image will be altered.
                                self.image = [UIImage imageWithCGImage:image.CGImage];
Gaëtan Renaudeau's avatar
Gaëtan Renaudeau committed
100 101 102 103 104 105 106 107 108
                                if(_onload) _onload();
                              }
                            }];
    }
  }
}


@end