root/lang/ruby/citrus/trunk/lib/citrus/plugins.rb @ 6844

Revision 6580, 2.1 kB (checked in by cho45, 6 years ago)

lang/ruby/chokan/branches/citrus:

chokan と同じようにリロードできるようにした。
スペックをいろいろ追加

  • Property svn:executable set to *
Line 
1#!/usr/bin/env ruby
2
3require "pathname"
4
5module Citrus
6        class Plugins
7                class PluginsError < StandardError; end
8                class UnknownPlugin < PluginsError; end
9
10                def initialize(path)
11                        @path      = Pathname.new(path)
12                        @instances = {}
13                        update
14                end
15
16                def plugin_names
17                        @plugins.keys
18                end
19
20                def loaded_plugin_names
21                        @instances.keys
22                end
23
24                def loaded_plugins
25                        @instances
26                end
27
28                def [](key)
29                        @instances[key]
30                end
31
32                def each(&block)
33                        @instances.each(&block)
34                end
35
36                def load(class_name, *args)
37                        raise UnknownPlugin, "UnknownPlugin: #{class_name}" unless @plugins.key?(class_name)
38
39                        info = @plugins[class_name]
40                        @instances[class_name] = info[:class].new(*args)
41                        @instances[class_name].on_load if @instances[class_name].respond_to? :on_load
42
43                        @instances[class_name]
44                end
45
46                def unload(class_name)
47                        raise UnknownPlugin, "UnknownPlugin: #{class_name}" unless @plugins.key?(class_name)
48                        @instances[class_name].on_unload if @instances[class_name].respond_to? :on_unload
49
50                        @instances.delete class_name
51                end
52
53                def reload(class_name, *args)
54                        if class_name == :all
55                                ret = {}
56                                plugins = search(@path)
57                                plugins.each do |k, v|
58                                        if @instances.key?(k)
59                                                # Re-instanciate
60                                                if @plugins[k][:time] < v[:time]
61                                                        @plugins[k] = v
62                                                        self.unload(k)
63                                                        ret[k] = self.load(k, *args)
64                                                end
65                                end
66                                end
67                                ret
68                        else
69                                plugins = search(@path)
70                                raise UnknownPlugin, "UnknownPlugin: #{class_name}" unless plugins.key?(class_name)
71                                file = plugins[class_name][:file]
72                                @plugins.update load_file(file)
73                                self.unload(class_name)
74                                self.load(class_name, *args)
75                        end
76                end
77
78                def update
79                        @plugins   = search(@path)
80                end
81
82                protected
83                def search(path)
84                        class_table = {}
85
86                        Pathname.glob("#{path}/*.rb") do |f|
87                                class_table.update(load_file(f))
88                        end
89
90                        class_table
91                end
92
93                def load_file(f)
94                        ret = {}
95                        m = Module.new
96                        m.module_eval(f.read)
97                        m.constants.each do |name|
98                                const = m.const_get(name)
99                                if const.is_a? Class
100                                        ret[name] = {
101                                                :class => const,
102                                                :file  => f,
103                                                :time  => f.mtime,
104                                        }
105                                end
106                        end
107                        ret
108                end
109        end
110end
111
Note: See TracBrowser for help on using the browser.