... | ... |
@@ -30,6 +30,7 @@ |
30 | 30 |
* 20250319 Add-dirdata button. |
31 | 31 |
* 20250320 Fix add-dirdata button appearance. |
32 | 32 |
* Dirdata colors. Select dirdata. |
33 |
+ * 20250329 Background loading of thumbnails. |
|
33 | 34 |
* |
34 | 35 |
* Author: Dario Rodriguez dario@darionomono.com |
35 | 36 |
* (c) Dario Rodriguez 2025 |
... | ... |
@@ -44,6 +45,7 @@ |
44 | 45 |
#include <dirent.h> |
45 | 46 |
#include <sys/stat.h> |
46 | 47 |
#include <sys/time.h> |
48 |
+#include <pthread.h> |
|
47 | 49 |
|
48 | 50 |
#include "raylib.h" |
49 | 51 |
#include "roboto_regular.c" |
... | ... |
@@ -96,6 +98,7 @@ |
96 | 98 |
#define BLOCKLISTINGBUF 2048 |
97 | 99 |
#define BLOCKLISTINGELEMS 1024 |
98 | 100 |
#define BLOCKDIRDATA 16 |
101 |
+#define SIZEBGLOAD 256 |
|
99 | 102 |
|
100 | 103 |
#ifndef FILLXY |
101 | 104 |
#define FILLXY(xywh,valx,valy) (xywh).x=(valx),(xywh).y=(valy) |
... | ... |
@@ -117,6 +120,15 @@ |
117 | 120 |
#define UNROLLWHXY(xywh) (xywh).w,(xywh).h,(xywh).x,(xywh).y |
118 | 121 |
#endif |
119 | 122 |
|
123 |
+#ifndef RD |
|
124 |
+#define RD 0 |
|
125 |
+#endif |
|
126 |
+ |
|
127 |
+#ifndef WR |
|
128 |
+#define WR 1 |
|
129 |
+#endif |
|
130 |
+ |
|
131 |
+ |
|
120 | 132 |
#if !defined(__linux__) && !defined(ANDROID) |
121 | 133 |
/* the old raylib used in the windows build lacks this function */ |
122 | 134 |
bool IsImageValid(Image image) |
... | ... |
@@ -206,6 +218,28 @@ typedef struct texture_t { |
206 | 218 |
xywh_t source; /* be able to detect a "double click" */ |
207 | 219 |
} texture_t; |
208 | 220 |
|
221 |
+typedef struct bgload_t { |
|
222 |
+ /* main/thread ownership management */ |
|
223 |
+ int lended_to_thread; // written from main, read from thread |
|
224 |
+ int thread_finished; // written from thread, read from main |
|
225 |
+ int is_todo; // written from main, read from thread |
|
226 |
+ int has_mark; // written/read from main |
|
227 |
+ /* data only accessed from owner */ |
|
228 |
+ char path[1024]; // to use only from owner |
|
229 |
+ Image image; // to use only from owner |
|
230 |
+ int has_data; // to use only from owner |
|
231 |
+ int has_failedload; // to use only from owner |
|
232 |
+} bgload_t; |
|
233 |
+ |
|
234 |
+typedef struct bg_t { |
|
235 |
+ int sizebgload; |
|
236 |
+ bgload_t *bgload; |
|
237 |
+ int pipe[2]; |
|
238 |
+ pthread_t thread; |
|
239 |
+ pthread_attr_t tattr; |
|
240 |
+ int flag_threadstarted; |
|
241 |
+} bg_t; |
|
242 |
+ |
|
209 | 243 |
typedef struct body_t { |
210 | 244 |
char *rootdir; |
211 | 245 |
xywh_t xywh; |
... | ... |
@@ -224,6 +258,7 @@ typedef struct body_t { |
224 | 258 |
int flag_drawbigtexture; |
225 | 259 |
xywh_t dirdataadd; |
226 | 260 |
Font roundedbox; |
261 |
+ bg_t *bg; |
|
227 | 262 |
} body_t; |
228 | 263 |
|
229 | 264 |
typedef struct im_t { |
... | ... |
@@ -262,7 +297,7 @@ int listing_get(listing_t *listing, char *pathprefix, char *path, int flag_sort) |
262 | 297 |
void listing_freedata(listing_t *listing); |
263 | 298 |
int listing_fillxywh(listing_t *listing, font_t *font, int w, int sidelen, int is_left); |
264 | 299 |
|
265 |
-int texture_load(texture_t *texture, char *fullpath, int maxw, int maxh); |
|
300 |
+int texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg); |
|
266 | 301 |
int texture_draw(texture_t *texture, int x0, int y0, int maxw, int maxh); |
267 | 302 |
int texture_freedata(texture_t *texture); |
268 | 303 |
|
... | ... |
@@ -281,6 +316,15 @@ void imutil_fpsreset(void); |
281 | 316 |
int imutil_fpsleft(void); |
282 | 317 |
long long imutil_milliseconds(void); |
283 | 318 |
|
319 |
+bg_t *bg_init(int sizebgload); |
|
320 |
+void bg_free(bg_t *bg); |
|
321 |
+int bg_resetmarks(bg_t *bg); |
|
322 |
+bgload_t *bg_get(bg_t *bg, char *path); |
|
323 |
+int bg_add(bg_t *bg, char *path); |
|
324 |
+int bg_freeunmarked(bg_t *bg); |
|
325 |
+ |
|
326 |
+void *bg_thread(void *); |
|
327 |
+ |
|
284 | 328 |
int |
285 | 329 |
main(int argc, char *argv[]) |
286 | 330 |
{ |
... | ... |
@@ -412,7 +456,7 @@ fprintf(stderr,"SELECTED: \"%s\"->\"%s\"\n",sel_menu,sel_submenu); |
412 | 456 |
} |
413 | 457 |
} |
414 | 458 |
#endif |
415 |
- if(has_mousechanges==0 && needs_nextredraw==0) { |
|
459 |
+ if(has_mousechanges==0 && needs_nextredraw==0 && scrollspeed==0) { |
|
416 | 460 |
/* Wait for new events when calling EndDrawing() */ |
417 | 461 |
EnableEventWaiting(); |
418 | 462 |
} else { |
... | ... |
@@ -750,6 +794,7 @@ im_body_init(int x, int y, font_t *font, font_t *fontbig, font_t *fonthuge, int |
750 | 794 |
return(NULL); /* sanity check failed */ |
751 | 795 |
if((body=calloc(1,sizeof(body_t)))==NULL |
752 | 796 |
|| (body->rootdir=strdup(rootdir))==NULL |
797 |
+ || (body->bg=bg_init(SIZEBGLOAD))==NULL |
|
753 | 798 |
) { |
754 | 799 |
im_body_free(body),body=NULL; |
755 | 800 |
return(NULL); |
... | ... |
@@ -792,6 +837,8 @@ im_body_free(body_t *body) |
792 | 837 |
if(body->rootdir!=NULL) |
793 | 838 |
free(body->rootdir),body->rootdir=NULL; |
794 | 839 |
/* NOTE: Cannot call UnloadFont(body->roundedbox) as the data was not malloc'd; see https://github.com/raysan5/raylib/blob/master/examples/others/embedded_files_loading.c */ |
840 |
+ if(body->bg!=NULL) |
|
841 |
+ bg_free(body->bg),body->bg=NULL; |
|
795 | 842 |
free(body),body=NULL; |
796 | 843 |
return; |
797 | 844 |
} |
... | ... |
@@ -958,7 +1005,7 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
958 | 1005 |
maxw=windowwidth; |
959 | 1006 |
maxh=windowheight-body->xywh.y; |
960 | 1007 |
if(body->bigtexture.has_texture==0 || strcmp(body->bigtexture.currentpath,body->texture.currentpath)!=0) |
961 |
- texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh); |
|
1008 |
+ texture_load(&(body->bigtexture),body->texture.currentpath,maxw,maxh,body->bg); |
|
962 | 1009 |
if(body->bigtexture.has_texture && strcmp(body->bigtexture.currentpath,body->texture.currentpath)==0) { |
963 | 1010 |
int x0,y0; |
964 | 1011 |
x0=0; |
... | ... |
@@ -988,6 +1035,8 @@ im_body_draw(body_t *body, Vector2 mousepos, int lmbdown, int rmbdown, int windo |
988 | 1035 |
DrawRectangle(body->xywh.x,body->xywh.y,body->leftsize, body->xywh.h, (Color){ 215, 215, 215, 255 } ); |
989 | 1036 |
/* draw right side background */ |
990 | 1037 |
DrawRectangle(body->xywh.x+body->leftsize,body->xywh.y,body->xywh.w-body->leftsize, body->xywh.h, (Color){ 227, 227, 227, 255 } ); |
1038 |
+ /* reset lazy load marks */ |
|
1039 |
+ bg_resetmarks(body->bg); |
|
991 | 1040 |
/* first pass, draw leftside, second pass, draw all of rightside */ |
992 | 1041 |
statustooltip[0]='\0'; |
993 | 1042 |
for(is_leftside=1,flag_skiprightside=flag_skipall=0;is_leftside>=0 && flag_skiprightside==0 && flag_skipall==0;is_leftside--) { |
... | ... |
@@ -1094,40 +1143,45 @@ DrawRectangle(UNROLLXYWH(body->backxywh),((Color){ 0,255,0,255 })); /* hit zone |
1094 | 1143 |
/* show image */ |
1095 | 1144 |
has_imagedrawn=0; |
1096 | 1145 |
if(is_imagefilename(elem->name+1)) { |
1097 |
- if(thumb->has_texture==0 && thumb->has_failedload==0 && imutil_fpsleft()==0) { |
|
1098 |
- *needs_nextredraw=1; |
|
1099 |
- } else if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
1100 |
- Image im; |
|
1146 |
+ if(thumb->has_texture==0 && thumb->has_failedload==0) { |
|
1147 |
+ bgload_t *bgload; |
|
1101 | 1148 |
char fullpath[2048]; |
1149 |
+ *needs_nextredraw=1; |
|
1102 | 1150 |
snprintf(fullpath,sizeof(fullpath),"%s/%s/%s",body->rootdir,dirdata->dirname,elem->name+1); |
1103 | 1151 |
fullpath[sizeof(fullpath)-1]='\0'; |
1104 |
- im=imutil_loadimage(fullpath); |
|
1105 |
- if(IsImageValid(im)) { |
|
1106 |
- int neww,newh; |
|
1107 |
- Image im2,impixel; |
|
1152 |
+ bgload=bg_get(body->bg,fullpath); |
|
1153 |
+ if(bgload!=NULL && bgload->has_data!=0) { |
|
1154 |
+ Image im; |
|
1155 |
+ im=ImageCopy(bgload->image); |
|
1156 |
+ if(IsImageValid(im)) { |
|
1157 |
+ int neww,newh; |
|
1158 |
+ Image im2,impixel; |
|
1108 | 1159 |
#if 1 |
1109 | 1160 |
fprintf(stderr,"Loaded %s\n",fullpath); |
1110 | 1161 |
{ |
1111 | 1162 |
int oldw=im.width,oldh=im.height; |
1112 | 1163 |
#endif |
1113 |
- im2=GenImageColor(sidelen,sidelen,(Color){0,0,0,255}); |
|
1114 |
- imutil_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
1115 |
- ImageResize(&im,neww,newh); |
|
1116 |
- impixel=ImageCopy(im); |
|
1117 |
- ImageResize(&impixel,1,1); |
|
1164 |
+ im2=GenImageColor(sidelen,sidelen,(Color){0,0,0,255}); |
|
1165 |
+ imutil_aspectmaximize(im.width,im.height,sidelen,sidelen,&neww,&newh); |
|
1166 |
+ ImageResize(&im,neww,newh); |
|
1167 |
+ impixel=ImageCopy(im); |
|
1168 |
+ ImageResize(&impixel,1,1); |
|
1118 | 1169 |
#if 1 |
1119 | 1170 |
if(neww>sidelen || newh>sidelen) |
1120 | 1171 |
fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidelen,oldw,oldh,neww,newh); |
1121 | 1172 |
} |
1122 | 1173 |
#endif |
1123 |
- ImageDraw(&im2,impixel,(Rectangle) {0,0,1,1},(Rectangle) {0,0,sidelen,sidelen},(Color){255,255,255,255}); |
|
1124 |
- ImageDraw(&im2,im,(Rectangle) {0,0,neww,newh},(Rectangle) {(sidelen-neww)/2,(sidelen-newh)/2,neww,newh},(Color){255,255,255,255}); |
|
1125 |
- *te=LoadTextureFromImage(im2); |
|
1126 |
- UnloadImage(im); |
|
1127 |
- UnloadImage(im2); |
|
1128 |
- thumb->has_texture=1; |
|
1129 |
- } else { |
|
1130 |
- thumb->has_failedload=1; |
|
1174 |
+ ImageDraw(&im2,impixel,(Rectangle) {0,0,1,1},(Rectangle) {0,0,sidelen,sidelen},(Color){255,255,255,255}); |
|
1175 |
+ ImageDraw(&im2,im,(Rectangle) {0,0,neww,newh},(Rectangle) {(sidelen-neww)/2,(sidelen-newh)/2,neww,newh},(Color){255,255,255,255}); |
|
1176 |
+ *te=LoadTextureFromImage(im2); |
|
1177 |
+ UnloadImage(im); |
|
1178 |
+ UnloadImage(im2); |
|
1179 |
+ thumb->has_texture=1; |
|
1180 |
+ } else { |
|
1181 |
+ thumb->has_failedload=1; |
|
1182 |
+ } |
|
1183 |
+ } else if(bgload==NULL) { |
|
1184 |
+ bg_add(body->bg,fullpath); |
|
1131 | 1185 |
} |
1132 | 1186 |
} |
1133 | 1187 |
if(thumb->has_texture!=0) { |
... | ... |
@@ -1146,7 +1200,7 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1146 | 1200 |
if((body->texture.has_texture==0 && !(body->texture.has_failedload && strcmp(body->texture.currentpath,fullpath)==0)) |
1147 | 1201 |
|| strcmp(body->texture.currentpath,fullpath)!=0 |
1148 | 1202 |
) { |
1149 |
- texture_load(&(body->texture),fullpath,maxw,maxh); |
|
1203 |
+ texture_load(&(body->texture),fullpath,maxw,maxh,body->bg); |
|
1150 | 1204 |
} |
1151 | 1205 |
if(body->texture.has_texture && strcmp(body->texture.currentpath,fullpath)==0) { |
1152 | 1206 |
int x0,y0; |
... | ... |
@@ -1237,14 +1291,17 @@ fprintf(stderr,"elem:\"%s\" sidelen:%i old:%ix%i new:%ix%i\n",elem->name+1,sidel |
1237 | 1291 |
DrawRectangle(0,windowheight-1-margin*2-font->height,m2.x+margin*2,font->height+margin*2,((Color){0,0,0,96})); |
1238 | 1292 |
DrawTextEx(font->font,statustooltip,(Vector2){margin,windowheight-1-margin-font->height},font->height,0,(Color){ 255,255,255,128 }); |
1239 | 1293 |
} |
1294 |
+ /* free not used bg load items */ |
|
1295 |
+ bg_freeunmarked(body->bg); |
|
1240 | 1296 |
return(0); |
1241 | 1297 |
} |
1242 | 1298 |
|
1243 | 1299 |
int |
1244 |
-texture_load(texture_t *texture, char *fullpath, int maxw, int maxh) |
|
1300 |
+texture_load(texture_t *texture, char *fullpath, int maxw, int maxh, bg_t *bg) |
|
1245 | 1301 |
{ |
1246 | 1302 |
Image im; |
1247 | 1303 |
int neww,newh; |
1304 |
+ bgload_t *bgload; |
|
1248 | 1305 |
if(texture==NULL || fullpath==NULL) |
1249 | 1306 |
return(-1); /* sanity check failed */ |
1250 | 1307 |
if(texture->has_texture) { |
... | ... |
@@ -1254,7 +1311,11 @@ texture_load(texture_t *texture, char *fullpath, int maxw, int maxh) |
1254 | 1311 |
texture->has_failedload=0; |
1255 | 1312 |
} |
1256 | 1313 |
texture->currentpath[0]='\0'; |
1257 |
- im=imutil_loadimage(fullpath); |
|
1314 |
+ if(bg!=NULL && (bgload=bg_get(bg,texture->currentpath))!=NULL && bgload->has_data!=0) { |
|
1315 |
+ im=ImageCopy(bgload->image); |
|
1316 |
+ } else { |
|
1317 |
+ im=imutil_loadimage(fullpath); |
|
1318 |
+ } |
|
1258 | 1319 |
if(IsImageValid(im)) { |
1259 | 1320 |
imutil_aspectmaximize(im.width,im.height,maxw,maxh,&neww,&newh); |
1260 | 1321 |
ImageResize(&im,neww,newh); |
... | ... |
@@ -1782,3 +1843,176 @@ imutil_milliseconds(void) |
1782 | 1843 |
return(res); |
1783 | 1844 |
} |
1784 | 1845 |
|
1846 |
+bg_t * |
|
1847 |
+bg_init(int sizebgload) |
|
1848 |
+{ |
|
1849 |
+ bg_t *bg; |
|
1850 |
+ bg=NULL; |
|
1851 |
+ if((bg=calloc(1,sizeof(bg_t)))==NULL |
|
1852 |
+ || (bg->pipe[0]=bg->pipe[1]=-1)!=-1 |
|
1853 |
+ || pipe(bg->pipe)!=0 |
|
1854 |
+ || (bg->bgload=calloc(sizebgload,sizeof(bgload_t)))==NULL |
|
1855 |
+ || (bg->sizebgload=sizebgload)!=sizebgload |
|
1856 |
+ || pthread_attr_init(&(bg->tattr))!=0 |
|
1857 |
+ || pthread_create(&(bg->thread),&(bg->tattr),bg_thread,(void *)bg)!=0 |
|
1858 |
+ || (bg->flag_threadstarted=1)!=1 |
|
1859 |
+ ) { |
|
1860 |
+ bg_free(bg); |
|
1861 |
+ return(NULL); |
|
1862 |
+ } |
|
1863 |
+ return(bg); |
|
1864 |
+} |
|
1865 |
+ |
|
1866 |
+ |
|
1867 |
+void |
|
1868 |
+bg_free(bg_t *bg) |
|
1869 |
+{ |
|
1870 |
+ int i; |
|
1871 |
+ if(bg==NULL) |
|
1872 |
+ return; /* nothing to do */ |
|
1873 |
+ if(bg->flag_threadstarted) { |
|
1874 |
+ char dummy=1; |
|
1875 |
+ write(bg->pipe[WR],&dummy,1); |
|
1876 |
+ pthread_join(bg->thread,NULL); |
|
1877 |
+ bg->flag_threadstarted=0; |
|
1878 |
+ } |
|
1879 |
+ if(bg->pipe[0]!=-1) |
|
1880 |
+ close(bg->pipe[0]),bg->pipe[0]=-1; |
|
1881 |
+ if(bg->pipe[1]!=-1) |
|
1882 |
+ close(bg->pipe[1]),bg->pipe[1]=-1; |
|
1883 |
+ if(bg->bgload!=NULL) { |
|
1884 |
+ bgload_t *bgload; |
|
1885 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1886 |
+ if(bgload->has_data) { |
|
1887 |
+ UnloadImage(bgload->image); |
|
1888 |
+ bgload->has_data=0; |
|
1889 |
+ } |
|
1890 |
+ } |
|
1891 |
+ free(bg->bgload),bg->bgload=NULL,bg->sizebgload=0; |
|
1892 |
+ } |
|
1893 |
+ return; |
|
1894 |
+} |
|
1895 |
+ |
|
1896 |
+int |
|
1897 |
+bg_resetmarks(bg_t *bg) |
|
1898 |
+{ |
|
1899 |
+ int i; |
|
1900 |
+ bgload_t *bgload; |
|
1901 |
+ if(bg==NULL) |
|
1902 |
+ return(-1); |
|
1903 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) |
|
1904 |
+ bgload->has_mark=0; |
|
1905 |
+ return(0); |
|
1906 |
+} |
|
1907 |
+ |
|
1908 |
+bgload_t * |
|
1909 |
+bg_get(bg_t *bg, char *path) |
|
1910 |
+{ |
|
1911 |
+ int i; |
|
1912 |
+ bgload_t *bgload; |
|
1913 |
+ if(bg==NULL) |
|
1914 |
+ return(NULL); |
|
1915 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1916 |
+ if(bgload->thread_finished && bgload->has_data && strcmp(path,bgload->path)==0) { |
|
1917 |
+ bgload->has_mark=1; |
|
1918 |
+#if 1 |
|
1919 |
+fprintf(stderr,"bg_get: \"%s\"\n",bgload->path); |
|
1920 |
+#endif |
|
1921 |
+ return(bgload); |
|
1922 |
+ } |
|
1923 |
+ } |
|
1924 |
+ return(NULL); |
|
1925 |
+} |
|
1926 |
+ |
|
1927 |
+int |
|
1928 |
+bg_add(bg_t *bg, char *path) |
|
1929 |
+{ |
|
1930 |
+ int i; |
|
1931 |
+ bgload_t *bgload; |
|
1932 |
+ int dummy; |
|
1933 |
+ if(bg==NULL) |
|
1934 |
+ return(-1); |
|
1935 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1936 |
+ if(bgload->lended_to_thread && strcmp(path,bgload->path)==0) { |
|
1937 |
+ bgload->is_todo=1; |
|
1938 |
+ bgload->has_mark=1; |
|
1939 |
+ dummy=0; |
|
1940 |
+ write(bg->pipe[WR],&dummy,1); |
|
1941 |
+ return(0); /* already on list */ |
|
1942 |
+ } |
|
1943 |
+ } |
|
1944 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1945 |
+ if(bgload->lended_to_thread==0) { |
|
1946 |
+ memset(bgload,0,sizeof(bgload_t)); |
|
1947 |
+ strncpy(bgload->path,path,sizeof(bgload->path)); |
|
1948 |
+ bgload->path[sizeof(bgload->path)-1]='\0'; |
|
1949 |
+ bgload->is_todo=1; |
|
1950 |
+ bgload->has_mark=1; |
|
1951 |
+ dummy=0; |
|
1952 |
+ bgload->lended_to_thread=1; |
|
1953 |
+ write(bg->pipe[WR],&dummy,1); |
|
1954 |
+ return(0); /* added to list */ |
|
1955 |
+ } |
|
1956 |
+ } |
|
1957 |
+ return(-1); /* couldn't add */ |
|
1958 |
+} |
|
1959 |
+ |
|
1960 |
+int |
|
1961 |
+bg_freeunmarked(bg_t *bg) |
|
1962 |
+{ |
|
1963 |
+ int i; |
|
1964 |
+ bgload_t *bgload; |
|
1965 |
+ if(bg==NULL) |
|
1966 |
+ return(-1); |
|
1967 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
1968 |
+ if(bgload->lended_to_thread && bgload->thread_finished && bgload->has_mark==0) { |
|
1969 |
+ if(bgload->has_data) { |
|
1970 |
+#if 1 |
|
1971 |
+fprintf(stderr,"bg: Unloading: \"%s\"\n",bgload->path); |
|
1972 |
+#endif |
|
1973 |
+ UnloadImage(bgload->image); |
|
1974 |
+ bgload->has_data=0; |
|
1975 |
+ } |
|
1976 |
+#if 1 |
|
1977 |
+else { |
|
1978 |
+fprintf(stderr,"bg: Cancelling: \"%s\"\n",bgload->path); |
|
1979 |
+} |
|
1980 |
+#endif |
|
1981 |
+ memset(bgload,0,sizeof(bgload_t)); |
|
1982 |
+ } |
|
1983 |
+ } |
|
1984 |
+ return(0); |
|
1985 |
+} |
|
1986 |
+ |
|
1987 |
+void * |
|
1988 |
+bg_thread(void *parambg) |
|
1989 |
+{ |
|
1990 |
+ bg_t *bg; |
|
1991 |
+ char dummy; |
|
1992 |
+ bg=(bg_t *)parambg; |
|
1993 |
+ int i; |
|
1994 |
+ bgload_t *bgload; |
|
1995 |
+ while(1) { |
|
1996 |
+ read(bg->pipe[RD],&dummy,1); |
|
1997 |
+ if(dummy!=0) |
|
1998 |
+ break; /* was told to exit */ |
|
1999 |
+ for(i=0,bgload=bg->bgload;i<bg->sizebgload;i++,bgload++) { |
|
2000 |
+ if(bgload->lended_to_thread==0) |
|
2001 |
+ continue; |
|
2002 |
+ if(bgload->is_todo==0) { |
|
2003 |
+ bgload->thread_finished=1; |
|
2004 |
+ continue; |
|
2005 |
+ } |
|
2006 |
+ if(bgload->has_data==0 && bgload->has_failedload==0) { |
|
2007 |
+ bgload->image=imutil_loadimage(bgload->path); |
|
2008 |
+ if(IsImageValid(bgload->image)) |
|
2009 |
+ bgload->has_data=1; |
|
2010 |
+ else |
|
2011 |
+ bgload->has_failedload=1; |
|
2012 |
+ bgload->thread_finished=1; |
|
2013 |
+ } |
|
2014 |
+ } |
|
2015 |
+ } |
|
2016 |
+ pthread_exit(NULL); |
|
2017 |
+} |
|
2018 |
+ |