New io library to take file loading inhouse. New io methods for the mod object

This commit is contained in:
Aussiemon 2023-01-08 18:53:05 -07:00
parent e6b0695357
commit 1134babf79
16 changed files with 282 additions and 53 deletions

View file

@ -4,6 +4,7 @@ Contribute to DMF -- add your name here!
+ [Fracticality](https://github.com/fracticality) + [Fracticality](https://github.com/fracticality)
+ [grasmann](https://github.com/grasmann) + [grasmann](https://github.com/grasmann)
+ [philipdestroyer](https://github.com/philippedavid) + [philipdestroyer](https://github.com/philippedavid)
+ [SirAiedail](https://github.com/SirAiedail)
# VMF contributors (sorted alphabetically) # VMF contributors (sorted alphabetically)
+ [Aussiemon](https://github.com/Aussiemon) + [Aussiemon](https://github.com/Aussiemon)

View file

@ -4,7 +4,7 @@ local dmf
local dmf_mod_object = {} local dmf_mod_object = {}
-- Global method to load a file through iowith a return -- Global method to load a file through iowith a return
local mod_dofile = Mods.file.dofile local io_dofile = Mods.file.dofile
-- Global backup of original print() method -- Global backup of original print() method
local print = __print local print = __print
@ -14,35 +14,39 @@ local print = __print
-- ##################################################################################################################### -- #####################################################################################################################
function dmf_mod_object:init() function dmf_mod_object:init()
mod_dofile("dmf/scripts/mods/dmf/modules/dmf_mod_data") io_dofile("dmf/scripts/mods/dmf/modules/dmf_mod_data")
mod_dofile("dmf/scripts/mods/dmf/modules/dmf_mod_manager") io_dofile("dmf/scripts/mods/dmf/modules/dmf_mod_manager")
--mod_dofile("dmf/scripts/mods/dmf/modules/dmf_dummy") --io_dofile("dmf/scripts/mods/dmf/modules/dmf_dummy")
mod_dofile("dmf/scripts/mods/dmf/modules/dmf_package_manager") io_dofile("dmf/scripts/mods/dmf/modules/dmf_package_manager")
mod_dofile("dmf/scripts/mods/dmf/modules/core/safe_calls") io_dofile("dmf/scripts/mods/dmf/modules/core/safe_calls")
mod_dofile("dmf/scripts/mods/dmf/modules/core/events") io_dofile("dmf/scripts/mods/dmf/modules/core/events")
mod_dofile("dmf/scripts/mods/dmf/modules/core/settings") io_dofile("dmf/scripts/mods/dmf/modules/core/settings")
mod_dofile("dmf/scripts/mods/dmf/modules/core/logging") io_dofile("dmf/scripts/mods/dmf/modules/core/logging")
mod_dofile("dmf/scripts/mods/dmf/modules/core/misc") io_dofile("dmf/scripts/mods/dmf/modules/core/misc")
mod_dofile("dmf/scripts/mods/dmf/modules/core/persistent_tables") io_dofile("dmf/scripts/mods/dmf/modules/core/persistent_tables")
mod_dofile("dmf/scripts/mods/dmf/modules/debug/dev_console") io_dofile("dmf/scripts/mods/dmf/modules/core/io")
mod_dofile("dmf/scripts/mods/dmf/modules/debug/table_dump")
mod_dofile("dmf/scripts/mods/dmf/modules/core/hooks")
mod_dofile("dmf/scripts/mods/dmf/modules/core/require")
mod_dofile("dmf/scripts/mods/dmf/modules/core/toggling")
mod_dofile("dmf/scripts/mods/dmf/modules/core/keybindings")
mod_dofile("dmf/scripts/mods/dmf/modules/core/chat")
mod_dofile("dmf/scripts/mods/dmf/modules/core/localization")
mod_dofile("dmf/scripts/mods/dmf/modules/core/options")
mod_dofile("dmf/scripts/mods/dmf/modules/core/network")
mod_dofile("dmf/scripts/mods/dmf/modules/core/commands")
mod_dofile("dmf/scripts/mods/dmf/modules/gui/custom_textures")
mod_dofile("dmf/scripts/mods/dmf/modules/gui/custom_views")
mod_dofile("dmf/scripts/mods/dmf/modules/ui/chat/chat_actions")
mod_dofile("dmf/scripts/mods/dmf/modules/ui/options/mod_options")
mod_dofile("dmf/scripts/mods/dmf/modules/dmf_options")
mod_dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_manager")
-- DMF's internal io module is now loaded:
dmf = get_mod("DMF") dmf = get_mod("DMF")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/debug/dev_console")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/debug/table_dump")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/hooks")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/require")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/toggling")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/keybindings")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/chat")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/localization")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/options")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/network")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/commands")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/gui/custom_textures")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/gui/custom_views")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/chat/chat_actions")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/mod_options")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/dmf_options")
dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_manager")
dmf.delayed_chat_messages_hook() dmf.delayed_chat_messages_hook()
dmf:hook(ModManager, "destroy", function(func, ...) dmf:hook(ModManager, "destroy", function(func, ...)
dmf.mods_unload_event(true) dmf.mods_unload_event(true)

View file

@ -0,0 +1,189 @@
local dmf = get_mod("DMF")
-- Local backup of the io library
local _io = dmf:persistent_table("_io")
_io.initialized = _io.initialized or false
if not _io.initialized then
_io = dmf.deepcopy(Mods.lua.io)
end
local _mod_directory = "./../mods"
-- #####################################################################################################################
-- ##### Local functions ###############################################################################################
-- #####################################################################################################################
-- Build a file path out of the mod directory and the given parameters
local get_file_path = function(local_path, file_name, file_extension)
local file_path = _mod_directory
if local_path and local_path ~= "" then
file_path = file_path .. "/" .. local_path
end
if file_name and file_name ~= "" then
file_path = file_path .. "/" .. file_name
end
if file_extension and file_extension ~= "" then
file_path = file_path .. "." .. file_extension
else
file_path = file_path .. ".lua"
end
if string.find(file_path, "\\") then
file_path = string.gsub(file_path, "\\", "/")
end
return file_path
end
-- Handle an IO operation with respect to safety, execution, and the results returned
local function handle_io(mod, local_path, file_name, file_extension, args, safe_call, execute, return_result)
local file_path = get_file_path(local_path, file_name, file_extension)
mod:debug("Loading " .. file_path)
-- Check for the existence of the path
local ff, err_io = _io.open(file_path, "r")
if ff ~= nil then
ff:close()
-- Initialize variables
local status, result
-- If this is a safe call, wrap it in a pcall
if safe_call then
status, result = pcall(function ()
local f = _io.open(file_path, "r")
local data = f:read("*all")
-- Either execute the data or return it unmodified
local pcall_result
if execute then
local func = loadstring(data)
pcall_result = func(args)
else
pcall_result = data
end
f:close()
if return_result then
return pcall_result
else
return true
end
end)
-- If status is failed, notify the user and return false
if not status then
mod:error("Error processing '" .. file_path .. "': " .. tostring(result))
return false
end
-- If this isn't a safe call, load without a pcall
else
local f = _io.open(file_path, "r")
local data = f:read("*all")
-- Either execute the data or return it unmodified
if execute then
local func = loadstring(data)
result = func(args)
else
result = data
end
f:close()
end
-- Return data if configured
if return_result then
return result
-- Otherwise return success
else
return true
end
-- If the initial open failed, report failure
else
mod:error("Error opening '" .. file_path .. "': " .. tostring(err_io))
return false
end
end
-- Return whether the file exists at the given path
local function file_exists(local_path, file_name, file_extension)
local file_path = get_file_path(local_path, file_name, file_extension)
local f = io.open(file_path,"r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
-- #####################################################################################################################
-- ##### DMFMod ########################################################################################################
-- #####################################################################################################################
-- Use the io library to execute the given file safely, without return
function DMFMod:io_exec(local_path, file_name, file_extension, args)
return handle_io(self, local_path, file_name, file_extension, args, true, true, false)
end
-- Use the io library to execute the given file without return
function DMFMod:io_exec_unsafe(local_path, file_name, file_extension, args)
return handle_io(self, local_path, file_name, file_extension, args, false, true, false)
end
-- Use the io library to execute the given file and return the result
function DMFMod:io_exec_with_return(local_path, file_name, file_extension, args)
return handle_io(self, local_path, file_name, file_extension, args, true, true, true)
end
-- Use the io library to execute the given file unsafely and return the result
function DMFMod:io_exec_unsafe_with_return(local_path, file_name, file_extension, args)
return handle_io(self, local_path, file_name, file_extension, args, false, true, true)
end
-- Use the io library to execute the given file and return the result,
-- but treat the first parameter as the entire path to the file, and assume .lua.
-- IO version of the dofile method.
function DMFMod:io_dofile(file_path)
return handle_io(self, file_path, nil, nil, nil, true, true, true)
end
-- Use the io library to execute the given file unsafely and return the result,
-- but treat the first parameter as the entire path to the file, and assume .lua.
-- IO version of the dofile method.
function DMFMod:io_dofile_unsafe(file_path)
return handle_io(self, file_path, nil, nil, nil, false, true, true)
end
-- Use the io library to return the contents of the given file without execution
function DMFMod:io_read_content(file_path, file_extension)
return handle_io(self, file_path, nil, file_extension, nil, true, false, true)
end
-- #####################################################################################################################
-- ##### Hooks #########################################################################################################
-- #####################################################################################################################
-- #####################################################################################################################
-- ##### DMF internal functions and variables ##########################################################################
-- #####################################################################################################################
-- #####################################################################################################################
-- ##### Script ########################################################################################################
-- #####################################################################################################################

View file

@ -139,5 +139,5 @@ end
-- ##### Script ####################################################################################################### -- ##### Script #######################################################################################################
-- #################################################################################################################### -- ####################################################################################################################
local localization_table = dmf:dofile("dmf/localization/dmf") local localization_table = dmf:io_dofile("dmf/localization/dmf")
dmf.initialize_mod_localization(dmf, localization_table) dmf.initialize_mod_localization(dmf, localization_table)

View file

@ -18,3 +18,20 @@ function dmf.check_wrong_argument_type(mod, dmf_function_name, argument_name, ar
table.concat(allowed_types, "/"), argument_type) table.concat(allowed_types, "/"), argument_type)
return true return true
end end
-- http://lua-users.org/wiki/CopyTable
function dmf.deepcopy(original_table)
local orig_type = type(original_table)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, original_table, nil do
copy[dmf.deepcopy(orig_key)] = dmf.deepcopy(orig_value)
end
setmetatable(copy, dmf.deepcopy(getmetatable(original_table)))
else -- number, string, boolean, etc
copy = original_table
end
return copy
end

View file

@ -26,11 +26,11 @@ local _mutators_sorted = false
local _all_mutators_disabled = false local _all_mutators_disabled = false
-- External modules -- External modules
local reward_manager = dmf:dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_reward") local reward_manager = dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_reward")
local set_lobby_data = dmf:dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_info") local set_lobby_data = dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_info")
-- Get default configuration -- Get default configuration
local _default_config = dmf:dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_default_config") local _default_config = dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/mutators/mutators_default_config")
-- List of enabled mutators in case DMF is reloaded in the middle of the game -- List of enabled mutators in case DMF is reloaded in the middle of the game
local _enabled_mutators = dmf:persistent_table("enabled_mutators") local _enabled_mutators = dmf:persistent_table("enabled_mutators")
@ -504,4 +504,4 @@ end
-- ##################################################################################################################### -- #####################################################################################################################
-- Testing -- Testing
--dmf:dofile("dmf/scripts/mods/dmf/modules/core/mutators/test/mutators_test") --dmf:io_dofile("dmf/scripts/mods/dmf/modules/core/mutators/test/mutators_test")

View file

@ -65,7 +65,7 @@ end
-- Handles the swap to io for registered files and the application of file hooks -- Handles the swap to io for registered files and the application of file hooks
dmf:hook(_G, "require", function (func, path, ...) dmf:hook(_G, "require", function (func, path, ...)
if _io_requires[path] then if _io_requires[path] then
return dmf:dofile(path) return dmf:io_dofile(path)
else else
local result = func(path, ...) local result = func(path, ...)

View file

@ -1,8 +1,5 @@
local dmf = get_mod("DMF") local dmf = get_mod("DMF")
-- Global method to load a file through io with a return
local mod_dofile = Mods.file.dofile
-- Global backup of original print() method -- Global backup of original print() method
local print = __print local print = __print
@ -90,7 +87,17 @@ function dmf.safe_call_dofile(mod, error_prefix_data, file_path)
show_error(mod, error_prefix_data, "file path should be a string.") show_error(mod, error_prefix_data, "file path should be a string.")
return false return false
end end
return dmf.safe_call(mod, error_prefix_data, mod_dofile, file_path) return dmf.safe_call(mod, error_prefix_data, dofile, mod, file_path)
end
-- Safe Call [io_dofile]
function dmf.safe_call_io_dofile(mod, error_prefix_data, file_path)
if type(file_path) ~= "string" then
show_error(mod, error_prefix_data, "file path should be a string.")
return false
end
return dmf.safe_call(mod, error_prefix_data, mod.io_dofile_unsafe, mod, file_path)
end end

View file

@ -4,8 +4,12 @@ local dmf = get_mod("DMF")
-- It would requires hooks to be pushed higher in the loading order, but then we lose hooks printing to console -- It would requires hooks to be pushed higher in the loading order, but then we lose hooks printing to console
-- Unless we find a way to store our logging messages in memory before the console is loaded. -- Unless we find a way to store our logging messages in memory before the console is loaded.
-- Global backup of the ffi library -- Local backup of the ffi library
local _ffi = Mods.lua.ffi local _ffi = dmf:persistent_table("_ffi")
_ffi.initialized = _ffi.initialized or false
if not _ffi.initialized then
_ffi = dmf.deepcopy(Mods.lua.ffi)
end
local _console_data = dmf:persistent_table("dev_console_data") local _console_data = dmf:persistent_table("dev_console_data")
if not _console_data.enabled then _console_data.enabled = false end if not _console_data.enabled then _console_data.enabled = false end

View file

@ -1,11 +1,18 @@
local dmf = get_mod("DMF") -- @TODO: remove it? local dmf = get_mod("DMF") -- @TODO: remove it?
-- Local backup of the io library
local _io = dmf:persistent_table("_io")
_io.initialized = _io.initialized or false
if not _io.initialized then
_io = dmf.deepcopy(Mods.lua.io)
end
-- Global backup of the io library -- Local backup of the io library
local _io = Mods.lua.io local _os = dmf:persistent_table("_os")
_os.initialized = _os.initialized or false
-- Global backup of the os library if not _os.initialized then
local _os = Mods.lua.os _os = dmf.deepcopy(Mods.lua.os)
end
-- Global backup of original print() method -- Global backup of original print() method
local print = __print local print = __print

View file

@ -50,7 +50,7 @@ local function resolve_resource(mod, error_prefix_data, resource, resource_value
local type_value = type(resource_value) local type_value = type(resource_value)
if type_value == "string" then if type_value == "string" then
return dmf.safe_call_dofile(mod, error_prefix_data, resource_value) return dmf.safe_call_io_dofile(mod, error_prefix_data, resource_value)
elseif type_value == "function" then elseif type_value == "function" then
return dmf.safe_call(mod, error_prefix_data, resource_value, mod) return dmf.safe_call(mod, error_prefix_data, resource_value, mod)
elseif type_value == "table" then elseif type_value == "table" then

View file

@ -32,7 +32,7 @@ local _queued_command
local function initialize_drawing_function() local function initialize_drawing_function()
if not _commands_list_gui_draw then if not _commands_list_gui_draw then
local commands_list_gui = dmf:dofile("dmf/scripts/mods/dmf/modules/ui/chat/commands_list_gui") local commands_list_gui = dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/chat/commands_list_gui")
_commands_list_gui_draw = commands_list_gui.draw _commands_list_gui_draw = commands_list_gui.draw
_commands_list_gui_destroy = commands_list_gui.destroy _commands_list_gui_destroy = commands_list_gui.destroy
end end

View file

@ -24,8 +24,8 @@ end
-- ##### DMF Options View Class ####################################################################################### -- ##### DMF Options View Class #######################################################################################
-- #################################################################################################################### -- ####################################################################################################################
local _content_blueprints = dmf:dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_content_blueprints") local _content_blueprints = dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_content_blueprints")
local _view_settings = dmf:dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_settings") local _view_settings = dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_settings")
local InputUtils = require("scripts/managers/input/input_utils") local InputUtils = require("scripts/managers/input/input_utils")
local ScriptWorld = require("scripts/foundation/utilities/script_world") local ScriptWorld = require("scripts/foundation/utilities/script_world")
@ -42,7 +42,7 @@ local SETTINGS_GRID = 2
local DMFOptionsView = class("DMFOptionsView", "BaseView") local DMFOptionsView = class("DMFOptionsView", "BaseView")
DMFOptionsView.init = function (self, settings) DMFOptionsView.init = function (self, settings)
local definitions = dmf:dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_definitions") local definitions = dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_definitions")
DMFOptionsView.super.init(self, definitions, settings) DMFOptionsView.super.init(self, definitions, settings)

View file

@ -1,6 +1,6 @@
local dmf = get_mod("DMF") local dmf = get_mod("DMF")
local _view_settings = dmf:dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_settings") local _view_settings = dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_settings")
local ButtonPassTemplates = require("scripts/ui/pass_templates/button_pass_templates") local ButtonPassTemplates = require("scripts/ui/pass_templates/button_pass_templates")
local CheckboxPassTemplates = require("scripts/ui/pass_templates/checkbox_pass_templates") local CheckboxPassTemplates = require("scripts/ui/pass_templates/checkbox_pass_templates")

View file

@ -1,6 +1,6 @@
local dmf = get_mod("DMF") local dmf = get_mod("DMF")
local _view_settings = dmf:dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_settings") local _view_settings = dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view_settings")
local ScrollbarPassTemplates = require("scripts/ui/pass_templates/scrollbar_pass_templates") local ScrollbarPassTemplates = require("scripts/ui/pass_templates/scrollbar_pass_templates")
local UIFontSettings = require("scripts/managers/ui/ui_font_settings") local UIFontSettings = require("scripts/managers/ui/ui_font_settings")

View file

@ -433,7 +433,7 @@ dmf.initialize_dmf_options_view = function ()
} }
}) })
dmf:dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view") dmf:io_dofile("dmf/scripts/mods/dmf/modules/ui/options/dmf_options_view")
end end
-- #################################################################################################################### -- ####################################################################################################################