WIP: advance implementation bot not yet complete
Now we request a watch on the directory and we manage sending and receiving directory change events. The mechanism to update on the fly the directory scan is not complete. The code to remove a file is there but we need to implement the code to add a new file.
This commit is contained in:
parent
31199ecbfc
commit
b2affddf32
|
@ -283,6 +283,43 @@ function core.project_files_number()
|
|||
end
|
||||
|
||||
|
||||
local function file_search(files, filepath)
|
||||
local inf, sup = 1, #files
|
||||
if false then -- FIXME: skipping binary search / it is broken
|
||||
while sup - inf > 8 do
|
||||
local curr = math.floor((inf + sup) / 2)
|
||||
if filepath < files[curr].filename then
|
||||
sup = curr - 1
|
||||
else
|
||||
inf = curr
|
||||
end
|
||||
end
|
||||
end
|
||||
for i = inf, sup do
|
||||
if files[i].filename == filepath then
|
||||
return i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function project_scan_remove_file(watch_id, filepath)
|
||||
local project_dir_entry
|
||||
for i = 1, #core.project_directories do
|
||||
if core.project_directories[i].watch_id == watch_id then
|
||||
project_dir_entry = core.project_directories[i]
|
||||
end
|
||||
end
|
||||
print("LOOKING for", filepath, " in", project_dir_entry and project_dir_entry.name)
|
||||
local index = project_dir_entry and file_search(project_dir_entry.files, filepath)
|
||||
if index then
|
||||
print("FOUND", filepath, " at index", index)
|
||||
table.remove(files, index)
|
||||
project_dir_entry.is_dirty = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- create a directory using mkdir but may need to create the parent
|
||||
-- directories as well.
|
||||
local function create_user_directory()
|
||||
|
@ -380,10 +417,13 @@ function core.add_project_directory(path)
|
|||
-- will be simply the name of the directory, without its path.
|
||||
-- The field item.topdir will identify it as a top level directory.
|
||||
path = normalize_path(path)
|
||||
local watch_id = system.watch_dir(path);
|
||||
table.insert(core.project_directories, {
|
||||
name = path,
|
||||
item = {filename = common.basename(path), type = "dir", topdir = true},
|
||||
files = {}
|
||||
files = {},
|
||||
is_dirty = true,
|
||||
watch_id = watch_id,
|
||||
})
|
||||
end
|
||||
|
||||
|
@ -890,6 +930,13 @@ function core.try(fn, ...)
|
|||
end
|
||||
|
||||
|
||||
function core.on_dir_change(watch_id, action, filepath)
|
||||
if action == "delete" then
|
||||
project_scan_remove_file(watch_id, filepath)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function core.on_event(type, ...)
|
||||
local did_keymap = false
|
||||
if type == "textinput" then
|
||||
|
@ -925,6 +972,9 @@ function core.on_event(type, ...)
|
|||
end
|
||||
elseif type == "focuslost" then
|
||||
core.root_view:on_focus_lost(...)
|
||||
elseif type == "dirchange" then
|
||||
print("DEBUG: dirchange", select(1, ...), select(2, ...), select(3, ...))
|
||||
core.on_dir_change(...)
|
||||
elseif type == "quit" then
|
||||
core.quit()
|
||||
end
|
||||
|
|
|
@ -108,11 +108,12 @@ function TreeView:check_cache()
|
|||
if not last_files then
|
||||
self.last[dir.name] = dir.files
|
||||
else
|
||||
if dir.files ~= last_files then
|
||||
if dir.is_dirty or dir.files ~= last_files then
|
||||
self:invalidate_cache(dir.name)
|
||||
self.last[dir.name] = dir.files
|
||||
end
|
||||
end
|
||||
dir.is_dirty = false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "api.h"
|
||||
#include "dmon.h"
|
||||
#include "dirmonitor.h"
|
||||
#include "rencache.h"
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
|
@ -223,6 +223,14 @@ top:
|
|||
lua_pushnumber(L, e.wheel.y);
|
||||
return 2;
|
||||
|
||||
case SDL_USEREVENT:
|
||||
lua_pushstring(L, "dirchange");
|
||||
lua_pushnumber(L, e.user.code >> 16);
|
||||
lua_pushstring(L, (e.user.code & 0xffff) == DMON_ACTION_DELETE ? "delete" : "create");
|
||||
lua_pushstring(L, e.user.data1);
|
||||
free(e.user.data1);
|
||||
return 4;
|
||||
|
||||
default:
|
||||
goto top;
|
||||
}
|
||||
|
@ -642,30 +650,17 @@ static void watch_callback(dmon_watch_id watch_id, dmon_action action, const cha
|
|||
const char* filepath, const char* oldfilepath, void* user)
|
||||
{
|
||||
(void)(user);
|
||||
(void)(watch_id);
|
||||
|
||||
switch (action) {
|
||||
case DMON_ACTION_CREATE:
|
||||
printf("CREATE: [%s]%s\n", rootdir, filepath);
|
||||
break;
|
||||
case DMON_ACTION_DELETE:
|
||||
printf("DELETE: [%s]%s\n", rootdir, filepath);
|
||||
break;
|
||||
case DMON_ACTION_MODIFY:
|
||||
printf("MODIFY: [%s]%s\n", rootdir, filepath);
|
||||
break;
|
||||
case DMON_ACTION_MOVE:
|
||||
printf("MOVE: [%s]%s -> [%s]%s\n", rootdir, oldfilepath, rootdir, filepath);
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
(void)(rootdir);
|
||||
dirmonitor_push_event(watch_id, action, filepath, oldfilepath);
|
||||
}
|
||||
|
||||
static int f_watch_dir(lua_State *L) {
|
||||
const char *path = luaL_checkstring(L, 1);
|
||||
dmon_watch(path, watch_callback, DMON_WATCHFLAGS_RECURSIVE, NULL);
|
||||
// FIXME: we ignore the watch id and if there is an error.
|
||||
return 0;
|
||||
fprintf(stderr, "DEBUG: watching dir: %s\n", path); fflush(stderr);
|
||||
dmon_watch_id watch_id = dmon_watch(path, watch_callback, DMON_WATCHFLAGS_RECURSIVE, NULL);
|
||||
lua_pushnumber(L, watch_id.id);
|
||||
// FIXME: we ignore if there is an error.
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
13
src/main.c
13
src/main.c
|
@ -18,12 +18,10 @@
|
|||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#define DMON_IMPL
|
||||
#include "dmon.h"
|
||||
#include "dirmonitor.h"
|
||||
|
||||
|
||||
SDL_Window *window;
|
||||
Uint32 dmon_event_no;
|
||||
|
||||
static double get_scale(void) {
|
||||
#ifdef _WIN32
|
||||
|
@ -136,12 +134,7 @@ int main(int argc, char **argv) {
|
|||
SDL_DisplayMode dm;
|
||||
SDL_GetCurrentDisplayMode(0, &dm);
|
||||
|
||||
dmon_init();
|
||||
dmon_event_no = SDL_RegisterEvents(1);
|
||||
if (dmon_event_no == (Uint32)-1) {
|
||||
fprintf(stderr, "internal error registering SDL dmon event.\n");
|
||||
exit(1);
|
||||
}
|
||||
dirmonitor_init();
|
||||
|
||||
window = SDL_CreateWindow(
|
||||
"", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, dm.w * 0.8, dm.h * 0.8,
|
||||
|
@ -222,7 +215,7 @@ init_lua:
|
|||
|
||||
lua_close(L);
|
||||
ren_free_window_resources();
|
||||
dmon_deinit();
|
||||
dirmonitor_deinit();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ lite_sources = [
|
|||
'api/regex.c',
|
||||
'api/system.c',
|
||||
'api/process.c',
|
||||
'dirmonitor.c',
|
||||
'renderer.c',
|
||||
'renwindow.c',
|
||||
'fontdesc.c',
|
||||
|
|
Loading…
Reference in New Issue