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 264bda273d
commit 5a5fc04da4
3 changed files with 48 additions and 40 deletions

View File

@ -221,27 +221,6 @@ local function project_scan_add_entry(dir, fileinfo)
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)
return a.filename == b.filename and a.type == b.type
end
@ -277,24 +256,30 @@ local function files_list_replace(as, i1, n, bs)
end
end
local function project_subdir_bounds(dir, filename)
local index, n = 0, #dir.files
for i, file in ipairs(dir.files) do
local file = dir.files[i]
if file.filename == filename then
index, n = i, #dir.files - i
for j = 1, #dir.files - i do
if not common.path_belongs_to(dir.files[i + j].filename, filename) then
n = j - 1
break
end
end
return index, n, file
end
end
end
local function rescan_project_subdir(dir, filename_rooted)
local new_files = get_directory_files(dir.name, filename_rooted, {}, true, coroutine.yield)
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)
for i, file in ipairs(dir.files) do
local file = dir.files[i]
if file.filename == filename then
index, n = i, #dir.files - i
for j = 1, #dir.files - i do
if not common.path_belongs_to(dir.files[i + j].filename, filename) then
n = j - 1
break
end
end
break
end
end
index, n = project_subdir_bounds(dir, filename)
end
if not files_list_match(dir.files, index, n, new_files) then
@ -304,6 +289,17 @@ local function rescan_project_subdir(dir, filename_rooted)
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.
-- Filter files and yields file's directory and info table. This latter
-- is filled to be like required by project directories "files" list.
@ -1057,10 +1053,13 @@ function core.dir_rescan_add_job(dir, filepath)
local dirpath_rooted = dirpath and PATHSEP .. dirpath or ""
local abs_dirpath = dir.name .. dirpath_rooted
if dirpath then
local _, dir_match = file_search(dir.files, {filename = dirpath, type = "dir"})
if not dir_match then return end
-- check if the directory is in the project files list, if not exit
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
local new_time = system.get_time() + 1
-- evaluate new rescan request versus existing rescan
local remove_list = {}
for _, rescan in pairs(scheduled_rescan) do
if abs_dirpath == rescan.abs_path or common.path_belongs_to(abs_dirpath, rescan.abs_path) then
@ -1068,12 +1067,14 @@ function core.dir_rescan_add_job(dir, filepath)
rescan.time_limit = new_time
return
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)
end
end
for _, key_path in ipairs(remove_list) do
scheduled_rescan[key_path] = nil
end
scheduled_rescan[abs_dirpath] = {dir = dir, path = dirpath_rooted, abs_path = abs_dirpath, time_limit = new_time}
core.add_thread(function()
while true do
@ -1082,6 +1083,7 @@ function core.dir_rescan_add_job(dir, filepath)
if system.get_time() > rescan.time_limit then
local has_changes = rescan_project_subdir(rescan.dir, rescan.path)
if has_changes then
core.redraw = true -- we run without an event, from a thread
rescan.time_limit = new_time
else
scheduled_rescan[rescan.abs_path] = nil

View File

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

View File

@ -14,7 +14,7 @@
`core.scan_project_subdir`: (before was named `core.scan_project_folder`)
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
is added to the project.
@ -24,6 +24,13 @@ New local function `scan_project_folder`:
`core.set_project_dir`:
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`: