Skip to content

Commit b1c6835

Browse files
committed
Normalizing paths and file extensions.
Fixed files innocently sometimes being treated as text files. Fixed some incorrect documentation.
1 parent 7d732d0 commit b1c6835

File tree

1 file changed

+54
-38
lines changed

1 file changed

+54
-38
lines changed

hotLoader.lua

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ local stateHasBeenReset = false
167167

168168

169169

170+
local DIRECTORY_SEPARATOR, TEMPLATE_SEPARATOR, SUBSTITUTION_POINT = package.config:match"^(%C)\n(%C)\n(%C)\n" -- Hopefully each line has a single character!
171+
DIRECTORY_SEPARATOR = DIRECTORY_SEPARATOR or "/"
172+
TEMPLATE_SEPARATOR = TEMPLATE_SEPARATOR or ";"
173+
SUBSTITUTION_POINT = SUBSTITUTION_POINT or "?"
174+
175+
176+
170177
--==============================================================
171178
--= Local Functions ============================================
172179
--==============================================================
@@ -198,8 +205,12 @@ end
198205

199206

200207

208+
local function normalizePath(path)
209+
return (path:gsub("\\", "/"))
210+
end
211+
201212
local function isPathAbsolute(path)
202-
return (path:find"^[/\\]" or path:find"^%a:") ~= nil
213+
return (path:find"^~?/" or path:find"^%a:") ~= nil
203214
end
204215

205216

@@ -228,7 +239,7 @@ local function fileExists(path)
228239
end
229240
end
230241

231-
local file = io.open(path, "r")
242+
local file = io.open(path, "rb")
232243
if not file then return false end
233244

234245
file:close()
@@ -247,8 +258,9 @@ local getCurrentClock
247258

248259

249260

250-
-- contents, errorMessage = getFileContents( path )
251-
local function getFileContents(path)
261+
-- contents = readFile( path )
262+
-- Returns nil and a message on error.
263+
local function readFile(path)
252264
if isLovePath(path) then
253265
return love.filesystem.read(path)
254266
end
@@ -262,17 +274,20 @@ local function getFileContents(path)
262274
return contents
263275
end
264276

265-
-- chunk, errorMessage = loadLuaFile( path )
277+
-- chunk = loadLuaFile( path )
278+
-- Returns nil and a message on error.
266279
local loadLuaFile = love and love.filesystem.load or loadfile
267280

268281

269282

270283
-- templates = getRequirePath( )
271284
-- templates = "template1;..."
272285
local getRequirePath
273-
= love and love.filesystem.getRequirePath
286+
= love and function()
287+
return normalizePath(love.filesystem.getRequirePath())
288+
end
274289
or function()
275-
return package.path
290+
return normalizePath(package.path)
276291
end
277292

278293

@@ -286,16 +301,11 @@ end
286301
-- path = getModuleFilePath( moduleName )
287302
local getModuleFilePath
288303
do
289-
local dirSep, tempSep, subPoint = package.config:match"^(%C)\n(%C)\n(%C)\n" -- Hopefully each line has a single character!
290-
dirSep = dirSep or "/"
291-
tempSep = tempSep or ";"
292-
subPoint = subPoint or "?"
293-
294-
local TEMPLATE_PATTERN = "[^" .. escapePattern(tempSep) .. "]+"
295-
local SUBSTITUTION_POINT_PATTERN = escapePattern(subPoint)
304+
local TEMPLATE_PATTERN = "[^" .. escapePattern(TEMPLATE_SEPARATOR) .. "]+"
305+
local SUBSTITUTION_POINT_PATTERN = escapePattern(SUBSTITUTION_POINT)
296306

297307
local modulePaths = {--[[ [moduleName1]=path, ... ]]}
298-
local moduleNameModifications = {["."]=dirSep:gsub("%%", "%%%%"), ["%"]="%%%%"}
308+
local moduleNameModifications = {["."]="/", ["%"]="%%%%"}
299309

300310
--[[local]] function getModuleFilePath(moduleName)
301311
local path = modulePaths[moduleName]
@@ -319,7 +329,8 @@ end
319329

320330

321331

322-
-- time, errorMessage = getLastModifiedTime( path )
332+
-- time = getLastModifiedTime( path )
333+
-- Returns nil and a message on error.
323334
local fakeModifiedTimes = {}
324335
local fileSizes = {}
325336

@@ -345,7 +356,7 @@ local getLastModifiedTime
345356
-- If the size changed then we generate a fake modification time.
346357
-- @Incomplete: Do this if neither LÖVE nor LuaFileSystem is available.
347358

348-
local file, err = io.open(path, "r")
359+
local file, err = io.open(path, "rb")
349360
if not file then
350361
fakeModifiedTimes[path] = nil
351362
return nil, "Could not determine file modification time."
@@ -373,7 +384,8 @@ local getLastModifiedTime
373384
return require"lfs".attributes(path, "modification")
374385
end
375386

376-
-- time, errorMessage = getModuleLastModifiedTime( moduleName )
387+
-- time = getModuleLastModifiedTime( moduleName )
388+
-- Returns nil and a message on error.
377389
local function getModuleLastModifiedTime(moduleName)
378390
return getLastModifiedTime(getModuleFilePath(moduleName))
379391
end
@@ -403,14 +415,14 @@ end
403415

404416

405417

406-
-- resource, errorMessage = loadResource( path, protected )
407-
-- protected: If true then errors are returned, otherwise errors are raised.
418+
-- resource = loadResource( path, protected )
419+
-- Returns nil and a message on error (if protected is true, otherwise errors are raised).
408420
local function loadResource(path, protected)
409421
local loader
410422
= customLoaders[path]
411-
or loaders[path:match"%.([^.]+)$"]
423+
or loaders[(path:match"%.([^.]+)$" or ""):lower()]
412424
or defaultLoader
413-
or getFileContents
425+
or readFile
414426

415427
local res
416428

@@ -734,17 +746,17 @@ local function createAndRegisterWatcher(level, watchers, id, path, value)
734746
if not baseDir then
735747
errorf(1+level, "Could not get base directory for file '%s'. (%s)", path, err)
736748
end
737-
watcher.fullPath = baseDir .. "/" .. path -- @Polish: Use OS-specific separator.
749+
watcher.fullPath = baseDir .. "/" .. path
738750

739751
elseif isPathAbsolute(path) then
740752
watcher.fullPath = path
741753

742754
else
743-
watcher.fullPath = (love and love.filesystem.getWorkingDirectory() or assert(require"lfs".currentdir())) .. "/" .. path -- @Polish: Use OS-specific separator.
755+
watcher.fullPath = (love and love.filesystem.getWorkingDirectory() or assert(require"lfs".currentdir())) .. "/" .. path
744756
end
745757

746-
local dir = watcher.fullPath:gsub("[/\\][^/\\]+$", "")
747-
if dir == "" then dir = "/" end -- @Polish: Use OS-specific separator.
758+
local dir = watcher.fullPath:gsub("/[^/]+$", "")
759+
if dir == "" then dir = "/" end
748760
assert(dir ~= watcher.fullPath, dir)
749761

750762
local dirWatcher = ffiWindows_watchedDirectories[dir]
@@ -970,12 +982,12 @@ end
970982

971983
-- loader = getLoader( fileExtension )
972984
function hotLoader.getLoader(fileExt)
973-
return loaders[fileExt]
985+
return loaders[fileExt:lower()]
974986
end
975987

976-
-- Set or remove a loader for a file extension.
977988
-- setLoader( fileExtension, [ fileExtension2..., ] loader|nil )
978-
-- loader: function( fileContents, path )
989+
-- resource = loader( path )
990+
-- Set or remove a loader for a file extension.
979991
function hotLoader.setLoader(...)
980992
local argCount = math.max(select("#", ...), 1)
981993
local loader = select(argCount, ...)
@@ -991,7 +1003,7 @@ function hotLoader.setLoader(...)
9911003
if type(fileExt) ~= "string" then
9921004
errorf(2, "Bad argument #%d (fileExtension) to 'setLoader'. (Expected string, got %s)", i, type(fileExt))
9931005
end
994-
loaders[fileExt] = loader
1006+
loaders[fileExt:lower()] = loader
9951007
end
9961008
end
9971009

@@ -1002,12 +1014,12 @@ end
10021014

10031015
-- loader|nil = getCustomLoader( path )
10041016
function hotLoader.getCustomLoader(path)
1005-
return customLoaders[path]
1017+
return customLoaders[normalizePath(path)]
10061018
end
10071019

1008-
-- Set or remove a loader for a specific file path.
10091020
-- setCustomLoader( path, [ path2..., ] loader|nil )
1010-
-- loader: function( fileContents, path )
1021+
-- resource = loader( path )
1022+
-- Set or remove a loader for a specific file path.
10111023
function hotLoader.setCustomLoader(...)
10121024
local argCount = math.max(select("#", ...), 1)
10131025
local loader = select(argCount, ...)
@@ -1023,7 +1035,7 @@ function hotLoader.setCustomLoader(...)
10231035
if type(path) ~= "string" then
10241036
errorf(2, "Bad argument #%d (path) to 'setCustomLoader'. (Expected string, got %s)", i, type(path))
10251037
end
1026-
customLoaders[path] = loader
1038+
customLoaders[normalizePath(path)] = loader
10271039
end
10281040
end
10291041

@@ -1053,14 +1065,16 @@ end
10531065

10541066

10551067

1056-
-- resource, errorMessage = load( path [, protectedLoad=false ] [, customLoader ] )
1057-
-- protected: If true then errors are returned, otherwise errors are raised.
1068+
-- resource = load( path [, protectedLoad=false ] [, customLoader ] )
1069+
-- Returns nil and a message on error (if protected is true, otherwise errors are raised).
10581070
-- customLoader: If set, replaces the previous custom loader for path.
10591071
function hotLoader.load(path, protected, loader)
10601072
if type(protected) == "function" then
10611073
protected, loader = false, protected
10621074
end
10631075

1076+
path = normalizePath(path)
1077+
10641078
if loader then
10651079
hotLoader.setCustomLoader(path, loader)
10661080
end
@@ -1080,7 +1094,7 @@ end
10801094
-- Forces the resource to reload at next load call.
10811095
-- unload( path )
10821096
function hotLoader.unload(path)
1083-
unregisterWatcher(watchedResources, watchedResources[path])
1097+
unregisterWatcher(watchedResources, watchedResources[normalizePath(path)])
10841098
end
10851099

10861100
-- preload( path, resource [, customLoader ] )
@@ -1090,6 +1104,8 @@ function hotLoader.preload(path, res, loader)
10901104
return
10911105
end
10921106

1107+
path = normalizePath(path)
1108+
10931109
if loader then
10941110
hotLoader.setCustomLoader(path, loader)
10951111
end
@@ -1106,7 +1122,7 @@ end
11061122

11071123
-- bool = hasLoaded( path )
11081124
function hotLoader.hasLoaded(path)
1109-
return watchedResources[path] ~= nil
1125+
return watchedResources[normalizePath(path)] ~= nil
11101126
end
11111127

11121128

0 commit comments

Comments
 (0)