Merge timber->trunk - thanks everyone!
[prosody.git] / core / modulemanager.lua
index f7594cd9042deb700cb4b3de12804b5574845055..bf1e1924acbb59b49010604b1cb4cc1991a0cb09 100644 (file)
@@ -110,6 +110,7 @@ local function do_unload_module(host, name)
                        end
                end
        end
+       mod.module.loaded = false;
        modulemap[host][name] = nil;
        return true;
 end
@@ -132,6 +133,22 @@ local function do_load_module(host, module_name)
                log("warn", "%s is already loaded for %s, so not loading again", module_name, host);
                return nil, "module-already-loaded";
        elseif modulemap["*"][module_name] then
+               local mod = modulemap["*"][module_name];
+               if module_has_method(mod, "add_host") then
+                       local _log = logger.init(host..":"..module_name);
+                       local host_module_api = setmetatable({
+                               host = host, event_handlers = {}, items = {};
+                               _log = _log, log = function (self, ...) return _log(...); end;
+                       },{
+                               __index = modulemap["*"][module_name].module;
+                       });
+                       local ok, result, module_err = call_module_method(mod, "add_host", host_module_api);
+                       if not ok or result == false then return nil, ok and module_err or result; end
+                       local host_module = setmetatable({ module = host_module_api }, { __index = mod });
+                       host_module.module.environment = host_module;
+                       modulemap[host][module_name] = host_module;
+                       return host_module;
+               end
                return nil, "global-module-already-loaded";
        end
        
@@ -168,8 +185,10 @@ local function do_load_module(host, module_name)
                                log("warn", "mod_%s: Setting module.host = '*' deprecated, call module:set_global() instead", module_name);
                                api_instance:set_global();
                        end
-               else
-                       modulemap[host][module_name] = pluginenv;
+                       if host ~= api_instance.host and module_has_method(pluginenv, "add_host") then
+                               -- Now load the module again onto the host it was originally being loaded on
+                               ok, err = do_load_module(host, module_name);
+                       end
                end
        end
        if not ok then
@@ -261,12 +280,12 @@ function is_loaded(host, name)
 end
 
 function module_has_method(module, method)
-       return type(module.module[method]) == "function";
+       return type(rawget(module.module, method)) == "function";
 end
 
 function call_module_method(module, method, ...)
-       if module_has_method(module, method) then
-               local f = module.module[method];
+       local f = rawget(module.module, method);
+       if type(f) == "function" then
                return pcall(f, ...);
        else
                return false, "no-such-method";