2004-05-08 03:11:51 +02:00
|
|
|
#include "precompiled.h"
|
2004-05-13 19:23:07 +02:00
|
|
|
|
|
|
|
#include "res.h"
|
2005-02-27 20:11:39 +01:00
|
|
|
#include "file.h" // file_make_native_path, file_invalidate_cache
|
2004-06-11 04:14:18 +02:00
|
|
|
#include "timer.h"
|
2004-10-06 16:00:43 +02:00
|
|
|
#include "hotload.h" // we implement that interface
|
2004-05-13 19:23:07 +02:00
|
|
|
|
2004-07-31 21:35:22 +02:00
|
|
|
#include "sysdep/dir_watch.h"
|
2004-06-04 19:44:56 +02:00
|
|
|
|
2004-06-18 20:56:10 +02:00
|
|
|
#include <string.h>
|
2004-06-04 19:44:56 +02:00
|
|
|
|
2004-10-06 16:00:43 +02:00
|
|
|
|
2005-02-27 20:11:39 +01:00
|
|
|
// called from res_reload_changed_files and via console.
|
2004-12-10 00:12:02 +01:00
|
|
|
int res_reload(const char* fn)
|
2004-05-13 19:23:07 +02:00
|
|
|
{
|
2005-02-27 20:11:39 +01:00
|
|
|
// if <fn> currently maps to an archive, the VFS must switch
|
|
|
|
// over to using the loose file (that was presumably changed).
|
2005-02-27 15:35:38 +01:00
|
|
|
vfs_rebuild();
|
2005-02-27 20:11:39 +01:00
|
|
|
|
|
|
|
// invalidate this file's cached blocks to make sure its contents are
|
|
|
|
// loaded anew.
|
|
|
|
file_invalidate_cache(fn);
|
|
|
|
|
2004-05-13 19:23:07 +02:00
|
|
|
return h_reload(fn);
|
2004-05-24 22:25:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-12-10 00:12:02 +01:00
|
|
|
int res_watch_dir(const char* path, intptr_t* watch)
|
2004-06-04 19:44:56 +02:00
|
|
|
{
|
2004-08-11 22:20:03 +02:00
|
|
|
char n_path[PATH_MAX];
|
2004-12-01 19:44:38 +01:00
|
|
|
CHECK_ERR(file_make_full_native_path(path, n_path));
|
2004-08-11 22:20:03 +02:00
|
|
|
return dir_add_watch(n_path, watch);
|
2004-06-04 19:44:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-08 16:33:58 +02:00
|
|
|
int res_cancel_watch(const intptr_t watch)
|
2004-06-08 17:18:01 +02:00
|
|
|
{
|
2004-07-31 21:35:22 +02:00
|
|
|
return dir_cancel_watch(watch);
|
2004-06-08 17:18:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-02-27 20:11:39 +01:00
|
|
|
// get directory change notifications, and reload all affected files.
|
|
|
|
// must be called regularly (e.g. once a frame). this is much simpler
|
|
|
|
// than asynchronous notifications: everything would need to be thread-safe.
|
2004-06-04 19:44:56 +02:00
|
|
|
int res_reload_changed_files()
|
|
|
|
{
|
2004-08-14 14:28:54 +02:00
|
|
|
char n_path[PATH_MAX];
|
|
|
|
while(dir_get_changed_file(n_path) == 0)
|
2004-06-11 04:14:18 +02:00
|
|
|
{
|
2005-02-27 20:11:39 +01:00
|
|
|
// convert to VFS path
|
2004-08-14 14:28:54 +02:00
|
|
|
char p_path[PATH_MAX];
|
2004-12-01 22:34:01 +01:00
|
|
|
CHECK_ERR(file_make_full_portable_path(n_path, p_path));
|
2004-06-11 04:14:18 +02:00
|
|
|
char vfs_path[VFS_MAX_PATH];
|
2004-08-14 14:28:54 +02:00
|
|
|
CHECK_ERR(vfs_make_vfs_path(p_path, vfs_path));
|
2004-06-11 04:14:18 +02:00
|
|
|
|
2005-02-27 20:11:39 +01:00
|
|
|
// various early-out checks that reduce debug output clutter,
|
|
|
|
// avoid the overhead of searching through all Handles, and
|
|
|
|
// try to eliminate repeated reloads:
|
|
|
|
const char* ext = strrchr(vfs_path, '.');
|
|
|
|
// .. ignore directory change notifications, because we get
|
|
|
|
// per-file notifications anyway. (note: assume no extension =>
|
|
|
|
// it's a directory). this also protects the strcmp calls below.
|
|
|
|
if(!ext)
|
2004-08-03 14:56:44 +02:00
|
|
|
continue;
|
2005-02-27 20:11:39 +01:00
|
|
|
// .. ignore files that can't be reloaded anyway.
|
|
|
|
if(!strcmp(ext, ".xmb"))
|
2004-06-11 04:14:18 +02:00
|
|
|
continue;
|
2005-02-27 20:11:39 +01:00
|
|
|
// .. skip temp files, because many apps save by creating a temp
|
|
|
|
// file, deleting the original, and renaming the temp file.
|
|
|
|
// => avoids 2 redundant reloads.
|
|
|
|
if(!strcmp(ext, ".tmp"))
|
2004-06-11 04:14:18 +02:00
|
|
|
continue;
|
|
|
|
|
2005-02-27 20:11:39 +01:00
|
|
|
int ret = res_reload(vfs_path);
|
|
|
|
assert(ret == 0);
|
2004-06-11 04:14:18 +02:00
|
|
|
}
|
2004-06-04 19:44:56 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|