Skip to content

Commit

Permalink
skip cache whem loading images from files #379
Browse files Browse the repository at this point in the history
* image <path/to/file.png>, cache: false
* still have work to do with the external cache and downloads.
  • Loading branch information
Cecil committed Oct 21, 2017
1 parent ab3c9b5 commit f3ec387
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 15 deletions.
40 changes: 40 additions & 0 deletions bugs/bug379.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Shoes.app do
require 'shoes/data'
require 'shoes/image'
stack do
flow do
@el = edit_line "#{DIR}/static/shoes-icon-walkabout.png"
#@el = edit_line "https://shoes.mvmanila.com/public/images/dino.jpg"
@cb = check; para "Don't cache"
button "(Re)load" do
@img.clear
@img.append do
if @cb.checked?
image @el.text, cache: false
else
image @el.text
end
end
end
button "Show cache" do
@cview.clear
@cview.append do
eb = edit_box width: 400
DATABASE.each do |key, value|
eb.append "#{key} -> #{value}"
end
end
end
button "clear caches" do
DATABASE.each do |k, val|
v = val.split('|')
path = Shoes::image_cache_path v[1], File.extname(k)
File.delete path if File.exist? path
end
DATABASE.clear
end
end
@img = flow {}
@cview = flow {}
end
end
2 changes: 1 addition & 1 deletion shoes/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ typedef struct {

shoes_code shoes_load_imagesize(VALUE, int *, int *);
shoes_cached_image *shoes_cached_image_new(int, int, cairo_surface_t *);
shoes_cached_image *shoes_load_image(VALUE, VALUE);
shoes_cached_image *shoes_load_image(VALUE, VALUE, VALUE);
unsigned char shoes_image_downloaded(shoes_image_download_event *);

// Canvas needs cSvg to create snapshots and send events
Expand Down
32 changes: 22 additions & 10 deletions shoes/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,17 +900,26 @@ int shoes_http_image_handler(shoes_http_event *de, void *data) {
return SHOES_DOWNLOAD_CONTINUE;
}

shoes_cached_image *shoes_load_image(VALUE slot, VALUE imgpath) {
shoes_cached_image *shoes_load_image(VALUE slot, VALUE imgpath, VALUE nocache) {
shoes_cached_image *cached = NULL;
cairo_surface_t *img = NULL;
VALUE filename = rb_funcall(imgpath, s_downcase, 0);
StringValue(filename);
char *fname = RSTRING_PTR(filename);
int width = 1, height = 1;

if (shoes_cache_lookup(RSTRING_PTR(imgpath), &cached))
/*
* don't check the cache issue #379 always download - it will be cached
* but we will ignore it. Brilliant fix or sub-optimal hack?
*/
if (nocache == Qnil || nocache == Qfalse) {
if (shoes_cache_lookup(RSTRING_PTR(imgpath), &cached)) {
fprintf(stderr, "using cached image\n");
goto done;

}
} else {
// fall thru
fprintf(stderr, "always (down)load\n");
}
if (strlen(fname) > 7 && (strncmp(fname, "http://", 7) == 0 || strncmp(fname, "https://", 8) == 0)) {
struct timeval tv;
VALUE cache, uext, hdrs, tmppath, uri, scheme, host, port, requ, path, cachepath = Qnil, hash = Qnil;
Expand All @@ -922,26 +931,27 @@ shoes_cached_image *shoes_load_image(VALUE slot, VALUE imgpath) {
requ = rb_funcall(uri, s_request_uri, 0);
path = rb_funcall(uri, s_path, 0);
path = rb_funcall(path, s_downcase, 0);

// check the download cache (~/.shoes/+cache)
cache = rb_funcall(rb_const_get(rb_cObject, rb_intern("DATABASE")), rb_intern("check_cache_for"), 1, imgpath);
uext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
hdrs = Qnil;
if (!NIL_P(cache)) {
VALUE etag = rb_hash_aref(cache, ID2SYM(rb_intern("etag")));
hash = rb_hash_aref(cache, ID2SYM(rb_intern("hash")));
if (!NIL_P(hash)) cachepath = rb_funcall(cShoes, rb_intern("image_cache_path"), 2, hash, uext);
if (!NIL_P(hash))
cachepath = rb_funcall(cShoes, rb_intern("image_cache_path"), 2, hash, uext);
int saved = NUM2INT(rb_hash_aref(cache, ID2SYM(rb_intern("saved"))));
gettimeofday(&tv, 0);
if (tv.tv_sec - saved < SHOES_IMAGE_EXPIRE) {
cached = shoes_load_image(slot, cachepath);
fprintf(stderr,"recursive load\n");
cached = shoes_load_image(slot, cachepath, nocache); // recursive ick!
if (cached != NULL) {
shoes_cache_insert(SHOES_CACHE_ALIAS, imgpath, cached);
goto done;
}
} else if (!NIL_P(etag))
rb_hash_aset(hdrs = rb_hash_new(), rb_str_new2("If-None-Match"), etag);
}

cached = shoes_cached_image_new(1, 1, shoes_world->blank_image);
shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
tmppath = rb_funcall(cShoes, rb_intern("image_temp_path"), 2, uri, uext);
Expand All @@ -967,11 +977,13 @@ shoes_cached_image *shoes_load_image(VALUE slot, VALUE imgpath) {
shoes_queue_download(req);
goto done;
}

/* here when not http reading from file */
fprintf(stderr, "Read file\n");
img = shoes_surface_create_from_file(imgpath, &width, &height);
if (img != shoes_world->blank_image) {
cached = shoes_cached_image_new(width, height, img);
shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
if (nocache != Qtrue)
shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
}

done:
Expand Down
17 changes: 14 additions & 3 deletions shoes/types/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,18 @@ VALUE shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent, shoes_t
image->attr = attr;
image->parent = shoes_find_canvas(parent);
COPY_PENS(image->attr, basic->attr);

VALUE nocache = Qfalse; // note reversed meaning internally
VALUE vcache = shoes_hash_get(attr,rb_intern("cache"));
if (! NIL_P(vcache)) {
// arg specified. reverse it.
if (vcache == Qnil || vcache == Qfalse) {
nocache = Qtrue;
fprintf(stderr, "don't cache\n");
}
} else {
fprintf(stderr,"will cache\n");
}

if (rb_obj_is_kind_of(path, cImage)) {
shoes_image *image2;
Data_Get_Struct(path, shoes_image, image2);
Expand All @@ -168,7 +179,7 @@ VALUE shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent, shoes_t
} else if (!NIL_P(path)) {
path = shoes_native_to_s(path);
image->path = path;
image->cached = shoes_load_image(image->parent, path);
image->cached = shoes_load_image(image->parent, path, nocache);
image->type = SHOES_CACHE_FILE;
} else {
shoes_canvas *canvas;
Expand Down Expand Up @@ -267,7 +278,7 @@ VALUE shoes_image_get_path(VALUE self) {
VALUE shoes_image_set_path(VALUE self, VALUE path) {
GET_STRUCT(image, image);
image->path = path;
image->cached = shoes_load_image(image->parent, path);
image->cached = shoes_load_image(image->parent, path, Qfalse);
image->type = SHOES_CACHE_FILE;
shoes_canvas_repaint_all(image->parent);
return path;
Expand Down
2 changes: 1 addition & 1 deletion shoes/types/pattern.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ VALUE shoes_pattern_set_fill(VALUE self, VALUE source) {
if (rb_obj_is_kind_of(source, cColor)) {
pattern->pattern = shoes_color_pattern(source);
} else {
pattern->cached = shoes_load_image(pattern->parent, source);
pattern->cached = shoes_load_image(pattern->parent, source, Qfalse);
if (pattern->cached != NULL && pattern->cached->pattern == NULL)
pattern->cached->pattern = cairo_pattern_create_for_surface(pattern->cached->surface);
}
Expand Down

1 comment on commit f3ec387

@ccoupe
Copy link

@ccoupe ccoupe commented on f3ec387 Oct 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo this commit was for issue #377

Please sign in to comment.