Changeset

745:5a343599cd3e

core.modulemanager: Some refactoring to make upcoming changes a little easier
author Matthew Wild <mwild1@gmail.com>
date Sat, 24 Jan 2009 01:15:40 +0000
parents 744:328b702fb80c
children 746:7027de4c039d
files core/modulemanager.lua
diffstat 1 files changed, 50 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/core/modulemanager.lua	Thu Jan 22 14:39:40 2009 +0000
+++ b/core/modulemanager.lua	Sat Jan 24 01:15:40 2009 +0000
@@ -32,7 +32,7 @@
 local loadfile, pcall = loadfile, pcall;
 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
 local pairs, ipairs = pairs, ipairs;
-local t_insert = table.insert;
+local t_insert, t_concat = table.insert, table.concat;
 local type = type;
 local next = next;
 local rawget = rawget;
@@ -107,7 +107,7 @@
 	end
 	
 
-	local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua");
+	local mod, err = loadfile(get_module_filename(module_name));
 	if not mod then
 		log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
 		return nil, err;
@@ -132,18 +132,22 @@
 	return true;
 end
 
+function get_module(host, name)
+	return modulemap[host] and modulemap[host][name];
+end
+
 function is_loaded(host, name)
 	return modulemap[host] and modulemap[host][name] and true;
 end
 
 function unload(host, name, ...)
-	local mod = modulemap[host] and modulemap[host][name];
+	local mod = get_module(host, name); 
 	if not mod then return nil, "module-not-loaded"; end
 	
-	if type(mod.module.unload) == "function" then
-		local ok, err = pcall(mod.module.unload, ...)
+	if module_has_method(mod, "unload") then
+		local ok, err = call_module_method(mod, "unload");
 		if (not ok) and err then
-			log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+			log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err);
 		end
 	end
 	modulemap[host][name] = nil;
@@ -161,36 +165,45 @@
 end
 
 function reload(host, name, ...)
-	local mod = modulemap[host] and modulemap[host][name];
+	local mod = get_module(host, name);
 	if not mod then return nil, "module-not-loaded"; end
 
-	local _mod, err = loadfile(plugin_dir.."mod_"..name..".lua"); -- checking for syntax errors
+	local _mod, err = loadfile(get_module_filename(name)); -- checking for syntax errors
 	if not _mod then
 		log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
 		return nil, err;
 	end
 
 	local saved;
-	if type(mod.module.save) == "function" then
-		local ok, err = pcall(mod.module.save)
-		if (not ok) and err then
-			log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+
+	if module_has_method(mod, "save") then
+		local ok, ret, err = call_module_method(mod, "save");
+		if ok then
+			saved = ret;
 		else
-			saved = err;
+			log("warn", "Error saving module '%s:%s' state: %s", host, module, ret);
+			if not config.get(host, "core", "force_module_reload") then
+				log("warn", "Aborting reload due to error, set force_module_reload to ignore this");
+				return nil, "save-state-failed";
+			else
+				log("warn", "Continuing with reload (using the force)");
+			end
 		end
 	end
 
 	unload(host, name, ...);
-	if load(host, name, ...) then
-		mod = modulemap[host] and modulemap[host][name];
-		if type(mod.module.restore) == "function" then
-			local ok, err = pcall(mod.module.restore, saved or {})
+	local ok, err = load(host, name, ...);
+	if ok then
+		mod = get_module(host, name);
+		if module_has_method(mod, "restore") then
+			local ok, err = call_module_method(mod, "restore", saved or {})
 			if (not ok) and err then
-				log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+				log("warn", "Error restoring module '%s' from '%s': %s", name, host, err);
 			end
 		end
 		return true;
 	end
+	return ok, err;
 end
 
 function handle_stanza(host, origin, stanza)
@@ -214,6 +227,25 @@
 	end
 end
 
+function module_has_method(module, method)
+	return type(module.module[method]) == "function";
+end
+
+function call_module_method(module, func, ...)
+	local f = module.module[func];
+	if module_has_method(module, method) then	
+		return pcall(f, ...);
+	else
+		return false, "no-such-method";
+	end
+end
+
+local _modulepath = { plugin_dir, "mod_", nil, ".lua"};
+function get_module_filename(name)
+	_modulepath[3] = name;
+	return t_concat(_modulepath);
+end
+
 ----- API functions exposed to modules -----------
 -- Must all be in api.*