diff options
-rw-r--r-- | lib/rbot/plugins.rb | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/lib/rbot/plugins.rb b/lib/rbot/plugins.rb index d68163ae..5095d19d 100644 --- a/lib/rbot/plugins.rb +++ b/lib/rbot/plugins.rb @@ -177,6 +177,12 @@ module Plugins end end + # Changing the value of @priority directly will cause problems, + # Please use priority=. + def priority + @priority ||= 1 + end + # Returns the symbol :BotModule def botmodule_class :BotModule @@ -320,6 +326,14 @@ module Plugins m.reply(_("incorrect usage, ask for help using '%{command}'") % {:command => "#{@bot.nick}: help #{m.plugin}"}) end + # Define the priority of the module. During event delegation, lower + # priority modules will be called first. Default priority is 1 + def priority=(prio) + if @priority != prio + @priority = prio + @bot.plugins.mark_priorities_dirty + end + end end # A CoreBotModule is a BotModule that provides core functionality. @@ -373,6 +387,10 @@ module Plugins @names_hash = Hash.new @commandmappers = Hash.new @maps = Hash.new + + # modules will be sorted on first delegate call + @sorted_modules = nil + @delegate_list = Hash.new { |h, k| h[k] = Array.new } @@ -475,6 +493,12 @@ module Plugins @commandmappers end + # Tells the PluginManager that the next time it delegates an event, it + # should sort the modules by priority + def mark_priorities_dirty + @sorted_modules = nil + end + # Makes a string of error _err_ by adding text _str_ def report_error(str, err) ([str, err.inspect] + err.backtrace).join("\n") @@ -753,9 +777,25 @@ module Plugins return false end + def sort_modules + @sorted_modules = (core_modules + plugins).sort do |a, b| + a.priority <=> b.priority + end || [] + + @delegate_list.each_value do |list| + list.sort! {|a,b| a.priority <=> b.priority} + end + end + # see if each plugin handles +method+, and if so, call it, passing # +message+ as a parameter def delegate(method, *args) + # if the priorities order of the delegate list is dirty, + # meaning some modules have been added or priorities have been + # changed, then the delegate list will need to be sorted before + # delegation. This should always be true for the first delegation. + sort_modules unless @sorted_modules + # debug "Delegating #{method.inspect}" ret = Array.new if method.match(DEFAULT_DELEGATE_PATTERNS) @@ -774,7 +814,7 @@ module Plugins } else debug "slow-delegating #{method}" - (core_modules + plugins).each { |p| + @sorted_modules.each { |p| if(p.respond_to? method) begin # debug "#{p.botmodule_class} #{p.name} responds" |