Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: features option to enable performance impacting non-essential features #816

Merged
merged 2 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src/uosc.conf
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,12 @@ color=
# This does not affect any text, which is always rendered fully opaque. Defaults:
# timeline=0.9,position=1,chapters=0.8,slider=0.9,slider_gauge=1,controls=0,speed=0.6,menu=1,submenu=0.4,border=1,title=1,tooltip=1,thumbnail=1,curtain=0.8,idle_indicator=0.8,audio_indicator=0.5,buffering_indicator=0.3,playlist_position=0.8
opacity=
# Use a faster estimation method instead of accurate measurement
# setting this to `no` might have a noticeable impact on performance, especially in large menus.
text_width_estimation=yes
# A comma delimited list of features to refine at a cost of some performance impact.
# text_width - Use a more accurate text width measurement that measures each text string individually
# instead of just measuring the width of known letters once and adding them up.
# sorting - Use filename sorting that handles non-english languages better, especially asian ones.
# At the moment, this is only available on windows, and has no effect on other platforms.
refine=
# Duration of animations in milliseconds
animation_duration=100
# Execute command for background clicks shorter than this number of milliseconds, 0 to disable
Expand Down
4 changes: 2 additions & 2 deletions src/uosc/lib/menus.lua
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,8 @@ function open_file_navigation_menu(directory_path, handle_select, opts)

if not files or not directories then return end

sort_filenames(directories)
sort_filenames(files)
sort_strings(directories)
sort_strings(files)

-- Pre-populate items with parent directory selector if not at root
-- Each item value is a serialized path table it points to.
Expand Down
2 changes: 1 addition & 1 deletion src/uosc/lib/text.lua
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ do
---@type boolean, boolean
local bold, italic = opts.bold or options.font_bold, opts.italic or false

if options.text_width_estimation then
if config.refine.text_width then
---@type {[string|number]: {[1]: number, [2]: integer}}
local text_width = get_cache_stage(width_cache, bold)
local width_px = text_width[text]
Expand Down
123 changes: 59 additions & 64 deletions src/uosc/lib/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,85 +6,80 @@
--- In place sorting of filenames
---@param filenames string[]

----- winapi start -----
-- in windows system, we can use the sorting function provided by the win32 API
-- see https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-strcmplogicalw
-- this function was taken from https://github.com/mpvnet-player/mpv.net/issues/575#issuecomment-1817413401
local winapi = {}

if state.platform == 'windows' then
-- is_ffi_loaded is false usually means the mpv builds without luajit
local is_ffi_loaded, ffi = pcall(require, 'ffi')

if is_ffi_loaded then
winapi = {
ffi = ffi,
C = ffi.C,
CP_UTF8 = 65001,
shlwapi = ffi.load('shlwapi'),
}

-- ffi code from https://github.com/po5/thumbfast, Mozilla Public License Version 2.0
ffi.cdef[[
int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr,
int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
int __stdcall StrCmpLogicalW(wchar_t *psz1, wchar_t *psz2);
]]
-- String sorting
do
----- winapi start -----
-- in windows system, we can use the sorting function provided by the win32 API
-- see https://learn.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-strcmplogicalw
-- this function was taken from https://github.com/mpvnet-player/mpv.net/issues/575#issuecomment-1817413401
local winapi = nil

if state.platform == 'windows' and config.refine.sorting then
-- is_ffi_loaded is false usually means the mpv builds without luajit
local is_ffi_loaded, ffi = pcall(require, 'ffi')

if is_ffi_loaded then
winapi = {
ffi = ffi,
C = ffi.C,
CP_UTF8 = 65001,
shlwapi = ffi.load('shlwapi'),
}

-- ffi code from https://github.com/po5/thumbfast, Mozilla Public License Version 2.0
ffi.cdef [[
int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr,
int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar);
int __stdcall StrCmpLogicalW(wchar_t *psz1, wchar_t *psz2);
]]

winapi.utf8_to_wide = function(utf8_str)
if utf8_str then
local utf16_len = winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, utf8_str, -1, nil, 0)
winapi.utf8_to_wide = function(utf8_str)
if utf8_str then
local utf16_len = winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, utf8_str, -1, nil, 0)

if utf16_len > 0 then
local utf16_str = winapi.ffi.new('wchar_t[?]', utf16_len)
if utf16_len > 0 then
local utf16_str = winapi.ffi.new('wchar_t[?]', utf16_len)

if winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, utf8_str, -1, utf16_str, utf16_len) > 0 then
return utf16_str
if winapi.C.MultiByteToWideChar(winapi.CP_UTF8, 0, utf8_str, -1, utf16_str, utf16_len) > 0 then
return utf16_str
end
end
end
end

return ''
return ''
end
end
end
end
----- winapi end -----

function sort_filenames_windows(filenames)
table.sort(filenames, function(a, b)
local a_wide = winapi.utf8_to_wide(a)
local b_wide = winapi.utf8_to_wide(b)
return winapi.shlwapi.StrCmpLogicalW(a_wide, b_wide) == -1
end)

return filenames
end
----- winapi end -----

function sort_filenames_lua(filenames)
-- alphanum sorting for humans in Lua
-- http://notebook.kulchenko.com/algorithms/alphanumeric-natural-sorting-for-humans-in-lua
local function padnum(n, d)
return #d > 0 and ('%03d%s%.12f'):format(#n, n, tonumber(d) / (10 ^ #d))
or ('%03d%s'):format(#n, n)
end

local tuples = {}
for i, f in ipairs(filenames) do
tuples[i] = {f:lower():gsub('0*(%d+)%.?(%d*)', padnum), f}
end
table.sort(tuples, function(a, b)
return a[1] == b[1] and #b[2] < #a[2] or a[1] < b[1]
end)
for i, tuple in ipairs(tuples) do filenames[i] = tuple[2] end
return filenames
end

function sort_filenames(filenames)
local is_ffi_loaded = pcall(require, 'ffi')
if state.platform == 'windows' and is_ffi_loaded then
sort_filenames_windows(filenames)
else
sort_filenames_lua(filenames)
local function sort_lua(strings)
local tuples = {}
for i, f in ipairs(strings) do
tuples[i] = {f:lower():gsub('0*(%d+)%.?(%d*)', padnum), f}
end
table.sort(tuples, function(a, b)
return a[1] == b[1] and #b[2] < #a[2] or a[1] < b[1]
end)
for i, tuple in ipairs(tuples) do strings[i] = tuple[2] end
return strings
end

---@param strings string[]
function sort_strings(strings)
if winapi then
table.sort(strings, function(a, b)
return winapi.shlwapi.StrCmpLogicalW(winapi.utf8_to_wide(a), winapi.utf8_to_wide(b)) == -1
end)
else
sort_lua(strings)
end
end
end

Expand Down Expand Up @@ -465,7 +460,7 @@ function get_adjacent_files(file_path, opts)
if not current_meta then return end
local files = read_directory(current_meta.dirname, {hidden = opts.hidden})
if not files then return end
sort_filenames(files)
sort_strings(files)
local current_file_index
local paths = {}
for _, file in ipairs(files) do
Expand Down
5 changes: 3 additions & 2 deletions src/uosc/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ defaults = {
color = '',
opacity = '',
animation_duration = 100,
text_width_estimation = true,
refine = '',
pause_on_click_shorter_than = 0, -- deprecated by below
click_threshold = 0,
click_command = 'cycle pause; script-binding uosc/flash-pause-indicator',
Expand Down Expand Up @@ -175,6 +175,7 @@ config = {
osd_margin_y = mp.get_property('osd-margin-y'),
osd_alignment_x = mp.get_property('osd-align-x'),
osd_alignment_y = mp.get_property('osd-align-y'),
refine = create_set(comma_split(options.refine)),
types = {
video = comma_split(options.video_types),
audio = comma_split(options.audio_types),
Expand Down Expand Up @@ -542,7 +543,7 @@ function load_file_index_in_current_directory(index)
})

if not files then return end
sort_filenames(files)
sort_strings(files)
if index < 0 then index = #files + index + 1 end

if files[index] then
Expand Down