core/modulemanager.lua
author Matthew Wild <mwild1@gmail.com>
Sun, 22 Jan 2012 19:27:06 +0000
changeset 4537 d8d257c13562
parent 4535 d46e9ad4fe8a
child 4565 5a2212d3468e
permissions -rw-r--r--
modulemanager: load(): Return and use the correct module object
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1523
841d61be198f Remove version number from copyright headers
Matthew Wild <mwild1@gmail.com>
parents: 1505
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2828
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 2828
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
519
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 467
diff changeset
     4
-- 
758
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 748
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
b1885732e979 GPL->MIT!
Matthew Wild <mwild1@gmail.com>
parents: 748
diff changeset
     6
-- COPYING file in the source package for more information.
519
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 467
diff changeset
     7
--
cccd610a0ef9 Insert copyright/license headers
Matthew Wild <mwild1@gmail.com>
parents: 467
diff changeset
     8
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
     9
local logger = require "util.logger";
540
ec03f6968fa8 Added function add_feature to modules API (for adding disco features)
Waqas Hussain <waqas20@gmail.com>
parents: 519
diff changeset
    10
local log = logger.init("modulemanager");
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
    11
local config = require "core.configmanager";
1360
857034905016 modulemanager: Changed to use util.pluginloader
Waqas Hussain <waqas20@gmail.com>
parents: 1346
diff changeset
    12
local pluginloader = require "util.pluginloader";
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
747
40837f3422ab modulemanager: Add get_host_type() API method, and fix up call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 746
diff changeset
    14
local hosts = hosts;
1247
4721e4124692 modulemanager: module:hook now allows global modules to hook events on the prosody.events object
Waqas Hussain <waqas20@gmail.com>
parents: 1231
diff changeset
    15
local prosody = prosody;
747
40837f3422ab modulemanager: Add get_host_type() API method, and fix up call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 746
diff changeset
    16
2977
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    17
local loadfile, pcall, xpcall = loadfile, pcall, xpcall;
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
local pairs, ipairs = pairs, ipairs;
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
    20
local t_insert, t_concat = table.insert, table.concat;
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
local type = type;
670
d5cf10b7fc44 Modulemanager: Basic modules can now be unloaded correctly
Waqas Hussain <waqas20@gmail.com>
parents: 637
diff changeset
    22
local next = next;
674
4f506c627b49 modulemanager: module.unload now gets called when modules are being unloaded
Waqas Hussain <waqas20@gmail.com>
parents: 670
diff changeset
    23
local rawget = rawget;
1392
9935ddfd8ccf modulemanager: Added simple module:require implementation
Waqas Hussain <waqas20@gmail.com>
parents: 1361
diff changeset
    24
local error = error;
2151
3bb7c1daa93f modulemanager: New module API methods for getting config options with type conversion, get_option_string, get_option_number, get_option_boolean, get_option_array, get_option_set
Matthew Wild <mwild1@gmail.com>
parents: 2072
diff changeset
    25
local tostring, tonumber = tostring, tonumber;
3bb7c1daa93f modulemanager: New module API methods for getting config options with type conversion, get_option_string, get_option_number, get_option_boolean, get_option_array, get_option_set
Matthew Wild <mwild1@gmail.com>
parents: 2072
diff changeset
    26
2977
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    27
local debug_traceback = debug.traceback;
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    28
local unpack, select = unpack, select;
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    29
pcall = function(f, ...)
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    30
	local n = select("#", ...);
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    31
	local params = {...};
3588
1e570ed17147 modulemanager: Fixed: Locally defined pcall wasn't returning return values of the called function.
Waqas Hussain <waqas20@gmail.com>
parents: 3587
diff changeset
    32
	return xpcall(function() return f(unpack(params, 1, n)) end, function(e) return tostring(e).."\n"..debug_traceback(); end);
2977
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    33
end
686f9a5a7f5e modulemanager: Log proper tracebacks on errors during module load/unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2951
diff changeset
    34
2151
3bb7c1daa93f modulemanager: New module API methods for getting config options with type conversion, get_option_string, get_option_number, get_option_boolean, get_option_array, get_option_set
Matthew Wild <mwild1@gmail.com>
parents: 2072
diff changeset
    35
local array, set = require "util.array", require "util.set";
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
3967
1a9bcbaeb55a modulemanager: Auto-load mod_offline.
Waqas Hussain <waqas20@gmail.com>
parents: 3758
diff changeset
    37
local autoload_modules = {"presence", "message", "iq", "offline"};
3677
dad563ed54aa modulemanager: Allow components to inherit mod_iq. This allows modules loaded on components to hook IQ stanza sub-events ("iq-set/bare/xmlns:tag", etc).
Waqas Hussain <waqas20@gmail.com>
parents: 3623
diff changeset
    38
local component_inheritable_modules = {"tls", "dialback", "iq"};
1505
e19cb945c25b modulemanager: Small code improvement, move autoloaded modules list to the top of the file
Matthew Wild <mwild1@gmail.com>
parents: 1504
diff changeset
    39
467
66f145f5c932 Update Makefile to now pass config paths to prosody. Update prosody, modulemanager and connectionlisteners to obey these paths.
Matthew Wild <mwild1@gmail.com>
parents: 439
diff changeset
    40
-- We need this to let modules access the real global namespace
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
local _G = _G;
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
module "modulemanager"
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
4531
c778ce7e3c78 modulemanager: Move in-module API functions to core.moduleapi (half the file size, yay)
Matthew Wild <mwild1@gmail.com>
parents: 4454
diff changeset
    45
local api = _G.require "core.moduleapi"; -- Module API container
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
    46
4535
d46e9ad4fe8a modulemanager: Cleanup some unused variables, imports, whitespace and add a comment.
Matthew Wild <mwild1@gmail.com>
parents: 4534
diff changeset
    47
-- [host] = { [module] = module_env }
584
eb0cea29c8d7 Temporary hack for global modules
Matthew Wild <mwild1@gmail.com>
parents: 579
diff changeset
    48
local modulemap = { ["*"] = {} };
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
    49
670
d5cf10b7fc44 Modulemanager: Basic modules can now be unloaded correctly
Waqas Hussain <waqas20@gmail.com>
parents: 637
diff changeset
    50
local NULL = {};
d5cf10b7fc44 Modulemanager: Basic modules can now be unloaded correctly
Waqas Hussain <waqas20@gmail.com>
parents: 637
diff changeset
    51
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
    52
-- Load modules when a host is activated
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
    53
function load_modules_for_host(host)
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    54
	local component = config.get(host, "core", "component_module");
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    55
	
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    56
	local global_modules_enabled = config.get("*", "core", "modules_enabled");
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    57
	local global_modules_disabled = config.get("*", "core", "modules_disabled");
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    58
	local host_modules_enabled = config.get(host, "core", "modules_enabled");
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    59
	local host_modules_disabled = config.get(host, "core", "modules_disabled");
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    60
	
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    61
	if host_modules_enabled == global_modules_enabled then host_modules_enabled = nil; end
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    62
	if host_modules_disabled == global_modules_disabled then host_modules_disabled = nil; end
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    63
	
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    64
	local global_modules = set.new(autoload_modules) + set.new(global_modules_enabled) - set.new(global_modules_disabled);
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    65
	if component then
3596
bbeba9f2acf8 modulemanager: load_modules_for_host(): For components, the inherited modules are the intersection of the inheritable and global modules lists, not the difference.
Waqas Hussain <waqas20@gmail.com>
parents: 3595
diff changeset
    66
		global_modules = set.intersection(set.new(component_inheritable_modules), global_modules);
1960
1e674dae31ae modulemanager: Re-organise module loading to still work when no global modules_enabled is defined in the config (thanks hoelzro for accidentally discovering this one)
Matthew Wild <mwild1@gmail.com>
parents: 1946
diff changeset
    67
	end
4135
9dfb3c0101b5 modulemanager: Fix disabling a module on a single host
Paul Aurich <paul@darkrain42.org>
parents: 4002
diff changeset
    68
	local modules = (global_modules + set.new(host_modules_enabled)) - set.new(host_modules_disabled);
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    69
	
3758
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    70
	-- COMPAT w/ pre 0.8
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    71
	if modules:contains("console") then
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    72
		log("error", "The mod_console plugin has been renamed to mod_admin_telnet. Please update your config.");
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    73
		modules:remove("console");
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    74
		modules:add("admin_telnet");
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    75
	end
41f174b61b6a modulemanager, mod_console: Rename mod_console -> mod_admin_telnet - add compatibility code to modulemanager for existing configs
Matthew Wild <mwild1@gmail.com>
parents: 3677
diff changeset
    76
	
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    77
	if component then
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    78
		load(host, component);
637
30b8ad9f7b70 Fix for not loading global modules when host-specific modules are specified in config
Matthew Wild <mwild1@gmail.com>
parents: 615
diff changeset
    79
	end
3595
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    80
	for module in modules do
ec1151d0c4a4 modulemanager: load_modules_for_host(): Inherit 'tls' and 'dialback' from global modules list for components, and load the component module. Also refactored to use util.set.
Waqas Hussain <waqas20@gmail.com>
parents: 3588
diff changeset
    81
		load(host, module);
573
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
    82
	end
f6555ebf84ec Move module loading to modulemanager
Matthew Wild <mwild1@gmail.com>
parents: 569
diff changeset
    83
end
4533
c6480d17be1e modulemanager: Drop unnecessary prosody_events local
Matthew Wild <mwild1@gmail.com>
parents: 4532
diff changeset
    84
prosody.events.add_handler("host-activated", load_modules_for_host);
30
bcf539295f2d Huge commit to:
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    85
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
    86
--- Private helpers ---
438
193f9dd64f17 Bumper commit for the new modulemanager API \o/ Updates all the modules, though some more changes may be in store.
Matthew Wild <mwild1@gmail.com>
parents: 400
diff changeset
    87
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
    88
local function do_unload_module(host, name)
2278
8c10f13c0c20 modulemanager, net.dns: Remove trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2270
diff changeset
    89
	local mod = get_module(host, name);
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
    90
	if not mod then return nil, "module-not-loaded"; end
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
    91
	
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
    92
	if module_has_method(mod, "unload") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
    93
		local ok, err = call_module_method(mod, "unload");
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
    94
		if (not ok) and err then
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
    95
			log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err);
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
    96
		end
674
4f506c627b49 modulemanager: module.unload now gets called when modules are being unloaded
Waqas Hussain <waqas20@gmail.com>
parents: 670
diff changeset
    97
	end
4534
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
    98
	
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
    99
	for handler, event in pairs(mod.module.event_handlers) do
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
   100
		event.object.remove_handler(event.name, handler);
1259
6bd11bca9725 modulemanager: Keep track of event handlers added by module:hook, and remove them on module unload
Waqas Hussain <waqas20@gmail.com>
parents: 1253
diff changeset
   101
	end
4534
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
   102
	
2828
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   103
	if mod.module.items then -- remove items
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   104
		for key,t in pairs(mod.module.items) do
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   105
			for i = #t,1,-1 do
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   106
				local value = t[i];
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   107
				t[i] = nil;
4381
bf81b4784853 modulemanager: Fixed undefined global access in broadcast of item-remove events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 4363
diff changeset
   108
				hosts[host].events.fire_event("item-removed/"..key, {source = mod.module, item = value});
2828
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   109
			end
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   110
		end
fbddc3ed0d09 modulemanager: Fire item-removed events on module unload.
Waqas Hussain <waqas20@gmail.com>
parents: 2072
diff changeset
   111
	end
1986
d4ba9d94eb74 modulemanager: Slightly rearranged code for more robust unloading of modules.
Waqas Hussain <waqas20@gmail.com>
parents: 1960
diff changeset
   112
	modulemap[host][name] = nil;
670
d5cf10b7fc44 Modulemanager: Basic modules can now be unloaded correctly
Waqas Hussain <waqas20@gmail.com>
parents: 637
diff changeset
   113
	return true;
439
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
   114
end
6608ad3a72f3 is_loaded() and incomplete unload() for modules
Matthew Wild <mwild1@gmail.com>
parents: 438
diff changeset
   115
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   116
local function do_load_module(host, module_name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   117
	if not (host and module_name) then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   118
		return nil, "insufficient-parameters";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   119
	elseif not hosts[host] then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   120
		return nil, "unknown-host";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   121
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   122
	
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   123
	if not modulemap[host] then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   124
		modulemap[host] = {};
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   125
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   126
	
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   127
	if modulemap[host][module_name] then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   128
		log("warn", "%s is already loaded for %s, so not loading again", module_name, host);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   129
		return nil, "module-already-loaded";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   130
	elseif modulemap["*"][module_name] then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   131
		return nil, "global-module-already-loaded";
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   132
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   133
	
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   134
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   135
	local mod, err = pluginloader.load_code(module_name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   136
	if not mod then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   137
		log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   138
		return nil, err;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   139
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   140
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   141
	local _log = logger.init(host..":"..module_name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   142
	local api_instance = setmetatable({ name = module_name, host = host, path = err,
4534
7a0a31c4f6c5 modulemanager, moduleapi: Replace hooks multitable with an event_handlers map stored in individual modules. Also adds module:hook_object_event() to hook events on any util.events compatible object.
Matthew Wild <mwild1@gmail.com>
parents: 4533
diff changeset
   143
		_log = _log, log = function (self, ...) return _log(...); end, event_handlers = {} }
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   144
		, { __index = api });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   145
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   146
	local pluginenv = setmetatable({ module = api_instance }, { __index = _G });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   147
	api_instance.environment = pluginenv;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   148
	
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   149
	setfenv(mod, pluginenv);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   150
	hosts[host].modules = modulemap[host];
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   151
	modulemap[host][module_name] = pluginenv;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   152
	
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   153
	local ok, err = pcall(mod);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   154
	if ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   155
		-- Call module's "load"
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   156
		if module_has_method(pluginenv, "load") then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   157
			ok, err = call_module_method(pluginenv, "load");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   158
			if not ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   159
				log("warn", "Error loading module '%s' on '%s': %s", module_name, host, err or "nil");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   160
			end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   161
		end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   162
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   163
		-- Use modified host, if the module set one
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   164
		if api_instance.host == "*" and host ~= "*" then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   165
			modulemap[host][module_name] = nil;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   166
			modulemap["*"][module_name] = pluginenv;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   167
			api_instance:set_global();
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   168
		end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   169
	else
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   170
		log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil");
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   171
		do_unload_module(api_instance.host, module_name); -- Ignore error, module may be partially-loaded
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   172
	end
4537
d8d257c13562 modulemanager: load(): Return and use the correct module object
Matthew Wild <mwild1@gmail.com>
parents: 4535
diff changeset
   173
	return ok and pluginenv, err;
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   174
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   175
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   176
local function do_reload_module(host, name)
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   177
	local mod = get_module(host, name);
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   178
	if not mod then return nil, "module-not-loaded"; end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   179
1360
857034905016 modulemanager: Changed to use util.pluginloader
Waqas Hussain <waqas20@gmail.com>
parents: 1346
diff changeset
   180
	local _mod, err = pluginloader.load_code(name); -- checking for syntax errors
713
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
   181
	if not _mod then
1386
9132f16666e4 modulemanager: Fix copy/paste error, should be name instead of module_name
Matthew Wild <mwild1@gmail.com>
parents: 1378
diff changeset
   182
		log("error", "Unable to load module '%s': %s", name or "nil", err or "nil");
713
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
   183
		return nil, err;
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
   184
	end
2afd6d9e21cd modulemanager: Check for syntax errors before reloading a module
Waqas Hussain <waqas20@gmail.com>
parents: 710
diff changeset
   185
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   186
	local saved;
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   187
	if module_has_method(mod, "save") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   188
		local ok, ret, err = call_module_method(mod, "save");
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   189
		if ok then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   190
			saved = ret;
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   191
		else
4383
718445c040c4 modulemanager: Fix undefined global access in handling of module.save error handling.
Waqas Hussain <waqas20@gmail.com>
parents: 4381
diff changeset
   192
			log("warn", "Error saving module '%s:%s' state: %s", host, name, ret);
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   193
			if not config.get(host, "core", "force_module_reload") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   194
				log("warn", "Aborting reload due to error, set force_module_reload to ignore this");
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   195
				return nil, "save-state-failed";
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   196
			else
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   197
				log("warn", "Continuing with reload (using the force)");
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   198
			end
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   199
		end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   200
	end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   201
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   202
	do_unload_module(host, name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   203
	local ok, err = do_load_module(host, name);
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   204
	if ok then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   205
		mod = get_module(host, name);
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   206
		if module_has_method(mod, "restore") then
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   207
			local ok, err = call_module_method(mod, "restore", saved or {})
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   208
			if (not ok) and err then
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   209
				log("warn", "Error restoring module '%s' from '%s': %s", name, host, err);
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   210
			end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   211
		end
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   212
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   213
	return ok and mod, err;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   214
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   215
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   216
--- Public API ---
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   217
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   218
-- Load a module and fire module-loaded event
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   219
function load(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   220
	local mod, err = do_load_module(host, name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   221
	if mod then
4537
d8d257c13562 modulemanager: load(): Return and use the correct module object
Matthew Wild <mwild1@gmail.com>
parents: 4535
diff changeset
   222
		(hosts[mod.module.host] or prosody).events.fire_event("module-loaded", { module = name, host = host });
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   223
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   224
	return mod, err;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   225
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   226
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   227
-- Unload a module and fire module-unloaded
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   228
function unload(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   229
	local ok, err = do_unload_module(host, name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   230
	if ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   231
		(hosts[host] or prosody).events.fire_event("module-unloaded", { module = name, host = host });
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   232
	end
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   233
	return ok, err;
710
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   234
end
56f6c115bc69 modulemanager: Added reload support, with callbacks for saving and restoring state
Waqas Hussain <waqas20@gmail.com>
parents: 709
diff changeset
   235
4532
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   236
function reload(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   237
	local ok, err = do_reload_module(host, name);
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   238
	if ok then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   239
		(hosts[host] or prosody).events.fire_event("module-reloaded", { module = name, host = host });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   240
	elseif not is_loaded(host, name) then
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   241
		(hosts[host] or prosody).events.fire_event("module-unloaded", { module = name, host = host });
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   242
	end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   243
	return ok, err;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   244
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   245
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   246
function get_module(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   247
	return modulemap[host] and modulemap[host][name];
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   248
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   249
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   250
function get_modules(host)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   251
	return modulemap[host];
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   252
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   253
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   254
function is_loaded(host, name)
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   255
	return modulemap[host] and modulemap[host][name] and true;
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   256
end
d8dbf569766c modulemanager: Some reorganisation. Only external change is (should be) that module-unloaded and module-loaded are no longer fired when reloading a module, the new event module-reloaded is fired instead.
Matthew Wild <mwild1@gmail.com>
parents: 4531
diff changeset
   257
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   258
function module_has_method(module, method)
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   259
	return type(module.module[method]) == "function";
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   260
end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   261
747
40837f3422ab modulemanager: Add get_host_type() API method, and fix up call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 746
diff changeset
   262
function call_module_method(module, method, ...)
2278
8c10f13c0c20 modulemanager, net.dns: Remove trailing whitespace
Matthew Wild <mwild1@gmail.com>
parents: 2270
diff changeset
   263
	if module_has_method(module, method) then
748
172c43d735e9 modulemanager: Really fix call_module_method to work properly
Matthew Wild <mwild1@gmail.com>
parents: 747
diff changeset
   264
		local f = module.module[method];
745
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   265
		return pcall(f, ...);
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   266
	else
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   267
		return false, "no-such-method";
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   268
	end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   269
end
5a343599cd3e core.modulemanager: Some refactoring to make upcoming changes a little easier
Matthew Wild <mwild1@gmail.com>
parents: 733
diff changeset
   270
39
89877d61ac51 Add support for arbitrary events and event hooks
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   271
return _M;