Merge pull request #68 from czarkoff/reload

Use stat(2) to monitor file changes
This commit is contained in:
Harry Jeffery 2015-12-28 13:40:35 +00:00
commit 433d8195a7
5 changed files with 42 additions and 96 deletions

View file

@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "navigator.h"
#include "viewport.h"
#include "util.h"
#include "reload.h"
struct {
int fullscreen;
@ -285,9 +284,6 @@ int main(int argc, char** argv)
struct imv_viewport view;
imv_init_viewport(&view, window);
struct imv_reload reload;
imv_init_reload(&reload);
/* put us in fullscren mode to begin with if requested */
if(g_options.fullscreen) {
imv_viewport_toggle_fullscreen(&view);
@ -422,7 +418,7 @@ int main(int argc, char** argv)
}
/* if the user has changed image, start loading the new one */
if(imv_navigator_poll_changed(&nav) || imv_reload_changed(&reload)) {
if(imv_navigator_poll_changed(&nav)) {
const char *current_path = imv_navigator_selection(&nav);
if(!current_path) {
fprintf(stderr, "No input files left. Exiting.\n");
@ -435,7 +431,6 @@ int main(int argc, char** argv)
imv_viewport_set_title(&view, title);
imv_loader_load_path(&ldr, current_path);
imv_reload_watch(&reload, current_path);
view.playing = 1;
}
@ -574,7 +569,6 @@ int main(int argc, char** argv)
imv_destroy_texture(&tex);
imv_navigator_destroy(&nav);
imv_destroy_viewport(&view);
imv_destroy_reload(&reload);
if(font) {
TTF_CloseFont(font);

View file

@ -27,6 +27,16 @@ void imv_navigator_init(struct imv_navigator *nav)
{
nav->buf_size = 512;
nav->paths = malloc(sizeof(char*) * nav->buf_size);
if (nav->paths == NULL) {
perror("imv_navigator_init");
exit(1);
}
nav->mtimes = malloc(sizeof(time_t) * nav->buf_size);
if (nav->paths == NULL) {
perror("imv_navigator_init");
free(nav->paths);
exit(1);
}
nav->num_paths = 0;
nav->cur_path = 0;
nav->last_move_direction = 1;
@ -38,22 +48,33 @@ void imv_navigator_destroy(struct imv_navigator *nav)
if(nav->buf_size > 0) {
free(nav->paths);
nav->paths = NULL;
free(nav->mtimes);
nav->mtimes = NULL;
nav->buf_size = 0;
}
nav->num_paths = 0;
}
static void add_item(struct imv_navigator *nav, const char *path)
static void add_item(struct imv_navigator *nav, const char *path,
time_t mtime)
{
if(nav->buf_size == nav->num_paths) {
int new_buf_size = nav->buf_size * 2;
char **new_paths = malloc(sizeof(char*) * new_buf_size);
memcpy(new_paths, nav->paths, sizeof(char*) * nav->buf_size);
free(nav->paths);
char **new_paths;
time_t *new_mtimes;
nav->buf_size *= 2;
new_paths = realloc(nav->paths, sizeof(char*) * nav->buf_size);
new_mtimes = realloc(nav->mtimes, sizeof(time_t) * nav->buf_size);
if (new_paths == NULL || new_mtimes == NULL) {
perror("add_item");
free(nav->paths);
free(nav->mtimes);
exit(1);
}
nav->paths = new_paths;
nav->buf_size = new_buf_size;
nav->mtimes = new_mtimes;
}
nav->paths[nav->num_paths] = strdup(path);
nav->mtimes[nav->num_paths] = mtime;
nav->num_paths += 1;
if(nav->num_paths == 1) {
nav->changed = 1;
@ -79,13 +100,13 @@ void imv_navigator_add(struct imv_navigator *nav, const char *path,
if(recursive) {
imv_navigator_add(nav, path_buf, recursive);
} else {
add_item(nav, path_buf);
add_item(nav, path_buf, path_info.st_mtim.tv_sec);
}
}
closedir(d);
}
} else {
add_item(nav, path);
add_item(nav, path, path_info.st_mtim.tv_sec);
}
}
@ -195,6 +216,13 @@ int imv_navigator_poll_changed(struct imv_navigator *nav)
nav->changed = 0;
return 1;
} else {
struct stat file_info;
if (stat(nav->paths[nav->cur_path], &file_info) == -1)
return 0;
if (nav->mtimes[nav->cur_path] != file_info.st_mtim.tv_sec) {
nav->mtimes[nav->cur_path] = file_info.st_mtim.tv_sec;
return 1;
}
return 0;
}
}

View file

@ -1,6 +1,8 @@
#ifndef IMV_NAVIGATOR_H
#define IMV_NAVIGATOR_H
#include <time.h>
/* Copyright (c) 2015 Harry Jeffery
This program is free software; you can redistribute it and/or
@ -23,6 +25,7 @@ struct imv_navigator {
int buf_size;
int cur_path;
char **paths;
time_t *mtimes;
int last_move_direction;
int changed;
};
@ -57,7 +60,8 @@ void imv_navigator_select_str(struct imv_navigator *nav, const int path);
/* Return the index of the path given. Returns -1 if not found. */
int imv_navigator_find_path(struct imv_navigator *nav, const char *path);
/* Returns 1 if the currently selected path has changed since last called */
/* Returns 1 if either the currently selected path or underlying file has
* changed since last called */
int imv_navigator_poll_changed(struct imv_navigator *nav);
#endif

View file

@ -1,49 +0,0 @@
#include <sys/inotify.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include "reload.h"
void imv_init_reload(struct imv_reload *rld)
{
rld->fd = inotify_init1(IN_NONBLOCK);
if(rld->fd == -1) {
perror("imv_init_reload");
}
rld->wd = 0;
}
void imv_reload_watch(struct imv_reload *rld, const char *path)
{
if(rld->wd != 0) {
inotify_rm_watch(rld->fd, rld->wd);
}
rld->wd = inotify_add_watch(rld->fd, path, IN_CLOSE_WRITE);
if(rld->wd == -1) {
perror("imv_reload_watch");
}
}
int imv_reload_changed(struct imv_reload *rld)
{
struct inotify_event ev;
ssize_t len = read(rld->fd, &ev, sizeof(ev));
if(len < 0) {
if(errno != EAGAIN) {
perror("imv_reload_changed");
}
} else if(ev.mask & IN_CLOSE_WRITE) {
return 1;
}
return 0;
}
void imv_destroy_reload(struct imv_reload *rld)
{
close(rld->fd);
}

View file

@ -1,31 +0,0 @@
#ifndef IMV_RELOAD_H
#define IMV_RELOAD_H
/* Copyright (c) 2015 Jose Diez
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
struct imv_reload {
int fd; // inotify file descriptor
int wd; // watch descriptor
};
void imv_init_reload(struct imv_reload *rld);
void imv_reload_watch(struct imv_reload *rld, const char *path);
int imv_reload_changed(struct imv_reload *rld);
void imv_destroy_reload(struct imv_reload *rld);
#endif