Fix a new things about project rescan

Add a flag core.redraw to force redraw when rescan is done.

Inhibit recursion when files_limit is reached.

Still doesn't work correctly for files limited directories.
This commit is contained in:
Francesco Abbate 2021-07-25 15:16:01 +02:00
parent b49422ab02
commit d4943680af
3 changed files with 48 additions and 40 deletions

View File

@ -228,27 +228,6 @@ local function project_scan_add_entry(dir, fileinfo)
end end
function core.scan_project_subdir(dirname, filename)
for _, dir in ipairs(core.project_directories) do
if dir.name == dirname then
for i, file in ipairs(dir.files) do
local file = dir.files[i]
if file.filename == filename then
if file.scanned then return end
local new_files = get_directory_files(dirname, PATHSEP .. filename, {})
for _, new_file in ipairs(new_files) do
-- FIXME: add index bounds to limit the scope of the search.
project_scan_add_entry(dir, new_file)
end
file.scanned = true
return true
end
end
end
end
end
local function files_info_equal(a, b) local function files_info_equal(a, b)
return a.filename == b.filename and a.type == b.type return a.filename == b.filename and a.type == b.type
end end
@ -284,11 +263,8 @@ local function files_list_replace(as, i1, n, bs)
end end
end end
local function rescan_project_subdir(dir, filename_rooted) local function project_subdir_bounds(dir, filename)
local new_files = get_directory_files(dir.name, filename_rooted, {}, true, coroutine.yield)
local index, n = 0, #dir.files local index, n = 0, #dir.files
if filename_rooted ~= "" then
local filename = strip_leading_path(filename_rooted)
for i, file in ipairs(dir.files) do for i, file in ipairs(dir.files) do
local file = dir.files[i] local file = dir.files[i]
if file.filename == filename then if file.filename == filename then
@ -299,11 +275,20 @@ local function rescan_project_subdir(dir, filename_rooted)
break break
end end
end end
break return index, n, file
end end
end end
end end
local function rescan_project_subdir(dir, filename_rooted)
local recursive = not dir.files_limit
local new_files = get_directory_files(dir.name, filename_rooted, {}, recursive, coroutine.yield)
local index, n = 0, #dir.files
if filename_rooted ~= "" then
local filename = strip_leading_path(filename_rooted)
index, n = project_subdir_bounds(dir, filename)
end
if not files_list_match(dir.files, index, n, new_files) then if not files_list_match(dir.files, index, n, new_files) then
files_list_replace(dir.files, index, n, new_files) files_list_replace(dir.files, index, n, new_files)
dir.is_dirty = true dir.is_dirty = true
@ -311,6 +296,17 @@ local function rescan_project_subdir(dir, filename_rooted)
end end
end end
function core.scan_project_subdir(dir, filename)
local index, n, file = project_subdir_bounds(dir, filename)
if index then
local new_files = get_directory_files(dir.name, PATHSEP .. filename, {})
files_list_replace(dir.files, index, n, new_files)
file.scanned = true
return true
end
end
-- Find files and directories recursively reading from the filesystem. -- Find files and directories recursively reading from the filesystem.
-- Filter files and yields file's directory and info table. This latter -- Filter files and yields file's directory and info table. This latter
-- is filled to be like required by project directories "files" list. -- is filled to be like required by project directories "files" list.
@ -1031,10 +1027,13 @@ function core.dir_rescan_add_job(dir, filepath)
local dirpath_rooted = dirpath and PATHSEP .. dirpath or "" local dirpath_rooted = dirpath and PATHSEP .. dirpath or ""
local abs_dirpath = dir.name .. dirpath_rooted local abs_dirpath = dir.name .. dirpath_rooted
if dirpath then if dirpath then
local _, dir_match = file_search(dir.files, {filename = dirpath, type = "dir"}) -- check if the directory is in the project files list, if not exit
if not dir_match then return end local dir_index, dir_match = file_search(dir.files, {filename = dirpath, type = "dir"})
if not dir_match or (dir.files_limit and not dir.files[dir_index].scanned) then return end
end end
local new_time = system.get_time() + 1 local new_time = system.get_time() + 1
-- evaluate new rescan request versus existing rescan
local remove_list = {} local remove_list = {}
for _, rescan in pairs(scheduled_rescan) do for _, rescan in pairs(scheduled_rescan) do
if abs_dirpath == rescan.abs_path or common.path_belongs_to(abs_dirpath, rescan.abs_path) then if abs_dirpath == rescan.abs_path or common.path_belongs_to(abs_dirpath, rescan.abs_path) then
@ -1042,12 +1041,14 @@ function core.dir_rescan_add_job(dir, filepath)
rescan.time_limit = new_time rescan.time_limit = new_time
return return
elseif common.path_belongs_to(rescan.abs_path, abs_dirpath) then elseif common.path_belongs_to(rescan.abs_path, abs_dirpath) then
-- abs_dirpath already cover this rescan: add to the list of rescan to be removed
table.insert(remove_list, rescan.abs_path) table.insert(remove_list, rescan.abs_path)
end end
end end
for _, key_path in ipairs(remove_list) do for _, key_path in ipairs(remove_list) do
scheduled_rescan[key_path] = nil scheduled_rescan[key_path] = nil
end end
scheduled_rescan[abs_dirpath] = {dir = dir, path = dirpath_rooted, abs_path = abs_dirpath, time_limit = new_time} scheduled_rescan[abs_dirpath] = {dir = dir, path = dirpath_rooted, abs_path = abs_dirpath, time_limit = new_time}
core.add_thread(function() core.add_thread(function()
while true do while true do
@ -1056,6 +1057,7 @@ function core.dir_rescan_add_job(dir, filepath)
if system.get_time() > rescan.time_limit then if system.get_time() > rescan.time_limit then
local has_changes = rescan_project_subdir(rescan.dir, rescan.path) local has_changes = rescan_project_subdir(rescan.dir, rescan.path)
if has_changes then if has_changes then
core.redraw = true -- we run without an event, from a thread
rescan.time_limit = new_time rescan.time_limit = new_time
else else
scheduled_rescan[rescan.abs_path] = nil scheduled_rescan[rescan.abs_path] = nil

View File

@ -215,8 +215,7 @@ function TreeView:on_mouse_pressed(button, x, y, clicks)
create_directory_in(hovered_item) create_directory_in(hovered_item)
else else
if hovered_item.dir.files_limit and not hovered_item.expanded then if hovered_item.dir.files_limit and not hovered_item.expanded then
local dirname = hovered_item.dir.name core.scan_project_subdir(hovered_item.dir, hovered_item.filename)
core.scan_project_subdir(dirname, hovered_item.filename)
end end
hovered_item.expanded = not hovered_item.expanded hovered_item.expanded = not hovered_item.expanded
end end

View File

@ -14,7 +14,7 @@
`core.scan_project_subdir`: (before was named `core.scan_project_folder`) `core.scan_project_subdir`: (before was named `core.scan_project_folder`)
scan a single folder, without recursion. Used when too many files. scan a single folder, without recursion. Used when too many files.
New local function `scan_project_folder`: Local function `scan_project_folder`:
Populate the project folder top directory. Done only once when the directory Populate the project folder top directory. Done only once when the directory
is added to the project. is added to the project.
@ -24,6 +24,13 @@ New local function `scan_project_folder`:
`core.set_project_dir`: `core.set_project_dir`:
Set the initial project directory. Set the initial project directory.
`core.dir_rescan_add_job`:
Add a job to rescan after an elapsed time a project's subdirectory to fix for any
changes.
Local function `rescan_project_subdir`:
Rescan a project's subdirectory, compare to the current version and patch the list if
a difference is found.
`core.project_scan_thread`: `core.project_scan_thread`: