+ class PluginManagerClass
+ include Singleton
+ attr_reader :bot
+ attr_reader :botmodules
+
+ def initialize
+ @botmodules = {
+ :CoreBotModule => [],
+ :Plugin => []
+ }
+
+ @names_hash = Hash.new
+ @commandmappers = Hash.new
+
+ @dirs = []
+
+ @failed = Array.new
+ @ignored = Array.new
+
+ bot_associate(nil)
+ end
+
+ # Reset lists of botmodules
+ def reset_botmodule_lists
+ @botmodules[:CoreBotModule].clear
+ @botmodules[:Plugin].clear
+ @names_hash.clear
+ @commandmappers.clear
+ @failures_shown = false
+ end
+
+ # Associate with bot _bot_
+ def bot_associate(bot)
+ reset_botmodule_lists
+ @bot = bot
+ end
+
+ # Returns the botmodule with the given _name_
+ def [](name)
+ @names_hash[name.to_sym]
+ end
+
+ # Returns +true+ if _cmd_ has already been registered as a command
+ def who_handles?(cmd)
+ return nil unless @commandmappers.has_key?(cmd.to_sym)
+ return @commandmappers[cmd.to_sym][:botmodule]
+ end
+
+ # Registers botmodule _botmodule_ with command _cmd_ and command path _auth_path_
+ def register(botmodule, cmd, auth_path)
+ raise TypeError, "First argument #{botmodule.inspect} is not of class BotModule" unless botmodule.kind_of?(BotModule)
+ @commandmappers[cmd.to_sym] = {:botmodule => botmodule, :auth => auth_path}
+ end
+
+ def add_botmodule(botmodule)
+ raise TypeError, "Argument #{botmodule.inspect} is not of class BotModule" unless botmodule.kind_of?(BotModule)
+ kl = botmodule.botmodule_class
+ if @names_hash.has_key?(botmodule.to_sym)
+ case self[botmodule].botmodule_class
+ when kl
+ raise "#{kl} #{botmodule} already registered!"
+ else
+ raise "#{self[botmodule].botmodule_class} #{botmodule} already registered, cannot re-register as #{kl}"
+ end
+ end
+ @botmodules[kl] << botmodule
+ @names_hash[botmodule.to_sym] = botmodule
+ end
+
+ # Returns an array of the loaded plugins
+ def core_modules
+ @botmodules[:CoreBotModule]
+ end
+
+ # Returns an array of the loaded plugins
+ def plugins
+ @botmodules[:Plugin]
+ end
+
+ # Returns a hash of the registered message prefixes and associated
+ # plugins
+ def commands
+ @commandmappers
+ end
+
+ # Makes a string of error _err_ by adding text _str_
+ def report_error(str, err)
+ ([str, err.inspect] + err.backtrace).join("\n")
+ end
+
+ # This method is the one that actually loads a module from the
+ # file _fname_