aboutsummaryrefslogtreecommitdiff
path: root/src/navigator.c
diff options
context:
space:
mode:
authorHarry Jeffery <harry@exec64.co.uk>2019-02-16 18:48:01 +0000
committerHarry Jeffery <harry@exec64.co.uk>2019-02-16 21:54:52 +0000
commit28eb7b50dcc91c2c869721d9c62095b7dc29f3cc (patch)
treeac85390bf8896fef07e82372b654a7420a68e180 /src/navigator.c
parent4eaa1c89aefb4ebb0cc5aa40613a555e6d250ed0 (diff)
downloadimv-28eb7b50dcc91c2c869721d9c62095b7dc29f3cc.tar.gz
navigator: Simplify file polling
We don't need to know when all paths were last touched, just when we switched to the current path, and the last time that the file changed. This also fixes a bug where imv would double-load images as it refreshed its internal mtime.
Diffstat (limited to 'src/navigator.c')
-rw-r--r--src/navigator.c117
1 files changed, 51 insertions, 66 deletions
diff --git a/src/navigator.c b/src/navigator.c
index 4b996b2..b03926c 100644
--- a/src/navigator.c
+++ b/src/navigator.c
@@ -17,8 +17,8 @@ struct imv_navigator {
int num_paths;
int cur_path;
char **paths;
- time_t *mtimes;
- time_t *ctimes;
+ time_t last_change;
+ time_t last_check;
int last_move_direction;
int changed;
int wrapped;
@@ -36,52 +36,35 @@ struct imv_navigator *imv_navigator_create(void)
void imv_navigator_free(struct imv_navigator *nav)
{
if(nav->paths) {
- for(int i = 0; i < nav->num_paths; ++i) {
- if(nav->paths[i] != NULL) {
+ for (int i = 0; i < nav->num_paths; ++i) {
+ if (nav->paths[i] != NULL) {
free(nav->paths[i]);
}
}
free(nav->paths);
}
- if(nav->mtimes) {
- free(nav->mtimes);
- }
-
- if(nav->ctimes) {
- free(nav->ctimes);
- }
-
free(nav);
}
-static int add_item(struct imv_navigator *nav, const char *path,
- time_t mtime)
+static int add_item(struct imv_navigator *nav, const char *path)
{
const size_t buf_size = 512;
- if(nav->num_paths % buf_size == 0) {
+ if (nav->num_paths % buf_size == 0) {
char **new_paths;
- time_t *new_mtimes;
- time_t *new_ctimes;
size_t new_size = nav->num_paths + buf_size;
new_paths = realloc(nav->paths, sizeof(char*) * new_size);
- new_mtimes = realloc(nav->mtimes, sizeof(time_t) * new_size);
- new_ctimes = realloc(nav->ctimes, sizeof(time_t) * new_size);
- if (new_paths == NULL || new_mtimes == NULL || new_ctimes == NULL) {
+ if (new_paths == NULL) {
return 1;
}
nav->paths = new_paths;
- nav->mtimes = new_mtimes;
- nav->ctimes = new_ctimes;
}
- if((nav->paths[nav->num_paths] = strndup(path, PATH_MAX)) == NULL) {
+ if ((nav->paths[nav->num_paths] = strndup(path, PATH_MAX)) == NULL) {
return 1;
}
- nav->mtimes[nav->num_paths] = mtime;
- nav->ctimes[nav->num_paths] = time(NULL);
nav->num_paths += 1;
- if(nav->num_paths == 1) {
+ if (nav->num_paths == 1) {
nav->changed = 1;
}
@@ -94,22 +77,21 @@ int imv_navigator_add(struct imv_navigator *nav, const char *path,
char path_buf[PATH_MAX];
struct stat path_info;
stat(path, &path_info);
- if(S_ISDIR(path_info.st_mode)) {
+ if (S_ISDIR(path_info.st_mode)) {
DIR *d = opendir(path);
- if(d) {
+ if (d) {
struct dirent *dir;
- while((dir = readdir(d)) != NULL) {
- if(strcmp(dir->d_name, "..") == 0 || strcmp(dir->d_name, ".") == 0) {
+ while ((dir = readdir(d)) != NULL) {
+ if (strcmp(dir->d_name, "..") == 0 || strcmp(dir->d_name, ".") == 0) {
continue;
}
snprintf(path_buf, sizeof(path_buf), "%s/%s", path, dir->d_name);
- if(recursive) {
- if(imv_navigator_add(nav, path_buf, recursive) != 0) {
+ if (recursive) {
+ if (imv_navigator_add(nav, path_buf, recursive) != 0) {
return 1;
}
} else {
- stat(path_buf, &path_info);
- if(add_item(nav, path_buf, path_info.st_mtim.tv_sec) != 0) {
+ if (add_item(nav, path_buf) != 0) {
return 1;
}
}
@@ -117,7 +99,7 @@ int imv_navigator_add(struct imv_navigator *nav, const char *path,
closedir(d);
}
} else {
- return add_item(nav, path, path_info.st_mtim.tv_sec);
+ return add_item(nav, path);
}
return 0;
@@ -125,7 +107,7 @@ int imv_navigator_add(struct imv_navigator *nav, const char *path,
const char *imv_navigator_selection(struct imv_navigator *nav)
{
- if(nav->num_paths == 0) {
+ if (nav->num_paths == 0) {
return "";
}
return nav->paths[nav->cur_path];
@@ -139,24 +121,24 @@ size_t imv_navigator_index(struct imv_navigator *nav)
void imv_navigator_select_rel(struct imv_navigator *nav, int direction)
{
const int prev_path = nav->cur_path;
- if(nav->num_paths == 0) {
+ if (nav->num_paths == 0) {
return;
}
- if(direction > 1) {
+ if (direction > 1) {
direction = 1;
- } else if(direction < -1) {
+ } else if (direction < -1) {
direction = -1;
- } else if(direction == 0) {
+ } else if (direction == 0) {
return;
}
nav->cur_path += direction;
- if(nav->cur_path == nav->num_paths) {
+ if (nav->cur_path == nav->num_paths) {
/* Wrap after the end of the list */
nav->cur_path = 0;
nav->wrapped = 1;
- } else if(nav->cur_path < 0) {
+ } else if (nav->cur_path < 0) {
/* Wrap before the start of the list */
nav->cur_path = nav->num_paths - 1;
nav->wrapped = 1;
@@ -170,17 +152,17 @@ void imv_navigator_select_abs(struct imv_navigator *nav, int index)
{
const int prev_path = nav->cur_path;
/* allow -1 to indicate the last image */
- if(index < 0) {
+ if (index < 0) {
index += nav->num_paths;
/* but if they go farther back than the first image, stick to first image */
- if(index < 0) {
+ if (index < 0) {
index = 0;
}
}
/* stick to last image if we go beyond it */
- if(index >= nav->num_paths) {
+ if (index >= nav->num_paths) {
index = nav->num_paths - 1;
}
@@ -192,32 +174,32 @@ void imv_navigator_select_abs(struct imv_navigator *nav, int index)
void imv_navigator_remove(struct imv_navigator *nav, const char *path)
{
int removed = -1;
- for(int i = 0; i < nav->num_paths; ++i) {
- if(strcmp(path, nav->paths[i]) == 0) {
+ for (int i = 0; i < nav->num_paths; ++i) {
+ if (strcmp(path, nav->paths[i]) == 0) {
removed = i;
free(nav->paths[i]);
break;
}
}
- if(removed == -1) {
+ if (removed == -1) {
return;
}
- for(int i = removed; i < nav->num_paths - 1; ++i) {
+ for (int i = removed; i < nav->num_paths - 1; ++i) {
nav->paths[i] = nav->paths[i+1];
}
nav->num_paths -= 1;
- if(nav->cur_path == removed) {
+ if (nav->cur_path == removed) {
/* We just removed the current path */
- if(nav->last_move_direction < 0) {
+ if (nav->last_move_direction < 0) {
/* Move left */
imv_navigator_select_rel(nav, -1);
} else {
/* Try to stay where we are, unless we ran out of room */
- if(nav->cur_path == nav->num_paths) {
+ if (nav->cur_path == nav->num_paths) {
nav->cur_path = 0;
nav->wrapped = 1;
}
@@ -228,7 +210,7 @@ void imv_navigator_remove(struct imv_navigator *nav, const char *path)
void imv_navigator_select_str(struct imv_navigator *nav, const int path)
{
- if(path <= 0 || path >= nav->num_paths) {
+ if (path <= 0 || path >= nav->num_paths) {
return;
}
int prev_path = nav->cur_path;
@@ -239,16 +221,16 @@ void imv_navigator_select_str(struct imv_navigator *nav, const int path)
int imv_navigator_find_path(struct imv_navigator *nav, const char *path)
{
/* first try to match the exact path */
- for(int i = 0; i < nav->num_paths; ++i) {
- if(strcmp(path, nav->paths[i]) == 0) {
+ for (int i = 0; i < nav->num_paths; ++i) {
+ if (strcmp(path, nav->paths[i]) == 0) {
return i;
}
}
/* no exact matches, try the final portion of the path */
- for(int i = 0; i < nav->num_paths; ++i) {
+ for (int i = 0; i < nav->num_paths; ++i) {
char *last_sep = strrchr(nav->paths[i], '/');
- if(last_sep && strcmp(last_sep+1, path) == 0) {
+ if (last_sep && strcmp(last_sep+1, path) == 0) {
return i;
}
}
@@ -259,26 +241,29 @@ int imv_navigator_find_path(struct imv_navigator *nav, const char *path)
int imv_navigator_poll_changed(struct imv_navigator *nav)
{
- if(nav->changed) {
+ if (nav->changed) {
nav->changed = 0;
+ nav->last_change = time(NULL);
return 1;
}
-
- if(nav->paths == NULL) {
+
+ if (nav->paths == NULL) {
return 0;
};
time_t cur_time = time(NULL);
/* limit polling to once per second */
- if(nav->ctimes[nav->cur_path] < cur_time - 1) {
- nav->ctimes[nav->cur_path] = cur_time;
+ if (nav->last_check < cur_time - 1) {
+ nav->last_check = cur_time;
struct stat file_info;
- if(stat(nav->paths[nav->cur_path], &file_info) == -1) {
+ 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;
+
+ time_t file_changed = file_info.st_mtim.tv_sec;
+ if (file_changed > nav->last_change) {
+ nav->last_change = file_changed;
return 1;
}
}
@@ -297,7 +282,7 @@ size_t imv_navigator_length(struct imv_navigator *nav)
char *imv_navigator_at(struct imv_navigator *nav, int index)
{
- if(index >= 0 && index < nav->num_paths) {
+ if (index >= 0 && index < nav->num_paths) {
return nav->paths[index];
}
return NULL;