Class: RSence::PluginManager
- Inherits:
-
Object
- Object
- RSence::PluginManager
- Defined in:
- lib/rsence/pluginmanager.rb
Overview
PluginManager is the service that loads and provides method delegation amongst its plugin bundles.
Usage
plugin_paths = [ 'plugins', '/home/me/rsence/plugins' ]
myPluginManager = RSence::PluginManager.new( plugin_paths )
Constant Summary collapse
- @@incr =
0
- @@prev_errors =
Prettier error handling.
[]
- @@pluginmanager_id =
0
Instance Attribute Summary collapse
-
#autoreload ⇒ Object
readonly
Returns the value of attribute autoreload.
-
#name_prefix ⇒ Object
readonly
Returns the value of attribute name_prefix.
-
#parent_manager ⇒ Object
readonly
Returns the value of attribute parent_manager.
-
#plugin_paths ⇒ Object
readonly
Returns the value of attribute plugin_paths.
-
#sessions ⇒ Object
Returns the value of attribute sessions.
-
#transporter ⇒ Object
readonly
Returns the value of attribute transporter.
Instance Method Summary collapse
- #add_servlet(bundle_name) ⇒ Object
-
#bundle_found(bundle_path, bundle_name, src_file) ⇒ Object
If a bundle is found, set its dependencies etc.
-
#bundle_info(bundle_path, bundle_name, src_file) ⇒ Object
Gets plugin information.
-
#call(plugin_name, method_name, *args) ⇒ Object
(also: #run_plugin)
Calls the method
method_name
with argsargs
of the pluginplugin_name
. - #callable?(plugin_name, method_name) ⇒ Boolean
-
#changed?(plugin_name) ⇒ Boolean
Returns true, if a plugin bundle has changed.
- #del_servlet(bundle_name) ⇒ Object
-
#delegate(method_name, *args) ⇒ Object
Delegates
method_name
withargs
to any loaded plugin that responds to the method. -
#delegate_reverse(method_name, *args) ⇒ Object
Reverse delegate
method_name
withargs
to any loaded plugin that responds to the method. -
#disabled?(bundle_path) ⇒ Boolean
Returns true, if the bundle is disabled.
-
#find_bundles(path) ⇒ Object
Scans a directory of plugins, calls
load_plugin
for bundles that match the definition of a plugin bundle. - #incr ⇒ Object
- #incr! ⇒ Object
-
#init_bundles! ⇒ Object
Top-level method for scanning all plugin directories.
-
#initialize(options) ⇒ PluginManager
constructor
Initialize with a list of directories as plugin_paths.
-
#load_bundle(name) ⇒ Object
Loads a plugin bundle.
-
#load_bundles ⇒ Object
loads all bundles found in order of dependency.
-
#loaded?(bundle_name) ⇒ Boolean
Returns true, if the bundle is loaded.
-
#match_servlet(req_type, req, resp, session) ⇒ Object
Calls the servlet that matches the
req_type
andreq.fullpath
with the highest score. -
#match_servlet_uri(uri, req_type = :get) ⇒ Object
Search servlets that match the
uri
andreq_type
. -
#method_missing(sym, *args, &block) ⇒ Object
By default, calling a method not defined calls a plugin of that name.
-
#most_recent(bundle_path, newest_date = 0) ⇒ Object
Finds the most recent file in the path.
- #plugin_error(e, err_location, err_location_descr, eval_repl = false) ⇒ Object
-
#register_alias(bundle_name, alias_name) ⇒ Object
Registers alias name for a plugin bundle.
-
#register_bundle(inst, bundle_name) ⇒ Object
Registers plugin class
inst
into the registry usingbundle_name
. -
#registry(plugin_name = false) ⇒ Object
(also: #[])
Returns the registry data for plugin bundle
plugin_name
. -
#say(message) ⇒ Object
Logs and speaks the message, if the speech synthesis command “say” exists.
-
#shutdown ⇒ Object
Delegates the
flush
andclose
methods to any loaded plugins, in that order. -
#unload_bundle(bundle_name) ⇒ Object
Unloads the plugin bundle named
bundle_name
. -
#update_bundles! ⇒ Object
Checks for changed plugin bundles and unloads/loads/reloads them accordingly.
-
#valid_plugindir?(path, bundle_name) ⇒ Boolean
Returns false, if the plugin directory isn’t valid.
Constructor Details
#initialize(options) ⇒ PluginManager
Initialize with a list of directories as plugin_paths. It’s an array containing all plugin directories to scan.
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 |
# File 'lib/rsence/pluginmanager.rb', line 661 def initialize( ) = { :plugin_paths => nil, :transporter => nil, :autoreload => false, :name_prefix => false, :resolved_deps => [], :resolved_categories => {}, :parent_manager => nil }.merge( ) @pluginmanager_id = @@pluginmanager_id @@pluginmanager_id += 1 @closed = false @plugin_paths = [:plugin_paths] if [:transporter] @transporter = [:transporter] #@sessions = options[:transporter].sessions end @autoreload = [:autoreload] @name_prefix = [:name_prefix] @parent_manager = [:parent_manager] if @parent_manager == nil RSence.plugin_manager = self end @deps = Dependencies.new( [:resolved_deps], [:resolved_categories] ) puts "Loading #{@name_prefix.to_s+' ' if @name_prefix}plugins..." if RSence.args[:verbose] init_bundles! puts %{Plugins #{"of #{@name_prefix} " if @name_prefix}loaded.} if RSence.args[:verbose] if @autoreload @thr = Thread.new do Thread.pass until @closed begin update_bundles! rescue => e plugin_error( e, "PluginManager#update_bundles!", "An error occurred while reloading bundles" ) end sleep 3 end puts "No longer reloading plugins of #{@name_prefix}." if RSence.args[:verbose] end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object
By default, calling a method not defined calls a plugin of that name
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/rsence/pluginmanager.rb', line 48 def method_missing( sym, *args, &block ) if @registry.has_key?(sym) if args == [] and block == nil return @registry[sym] elsif block == nil call( sym, *args ) end elsif @parent_manager return @parent_manager.method_missing( sym, *args, &block ) end end |
Instance Attribute Details
#autoreload ⇒ Object (readonly)
Returns the value of attribute autoreload.
645 646 647 |
# File 'lib/rsence/pluginmanager.rb', line 645 def autoreload @autoreload end |
#name_prefix ⇒ Object (readonly)
Returns the value of attribute name_prefix.
646 647 648 |
# File 'lib/rsence/pluginmanager.rb', line 646 def name_prefix @name_prefix end |
#parent_manager ⇒ Object (readonly)
Returns the value of attribute parent_manager.
648 649 650 |
# File 'lib/rsence/pluginmanager.rb', line 648 def parent_manager @parent_manager end |
#plugin_paths ⇒ Object (readonly)
Returns the value of attribute plugin_paths.
647 648 649 |
# File 'lib/rsence/pluginmanager.rb', line 647 def plugin_paths @plugin_paths end |
#sessions ⇒ Object
Returns the value of attribute sessions.
24 25 26 |
# File 'lib/rsence/pluginmanager.rb', line 24 def sessions @sessions end |
#transporter ⇒ Object (readonly)
Returns the value of attribute transporter.
24 25 26 |
# File 'lib/rsence/pluginmanager.rb', line 24 def transporter @transporter end |
Instance Method Details
#add_servlet(bundle_name) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/rsence/pluginmanager.rb', line 88 def add_servlet( bundle_name ) if @parent_manager sub_name = "#{@name_prefix.to_s}:#{bundle_name.to_s}" @parent_manager.add_servlet( sub_name ) end @servlets.push( bundle_name ) end |
#bundle_found(bundle_path, bundle_name, src_file) ⇒ Object
If a bundle is found, set its dependencies etc
439 440 441 |
# File 'lib/rsence/pluginmanager.rb', line 439 def bundle_found( bundle_path, bundle_name, src_file ) @info[ bundle_name ] = bundle_info( bundle_path, bundle_name, src_file ) end |
#bundle_info(bundle_path, bundle_name, src_file) ⇒ Object
Gets plugin information
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
# File 'lib/rsence/pluginmanager.rb', line 290 def bundle_info( bundle_path, bundle_name, src_file ) # Default bundle information info = { # The human-readable product name of the package :title => bundle_name.to_s.capitalize, # The human-readable version of the package :version => '0.0.0', # A brief description of the package (rdoc formatting supported) :description => 'No Description', # A flag (when false) prevents the plugin from automatically reload when changed. :reloadable => true, # System version requirement. # NOTE: Has no effect yet! :sys_version => '>= 2.2.0', # Dependency, by default the system category (built-in plugins). # A nil ( "~" in yaml ) value means no dependencies. :depends_on => [ :system ], # Optional, name of category. The built-in plugins are :system :category => nil, # Optional, name of plugin to replace # NOTE: Has no effect yet! :replaces => nil, # Optional, reverse dependency. Loads before the prepended plugin(category). # NOTE: Doesn't support packages yet! :prepends => nil, # Name of plugin manager, so the bundle internals know what its path is. :manager => @name_prefix } # Merge info.yaml data into info info_path = File.join( bundle_path, 'info.yaml' ) if File.exists?( info_path ) info_yaml = YAML.load( File.read( info_path ) ) info_yaml.each do |info_key,info_value| info[ info_key.to_sym ] = info_value end elsif RSence.args[:debug] warn "Expected info.yaml, using defaults:" warn " #{info_path}" end @deps.set_deps( bundle_name, info[:depends_on] ) if info[:category] if info[:category].class == Symbol @deps.add_category( info[:category] ) unless @deps.category?( info[:category] ) @deps.set_deps( info[:category], bundle_name ) else warn "Invalid category: #{info[:category].inspect}" end end if info[:prepends] if info[:prepends].class == Array info[:prepends].each do |prep| @deps.set_deps( prep, bundle_name ) end else @deps.set_deps( info[:prepends], bundle_name ) end end # Extra information, not override-able in info.yaml # Path of bundle info[:path] = bundle_path # Name of bundle info[:name] = bundle_name # Full path of source file info[:src_file] = src_file # Timestamp of last changed file info[:last_changed] = most_recent( bundle_path ) # ..however, don't accept future timestamps: time_now = Time.now.to_i info[:last_changed] = time_now if info[:last_changed] > time_now return info end |
#call(plugin_name, method_name, *args) ⇒ Object Also known as: run_plugin
Calls the method method_name
with args args
of the plugin plugin_name
. Returns false, if no such plugin or method exists.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/rsence/pluginmanager.rb', line 114 def call( plugin_name, method_name, *args ) puts "#{plugin_name}.#{method_name}" if RSence.args[:trace_delegate] plugin_name_s = plugin_name.to_s if plugin_name_s.include?(':') colon_index = plugin_name_s.index(':') sub_manager_name = plugin_name_s[0..(colon_index-1)].to_sym plugin_name = plugin_name_s[(colon_index+1)..-1].to_sym if @registry.has_key?( sub_manager_name ) sub_manager = @registry[sub_manager_name] if sub_manager.respond_to?( :plugin_plugins ) return sub_manager.plugin_plugins.call( plugin_name, method_name, *args ) end end return false end plugin_name = plugin_name.to_sym if callable?( plugin_name, method_name ) begin return @registry[ plugin_name ].send( method_name, *args ) rescue => e plugin_error( e, "RSence::PluginManager.call error", "plugin_name: #{plugin_name.inspect}, method_name: #{method_name.inspect}", plugin_name ) end elsif @deps.category?( plugin_name ) warn "Warning! Tried to call category: #{plugin_name.inpsect}" elsif not @registry.has_key?( plugin_name ) warn "Warning (#{@pluginmanager_id})! No such plugin: #{plugin_name.inspect} (tried to call #{method_name.inspect[0..100]} using args: #{args.inspect[0..100]}" elsif not @registry[ plugin_name ].respond_to?( method_name ) warn "Warning! Plugin: #{plugin_name.inspect} does not respond to #{method_name.inspect}" end return false end |
#callable?(plugin_name, method_name) ⇒ Boolean
104 105 106 107 108 109 110 |
# File 'lib/rsence/pluginmanager.rb', line 104 def callable?( plugin_name, method_name ) return false if @deps.category?( plugin_name ) return false unless @registry.has_key?( plugin_name ) plugin = @registry[plugin_name] return false unless plugin.respond_to?( method_name ) return true end |
#changed?(plugin_name) ⇒ Boolean
Returns true, if a plugin bundle has changed. Only compares timestamp, not checksum.
524 525 526 527 528 529 |
# File 'lib/rsence/pluginmanager.rb', line 524 def changed?( plugin_name ) info = @info[plugin_name] last_changed = info[:last_changed] newest_change = most_recent( info[:path], last_changed ) return last_changed < newest_change end |
#del_servlet(bundle_name) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/rsence/pluginmanager.rb', line 96 def del_servlet( bundle_name ) if @parent_manager sub_name = "#{@name_prefix.to_s}:#{bundle_name.to_s}" @parent_manager.del_servlet( sub_name ) end @servlets.delete( bundle_name ) end |
#delegate(method_name, *args) ⇒ Object
Delegates method_name
with args
to any loaded plugin that responds to the method.
239 240 241 242 243 |
# File 'lib/rsence/pluginmanager.rb', line 239 def delegate( method_name, *args ) @deps.list.each do |plugin_name| call( plugin_name, method_name, *args ) if callable?( plugin_name, method_name ) end end |
#delegate_reverse(method_name, *args) ⇒ Object
Reverse delegate method_name
with args
to any loaded plugin that responds to the method.
247 248 249 250 251 |
# File 'lib/rsence/pluginmanager.rb', line 247 def delegate_reverse( method_name, *args ) @deps.list.reverse.each do |plugin_name| call( plugin_name, method_name, *args ) if callable?( plugin_name, method_name ) end end |
#disabled?(bundle_path) ⇒ Boolean
Returns true, if the bundle is disabled
460 461 462 |
# File 'lib/rsence/pluginmanager.rb', line 460 def disabled?( bundle_path ) File.exists?( File.join( bundle_path, 'disabled' ) ) end |
#find_bundles(path) ⇒ Object
Scans a directory of plugins, calls load_plugin
for bundles that match the definition of a plugin bundle.
- Skips bundles starting with a dot
- Skips bundles without a ruby source file with the same
name as the directory (plus '.rb').
- Skips bundles containing a file or directory named 'disabled'
475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'lib/rsence/pluginmanager.rb', line 475 def find_bundles( path ) bundles_found = [] Dir.entries(path).each do |bundle_name| bundle_status = valid_plugindir?( path, bundle_name ) if bundle_status (bundle_path, src_file) = bundle_status unless disabled?( bundle_path ) # bundle_name = "#{@name_prefix.to_s}.#{bundle_name}" if @name_prefix bundles_found.push( [bundle_path, bundle_name.to_sym, src_file] ) end end end return bundles_found end |
#incr ⇒ Object
27 28 29 |
# File 'lib/rsence/pluginmanager.rb', line 27 def incr return @@incr end |
#incr! ⇒ Object
30 31 32 |
# File 'lib/rsence/pluginmanager.rb', line 30 def incr! @@incr += 1 end |
#init_bundles! ⇒ Object
Top-level method for scanning all plugin directories. Clears previously loaded plugins.
636 637 638 639 640 641 642 |
# File 'lib/rsence/pluginmanager.rb', line 636 def init_bundles! @registry = {} # bundle_name => bundle_instance mapping @info = {} # bundle_name => bundle_info mapping @aliases = {} # bundle_alias => bundle_name mapping @servlets = [] # bundle_name list of Servlet class instances update_bundles! end |
#load_bundle(name) ⇒ Object
Loads a plugin bundle.
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/rsence/pluginmanager.rb', line 384 def load_bundle( name ) if @deps.unresolved?(name) warn "Warning: Bundle #{name} has unmet dependencies." return end if @registry.has_key?( name ) warn "Warning: Bundle #{name} already loaded." return end puts "Loading bundle: #{name.inspect}" if RSence.args[:debug] info = @info[ name ] path = info[:path] src_file = info[:src_file] bundle_src = File.read( src_file ) module_ns = Plugins.bundle_loader( { :bundle_path => path, :bundle_name => name, :bundle_info => info, :plugin_manager => self, :src_path => src_file, :src => bundle_src } ) module_ns.constants.each do |module_const_name| module_const = module_ns.const_get( module_const_name ) if module_const.class == Class type = module_const.bundle_type if [:Servlet, :Plugin, :GUIPlugin].include? type bundle_inst = module_const.new( name, info, path, self ) bundle_inst.register( name ) if [ :Plugin, :GUIPlugin ].include?( type ) break else warn "Can't init class: #{module_const.to_s}" break end else warn "Invalid module_const.class: #{module_const.class.inspect}" end end end |
#load_bundles ⇒ Object
loads all bundles found in order of dependency
432 433 434 435 436 |
# File 'lib/rsence/pluginmanager.rb', line 432 def load_bundles @deps.list.each do |name| load_bundle( name ) if @deps.loadable?( name ) end end |
#loaded?(bundle_name) ⇒ Boolean
Returns true, if the bundle is loaded.
465 466 467 |
# File 'lib/rsence/pluginmanager.rb', line 465 def loaded?( bundle_name ) @registry.has_key?( bundle_name ) end |
#match_servlet(req_type, req, resp, session) ⇒ Object
Calls the servlet that matches the req_type
and req.fullpath
with the highest score.
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/rsence/pluginmanager.rb', line 216 def match_servlet( req_type, req, resp, session ) req_uri = req.fullpath matches_order = match_servlet_uri( req_uri, req_type ) return false unless matches_order matches_order.each do |servlet_name| begin call( servlet_name, req_type, req, resp, session ) return true rescue => e plugin_error( e, "RSence::PluginManager.match_servlet", "servlet_name: #{servlet_name.inspect}, req_type: #{req_type.inspect}", servlet_name ) next end end return false end |
#match_servlet_uri(uri, req_type = :get) ⇒ Object
Search servlets that match the uri
and req_type
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/rsence/pluginmanager.rb', line 184 def match_servlet_uri( uri, req_type=:get ) match_score = {} @servlets.each do | servlet_name | if call( servlet_name, :match, uri, req_type ) score = call( servlet_name, :score ) match_score[ score ] = [] unless match_score.has_key? score match_score[ score ].push( servlet_name ) end end match_scores = match_score.keys.sort if match_scores.empty? return false else matches_order = [] matches_best = match_score[ match_scores[0] ] if matches_best.size > 1 matches_best = matches_best[ rand( matches_best.size ) ] else matches_best = matches_best.first end matches_order.push( matches_best ) match_score.keys.sort.each do |match_n| match_score[ match_n ].each do | match_name | matches_order.push( match_name ) unless matches_order.include? match_name end end return matches_order end end |
#most_recent(bundle_path, newest_date = 0) ⇒ Object
Finds the most recent file in the path
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/rsence/pluginmanager.rb', line 267 def most_recent( bundle_path, newest_date=0 ) path_date = File.stat( bundle_path ).mtime.to_i is_dir = File.directory?( bundle_path ) if path_date > newest_date and not is_dir newest_date = path_date end if is_dir Dir.entries( bundle_path ).each do |entry_name| next if entry_name[0].chr == '.' # skip hidden, '.' and '..' full_path = File.join( bundle_path, entry_name ) if File.directory?( full_path ) next if entry_name == 'plugins' # skip sub-plugins else next unless entry_name.include?('.') next unless ['yaml','rb'].include?( entry_name.split('.')[-1] ) end newest_date = most_recent( full_path, newest_date ) end end return newest_date end |
#plugin_error(e, err_location, err_location_descr, eval_repl = false) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/rsence/pluginmanager.rb', line 154 def plugin_error( e, err_location, err_location_descr, eval_repl=false ) err_msg = [ "*"*40, err_location, err_location_descr, "#{e.class.to_s}, #{e.message}", "Backtrace:", "\t"+e.backtrace.join("\n\t"), "*"*40 ].join("\n")+"\n" error_say = "Error! #{err_location_descr.capitalize}. #{e.class.to_s}, #{e.message}?" unless @@prev_errors.include?( error_say ) @@prev_errors.push( error_say ) say error_say end @@prev_errors.shift if @@prev_errors.length > 10 if eval_repl puts puts "plugin: #{eval_repl}" puts begin err_msg = err_msg.gsub(/^\t\(eval\)\:/s,"\t#{eval_repl}:") rescue Encoding::CompatibilityError => e $stderr.write( "Encoding::CompatibilityError in plugin error eval!" ) end end $stderr.write( err_msg ) end |
#register_alias(bundle_name, alias_name) ⇒ Object
Registers alias name for a plugin bundle.
61 62 63 64 65 66 67 |
# File 'lib/rsence/pluginmanager.rb', line 61 def register_alias( bundle_name, alias_name ) if @aliases.has_key?( alias_name.to_sym ) warn "Alias already taken: #{alias_name.inspect}" else @aliases[ alias_name ] = bundle_name.to_sym end end |
#register_bundle(inst, bundle_name) ⇒ Object
Registers plugin class inst
into the registry using bundle_name
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/rsence/pluginmanager.rb', line 70 def register_bundle( inst, bundle_name ) bundle_name = bundle_name.to_sym if @registry.has_key?( bundle_name ) if registry[ bundle_name ] != inst warn "Tried to register a conflicting bundle name: #{bundle_name.inspect}; ignoring" else warn "Use @plugins.register_alias to register more than one name per plugin." register_alias( inst.name.to_sym, bundle_name ) end else inst.init if inst.respond_to? :init and not inst.inited @registry[ bundle_name ] = inst if inst.respond_to?( :match ) and ( inst.respond_to?( :get ) or inst.respond_to?( :post ) ) add_servlet( bundle_name ) end end end |
#registry(plugin_name = false) ⇒ Object Also known as: []
Returns the registry data for plugin bundle plugin_name
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/rsence/pluginmanager.rb', line 35 def registry( plugin_name=false ) return @registry unless plugin_name if @registry.has_key?( plugin_name ) return @registry[ plugin_name ] elsif @parent_manager return @parent_manager.registry( plugin_name ) else throw "Plugin not in registry: #{plugin_name.inspect}" end end |
#say(message) ⇒ Object
Logs and speaks the message, if the speech synthesis command “say” exists.
532 533 534 535 536 537 538 539 540 |
# File 'lib/rsence/pluginmanager.rb', line 532 def say( ) puts if RSence.args[:say] Thread.new do Thread.pass system(%{say "#{message.gsub('"',"'").gsub('`',"'")}"}) end end end |
#shutdown ⇒ Object
Delegates the flush
and close
methods to any loaded plugins, in that order.
255 256 257 258 259 260 261 262 263 264 |
# File 'lib/rsence/pluginmanager.rb', line 255 def shutdown if @parent_manager @closed = true else @transporter.online = false end @deps.list.reverse.each do |bundle_name| unload_bundle( bundle_name ) end end |
#unload_bundle(bundle_name) ⇒ Object
Unloads the plugin bundle named bundle_name
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/rsence/pluginmanager.rb', line 491 def unload_bundle( bundle_name ) if @registry.has_key?( bundle_name ) unload_order = @deps.del_order( bundle_name ) unload_order.each do |unload_dep| unload_bundle( unload_dep ) unless unload_dep == bundle_name end puts "Unloading bundle: #{bundle_name.inspect}" if RSence.args[:debug] @deps.del_item( bundle_name ) if @transporter online_status = @transporter.online? @transporter.online = false end call( bundle_name, :flush ) call( bundle_name, :close ) @registry.delete( bundle_name ) @aliases.each do |a_name,b_name| if b_name == bundle_name @aliases.delete( a_name ) end end if @servlets.include?( bundle_name ) del_servlet( bundle_name ) end if @info.include?( bundle_name ) @info.delete( bundle_name ) end @transporter.online = online_status if @transporter return unload_order end end |
#update_bundles! ⇒ Object
Checks for changed plugin bundles and unloads/loads/reloads them accordingly.
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
# File 'lib/rsence/pluginmanager.rb', line 543 def update_bundles! (are_found, to_load, to_unload, to_reload) = [[],[],[],[]] found_map = {} @plugin_paths.each do |path| are_found += find_bundles( path ) end are_found.each do |item| (path, name, src_file) = item found_map[name] = item is_loaded = loaded?( name ) if is_loaded and changed?( name ) to_reload.push( name ) elsif not is_loaded to_load.push( name ) end end @registry.keys.each do |name| to_unload.push( name ) if not found_map.has_key?( name ) end to_unload.each do |name| next if @deps.category?( name ) if RSence.args[:verbose] print "Unloading #{name.inspect}..."; STDOUT.flush end unload_bundle( name ) puts "done!" if RSence.args[:verbose] end to_reload.each do |name| next if @deps.category?( name ) if RSence.args[:verbose] print "Unloading #{name.inspect}..."; STDOUT.flush end unload_order = unload_bundle( name ) to_load += unload_order puts "done!" if RSence.args[:verbose] end info_map = {} to_load.each do |name| next unless found_map.has_key? name info_map[name] = bundle_info( *found_map[name] ) end no_deps = {} to_load.dup.each do |name| if @deps.unresolved?( name ) no_deps[ name ] = @deps.deps_on( name ) @deps.del_item( name ) to_load.delete( name ) end end to_open = [] @deps.list.each do |name| next if @deps.category?( name ) next unless to_load.include?( name ) info = info_map[name] if RSence.args[:verbose] if to_reload.include?( name ) print "Reloading #{name.inspect}..." else print "Loading #{name.inspect}..." end STDOUT.flush end @info[name] = info load_bundle( name ) to_open.push( name ) puts "done!" if RSence.args[:verbose] end unless no_deps.empty? warn "Warning! Unable to load the following bundles; missing dependencies:" no_deps.each do |name,deps| warn " #{name} depends on: #{deps.join(', ')}" end end to_open.each do |name| if RSence.args[:verbose] print "Opening #{name.inspect}..."; STDOUT.flush end call( name, :open ) puts "done!" if RSence.args[:verbose] end if not (to_load.empty? and to_unload.empty? and to_reload.empty?) incr! puts "@@incr: #{@@incr}" if RSence.args[:debug] puts "Plugin bundles:" puts " loaded: #{to_load.join(', ')}" unless to_load.empty? puts " unloaded: #{to_unload.join(', ')}" unless to_unload.empty? puts " reloaded: #{to_reload.join(', ')}" unless to_reload.empty? puts " opened: #{to_open.join(', ')}" unless to_open.empty? end end |
#valid_plugindir?(path, bundle_name) ⇒ Boolean
Returns false, if the plugin directory isn’t valid. Returns [bundle_path, src_file] otherwise.
445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/rsence/pluginmanager.rb', line 445 def valid_plugindir?( path, bundle_name ) return false if bundle_name[0].chr == '.' bundle_path = File.( File.join( path, bundle_name ) ) return false unless File.directory?( bundle_path ) bundle_file = bundle_name+'.rb' src_file = File.join( bundle_path, bundle_file ) if not File.exists?( src_file ) bundle_file = 'main.rb' src_file = File.join( bundle_path, bundle_file ) return false unless File.exists?( src_file ) end return [ bundle_path, src_file ] end |