* loadrequire() Features

For users to report plugin bugs and request plugin enhancements; and for authors to test new/new versions of plugins, and to discuss plugin development (in the Programming Technicalities sub-forum). If you want advice on choosing or using a plugin, please ask in General Usage or an appropriate sub-forum.
Post Reply
User avatar
tatewise
Megastar
Posts: 27087
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

loadrequire() Features

Post by tatewise » 20 Oct 2013 11:57

Jane has suggested that a loadrequire() function like plugins:code_snippets:module_require_with_load|> Module Require With Load (code snippet) could be supplied with FH, presumably as a library module loadrequire.lua preloaded in the Plugins folder.

In the meantime a simple workaround would be a loadrequire.fh_lua Plugin from the Plugin Store that when run simply renames itself to loadrequire.lua. Then to provide the loadrequire() function any Plugin could use:

Code: Select all

 local loadrequire = require("loadrequire").loadrequire
The Plugin would have the following code structure:

Code: Select all

--[[
@Module: loadrequire
@Author: Mike Tate
@Version: 1.0
@LastUpdated: 20 Oct 2013
@Description: loadrequire() function plugin & module.
@V1.0: Initial version.
]]
require "lfs"
require "luacom"
if not ... then
	local plugins = fhGetContextInfo('CI_APP_DATA_FOLDER')..'\\Plugins\\'
	local source = 'loadrequire.fh_lua'
	local target = 'loadrequire.lua'
	if lfs.attributes(plugins..source,'mode') == 'file' then
		if lfs.attributes(plugins..target,'mode') == 'file' then
			local res, err = os.remove (plugins..target)
			if not res then print(err) end
		end
		local res, err = os.rename (plugins..source, plugins..target)
		if not res then print(err) end
		return
	end
	error("\n\nThis is a Library Module, and so it can not be executed on its own.")
end

local fh = {}									-- Local environment table
package.seeall(fh)							 -- Enable all globals
module("...",package.seeall)				-- Create matching module name
setfenv(1,fh)									-- All public names are added to local fh table

function loadrequire(module,extended) 
		... { standard loadrequire function body goes here } ...
end -- function loadrequire

return fh
Some recent refinements have been added to the plugins:code_snippets:module_require_with_load|> Module Require With Load (code snippet).

To catch module errors, other than simply a missing module file, the fragment:

Code: Select all

	res = pcall(requiref,extended)
	if not(res) then
		{ load library modules }
	end
becomes:

Code: Select all

	local res, err = pcall(requiref,extended)	-- was: res = pcall(requiref,extended)
	if not(res) then
		if err:match("module '"..extended:gsub("(%W)","%%%1").."' not found") then
			{ load library modules }
		else
			fhMessageBox('Error from require("'..module..'") command:\n'..err)
			return false
		end
	end
The module loading would be more efficient, when updating the planned FH library, if existing module files were not downloaded again. This could be achieved by checking the name & size of existing files against a modlist that would include byte sizes, e.g.

Code: Select all

return {
['fh/encoder_v1.lua']=13728,
['fh/encoder_v2.lua']=16117,
['fh/general_v1.lua']=7750,
['fh/stringx_v1.lua']=2636
}
This would be handled by:

Code: Select all

		local modlist = loadstring(http.ResponseBody)
		for x,y in pairs(modlist()) do
			if type(x) == 'number' and type(y) == 'string' then
				x = y		-- revert to original numbered modlist
				y = 0
			end
			if not(installmodule(module,x,y)) then
				break
			end
		end
The function installmodule(module,filename,size) would have the extra fragment

Code: Select all

		local attr = lfs.attributes(storein..filename)
		if attr and attr.mode == 'file' and attr.size == size then return true end
		-- Get file down and install it
See also Modules for FH Library (10857).
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
tatewise
Megastar
Posts: 27087
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: loadrequire() Features (name & size filter)

Post by tatewise » 21 Oct 2013 10:28

Loading modules filtered by file name & size offers the following features:

If file name & size is specified in the modlist, then only new module files that do not exactly match existing module files by name & size will be downloaded. This allows new library versions to be 'required' without suffering the download overhead of previously downloaded modules.

If file name & size is specified in the modlist for an existing module file, but with a different size, then such existing modules will be reloaded. This allows minor backward-compatible changes to be downloaded for previously downloaded modules from an earlier library version, when a new library version is 'required'.

If a total reload of all module files is needed, then either revert to the old file name only modlist, or set all the size values to 0 in the new modlist. This might apply if for example all the script headers needed changing to a new style.
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

User avatar
tatewise
Megastar
Posts: 27087
Joined: 25 May 2010 11:00
Family Historian: V7
Location: Torbay, Devon, UK
Contact:

Re: loadrequire() Features (FH API)

Post by tatewise » 21 Oct 2013 10:36

If instead of supplying loadrequire.lua with FH as a module file, it might be supplied as an integrated Plugins FH API. In this case its name would probably be fhLoadRequire.

The same interim workaround as described above would still work, but with all instances of loadrequire simply changed to fhLoadRequire. Then to provide the fhLoadRequire() function any Plugin could use:

Code: Select all

     local fhLoadRequire = require("fhLoadRequire").fhLoadRequire
Mike Tate ~ researching the Tate and Scott family history ~ tatewise ancestry

Post Reply