Port mod package manager
This commit is contained in:
parent
70e726f090
commit
4b6827f688
3 changed files with 166 additions and 2 deletions
160
vmf/scripts/mods/vmf/modules/core/packages.lua
Normal file
160
vmf/scripts/mods/vmf/modules/core/packages.lua
Normal file
|
@ -0,0 +1,160 @@
|
|||
local vmf = get_mod("VMF")
|
||||
|
||||
local _initialized = false
|
||||
|
||||
local _mod_handles = {}
|
||||
local _queued_packages = {}
|
||||
local _loading_package = nil
|
||||
local _loaded_packages = {}
|
||||
|
||||
function VMFMod:load_package(package_name, callback)
|
||||
if not _initialized then
|
||||
self:error("Package manager has not been initialized yet. It can only be used after the `all_mods_loaded` event has been processed.")
|
||||
return
|
||||
elseif self:has_package_loaded(package_name) then
|
||||
self:error("Package '%s' has already been loaded", package_name)
|
||||
return
|
||||
end
|
||||
|
||||
if not _loaded_packages[self] then
|
||||
_loaded_packages[self] = {}
|
||||
end
|
||||
|
||||
local package_handle = string.format("resource_packages/%s/%s", self:get_name(), package_name)
|
||||
local workshop_id = self:get_internal_data("workshop_id")
|
||||
|
||||
local resource_package = Mod.resource_package(_mod_handles[workshop_id], package_handle)
|
||||
|
||||
local is_loading = self:is_package_loading(package_name)
|
||||
|
||||
if not callback then
|
||||
if not is_loading then
|
||||
resource_package:load()
|
||||
end
|
||||
|
||||
resource_package:flush()
|
||||
|
||||
_loaded_packages[self][package_name] = resource_package
|
||||
|
||||
self:debug("Loaded package '%s' synchronously", package_name)
|
||||
else
|
||||
if is_loading then
|
||||
self:error("Package '%s' is currently loading", package_name)
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(_queued_packages, {
|
||||
mod = self,
|
||||
package_name = package_name,
|
||||
resource_package = resource_package,
|
||||
callback = callback,
|
||||
})
|
||||
self:debug("Queued package '%s'", package_name)
|
||||
end
|
||||
end
|
||||
|
||||
function VMFMod:unload_package(package_name)
|
||||
if not _initialized then
|
||||
self:error("Package manager has not been initialized yet. It can only be used after the `all_mods_loaded` event has been processed.")
|
||||
return
|
||||
end
|
||||
|
||||
if not self:has_package_loaded(package_name) then
|
||||
self:error("Package '%s' has not been loaded", package_name)
|
||||
return
|
||||
end
|
||||
|
||||
local resource_package = _loaded_packages[self][package_name]
|
||||
|
||||
resource_package:unload()
|
||||
Mod.release_resource_package(resource_package)
|
||||
_loaded_packages[self][package_name] = nil
|
||||
|
||||
self:debug("Unloaded package '%s'", package_name)
|
||||
end
|
||||
|
||||
function VMFMod:is_package_loading(package_name)
|
||||
if not _initialized then
|
||||
self:error("Package manager has not been initialized yet. It can only be used after the `all_mods_loaded` event has been processed.")
|
||||
return
|
||||
end
|
||||
|
||||
if _loading_package and _loading_package.mod == self and _loading_package.package_name == package_name then
|
||||
return true
|
||||
end
|
||||
|
||||
for _, queued_package in ipairs(_queued_packages) do
|
||||
if queued_package.mod == self and queued_package.package_name == package_name then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function VMFMod:has_package_loaded(package_name)
|
||||
if not _initialized then
|
||||
self:error("Package manager has not been initialized yet. It can only be used after the `all_mods_loaded` event has been processed.")
|
||||
return
|
||||
end
|
||||
|
||||
local loaded_packages = _loaded_packages[self]
|
||||
return loaded_packages and loaded_packages[package_name] ~= nil
|
||||
end
|
||||
|
||||
function VMFMod:is_package_manager_initialized()
|
||||
return _initialized
|
||||
end
|
||||
|
||||
function vmf.initialize_package_manager()
|
||||
vmf:debug("Initializing package manager")
|
||||
|
||||
for _, mod_data in ipairs(Managers.mod._mods) do
|
||||
_mod_handles[mod_data.id] = mod_data.handle
|
||||
end
|
||||
|
||||
_initialized = true
|
||||
end
|
||||
|
||||
function vmf.update_package_manager()
|
||||
local loading_package = _loading_package
|
||||
|
||||
if loading_package then
|
||||
if loading_package.resource_package:has_loaded() then
|
||||
vmf:debug("Finished loading package '%s/%s' asynchronously", loading_package.mod:get_name(), loading_package.package_name)
|
||||
_loaded_packages[loading_package.mod][loading_package.package_name] = loading_package.resource_package
|
||||
_loading_package = nil
|
||||
|
||||
-- The callback has to be called last, so that any calls to `has_package_loaded` or `is_package_loading` return the correct value
|
||||
loading_package.callback()
|
||||
else
|
||||
vmf:debug("Package '%s/%s' is still loading asynchronously", loading_package.mod:get_name(), loading_package.package_name)
|
||||
end
|
||||
|
||||
return
|
||||
-- else
|
||||
-- vmf:debug("No package to load asynchronously")
|
||||
end
|
||||
|
||||
local queued_package = _queued_packages[1]
|
||||
|
||||
if queued_package then
|
||||
_loading_package = queued_package
|
||||
table.remove(_queued_packages, 1)
|
||||
|
||||
_loading_package.resource_package:load()
|
||||
vmf:debug("Started loading package '%s/%s' asynchronously", _loading_package.mod:get_name(), _loading_package.package_name)
|
||||
end
|
||||
end
|
||||
|
||||
function VMFMod:dump_package_manager()
|
||||
self:debug("initialized = %s", _initialized)
|
||||
self:dump(_mod_handles, "_mod_handles", 2)
|
||||
self:dump(_queued_packages, "_queued_packages", 2)
|
||||
if _loading_package then
|
||||
self:dump(_loading_package, "_loading_package", 2)
|
||||
else
|
||||
self:debug("_loading_package = nil")
|
||||
end
|
||||
self:dump(_loaded_packages, "_loaded_packages", 2)
|
||||
end
|
|
@ -115,6 +115,7 @@ function vmf.initialize_mod_data(mod, mod_data)
|
|||
vmf.set_internal_data(mod, "is_togglable", mod_data.is_togglable or mod_data.is_mutator)
|
||||
vmf.set_internal_data(mod, "is_mutator", mod_data.is_mutator)
|
||||
vmf.set_internal_data(mod, "allow_rehooking", mod_data.allow_rehooking)
|
||||
vmf.set_internal_data(mod, "workshop_id", mod_data.workshop_id)
|
||||
|
||||
-- Register mod as mutator @TODO: calling this after options initialization would be better, I guess?
|
||||
if mod_data.is_mutator then
|
||||
|
@ -163,4 +164,4 @@ end
|
|||
-- VARIABLES
|
||||
|
||||
vmf.mods = _mods
|
||||
vmf.mods_unloading_order = _mods_unloading_order
|
||||
vmf.mods_unloading_order = _mods_unloading_order
|
||||
|
|
|
@ -29,6 +29,7 @@ function vmf_mod_object:init()
|
|||
dofile("scripts/mods/vmf/modules/core/options")
|
||||
dofile("scripts/mods/vmf/modules/legacy/options")
|
||||
dofile("scripts/mods/vmf/modules/core/network")
|
||||
dofile("scripts/mods/vmf/modules/core/packages")
|
||||
dofile("scripts/mods/vmf/modules/core/commands")
|
||||
dofile("scripts/mods/vmf/modules/gui/custom_textures")
|
||||
dofile("scripts/mods/vmf/modules/gui/custom_views")
|
||||
|
@ -55,6 +56,7 @@ end
|
|||
-- #####################################################################################################################
|
||||
|
||||
function vmf_mod_object:update(dt)
|
||||
vmf.update_package_manager()
|
||||
vmf.mods_update_event(dt)
|
||||
vmf.check_keybinds()
|
||||
vmf.execute_queued_chat_command()
|
||||
|
@ -63,6 +65,7 @@ function vmf_mod_object:update(dt)
|
|||
if not vmf.all_mods_were_loaded and Managers.mod._state == "done" then
|
||||
|
||||
vmf.generate_keybinds()
|
||||
vmf.initialize_package_manager()
|
||||
vmf.initialize_vmf_options_view()
|
||||
vmf.create_network_dictionary()
|
||||
vmf.ping_vmf_users()
|
||||
|
@ -111,4 +114,4 @@ end
|
|||
-- ##### Return ########################################################################################################
|
||||
-- #####################################################################################################################
|
||||
|
||||
return vmf_mod_object
|
||||
return vmf_mod_object
|
||||
|
|
Loading…
Add table
Reference in a new issue