From ec6ed657b40ec55a109652abb1d3af7366b3bde4 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 31 Jan 2024 01:59:39 +0300 Subject: [PATCH 1/2] chore(core): Wire SILE.use() to class:loadPackage() when module is a package --- classes/base.lua | 10 ++++++++-- core/sile.lua | 5 ++--- inputters/base.lua | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/classes/base.lua b/classes/base.lua index 405ab3a52..856628825 100644 --- a/classes/base.lua +++ b/classes/base.lua @@ -182,9 +182,15 @@ function class.declareSettings (_) end function class:loadPackage (packname, options, reload) - local pack = require(("packages.%s"):format(packname)) + local pack + if type(packname) == "table" then + pack = packname + else + pack = require(("packages.%s"):format(packname)) + end if type(pack) == "table" and pack.type == "package" then -- new package - self.packages[pack._name] = pack(options, reload) + local name = pack._name + self.packages[name] = pack(options, reload) else -- legacy package self:initPackage(pack, options) end diff --git a/core/sile.lua b/core/sile.lua index 06710d7c4..83f0ce40f 100644 --- a/core/sile.lua +++ b/core/sile.lua @@ -174,7 +174,7 @@ local function suggest_luarocks (module) ) end -SILE.use = function (module, options) +SILE.use = function (module, options, reload) local status, pack if type(module) == "string" then status, pack = pcall(require, module) @@ -211,9 +211,8 @@ SILE.use = function (module, options) SILE.pagebuilders[name] = pack SILE.pagebuilder = pack(options) elseif pack.type == "package" then - SILE.packages[name] = pack if class then - pack(options) + class:loadPackage(pack, options, reload) else table.insert(SILE.input.preambles, { pack = pack, options = options }) end diff --git a/inputters/base.lua b/inputters/base.lua index a72d86c38..4674bdfde 100644 --- a/inputters/base.lua +++ b/inputters/base.lua @@ -65,7 +65,8 @@ local function process_ambles (ambles) local options = {} if amble.pack then amble, options = amble.pack, amble.options end if amble.type == "package" then - amble(options) + local class = SILE.documentState.documentClass + class:loadPackage(amble.pack, options) else SILE.documentState.documentClass:initPackage(amble, options) end From 3c3fada13021ca774c3b1c435ed0e1ac4c9e8c2d Mon Sep 17 00:00:00 2001 From: Caleb Maclennan Date: Wed, 31 Jan 2024 11:17:05 +0300 Subject: [PATCH 2/2] chore(packages): Protect existing instances of packages This re-runs the _init() function to potentially force a reload or change options, but it avoids re-instantiating a new instance from the package class. --- classes/base.lua | 27 ++++++++++++++++++++++----- core/sile.lua | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/classes/base.lua b/classes/base.lua index 856628825..b83a68ff3 100644 --- a/classes/base.lua +++ b/classes/base.lua @@ -183,14 +183,31 @@ end function class:loadPackage (packname, options, reload) local pack + -- Allow loading by injecting whole packages as-is, otherwise try to load it with the usual packages path. if type(packname) == "table" then - pack = packname + pack, packname = packname, packname._name else - pack = require(("packages.%s"):format(packname)) + pack = require(("packages.%s"):format(packname)) + if pack._name ~= packname then + SU.error(("Loaded module name '%s' does not match requested name '%s'"):format(pack._name, packname)) + end end - if type(pack) == "table" and pack.type == "package" then -- new package - local name = pack._name - self.packages[name] = pack(options, reload) + SILE.packages[packname] = pack + if type(pack) == "table" and pack.type == "package" then -- current package api + if self.packages[packname] then + -- If the same package name has been loaded before, we might be loading a modified version of the same package or + -- we might be re-loading the same package, or we might just be doubling up work because somebody called us twice. + -- The package itself should take care of the difference between load and reload based on the reload flag here, + -- but in addition to that we also want to avoid creating a new instance. We want to run the intitializer from the + -- (possibly different) new module, but not create a new instance ID and loose any connections it made. + -- To do this we add a create function that returns the current instance. This brings along the _initialized flag + -- and of course anything else already setup and running. + local current_instance = self.packages[packname] + pack._create = function () return current_instance end + pack(options, true) + else + self.packages[packname] = pack(options, reload) + end else -- legacy package self:initPackage(pack, options) end diff --git a/core/sile.lua b/core/sile.lua index 83f0ce40f..698a43340 100644 --- a/core/sile.lua +++ b/core/sile.lua @@ -211,6 +211,7 @@ SILE.use = function (module, options, reload) SILE.pagebuilders[name] = pack SILE.pagebuilder = pack(options) elseif pack.type == "package" then + SILE.packages[pack._name] = pack if class then class:loadPackage(pack, options, reload) else