class Loom::Mods::Module
Attributes
action_proxy[RW]
loom[RW]
loom_config[RW]
mods[RW]
shell[RW]
Public Class Methods
action_proxy(mod, shell_api)
click to toggle source
This needs more thought
# File lib/loom/mods/module.rb, line 115 def action_proxy(mod, shell_api) @action_proxy_klasses ||= {} @action_proxy_klasses[mod.class.hash] ||= ActionProxy.subclass_for_action_map action_map @action_proxy_klasses[mod.class.hash].new mod, shell_api end
bind_action(action_name, unbound_method, namespace=nil)
click to toggle source
# File lib/loom/mods/module.rb, line 94 def bind_action(action_name, unbound_method, namespace=nil) bound_method_name = [namespace, action_name].compact.join '_' # TODO: document why the `define_method` calls in class only operate on # the single mod instance, rather than adding each "bound_method_name" # (e.g.) to each instance of Module. (actually I think it's because this # is executing from the subclass (via import_actions), so it's only that # class). in any case, add more docs and code pointers. define_method bound_method_name do |*args, &block| Loom.log.debug1(self) { "exec mod action #{self.class}##{bound_method_name}" } bound_method = unbound_method.bind self bound_method.call *args, &block end Loom.log.debug2(self) { "bound mod action => #{self.class.name}##{action_name}" } bound_method_name end
import_actions(action_module, namespace=nil)
click to toggle source
# File lib/loom/mods/module.rb, line 85 def import_actions(action_module, namespace=nil) action_module.instance_methods.each do |action_name| bound_method_name = bind_action( action_name, action_module.instance_method(action_name), namespace) action_map.add_action action_name, bound_method_name, namespace end end
new(shell, loom_config)
click to toggle source
# File lib/loom/mods/module.rb, line 9 def initialize(shell, loom_config) unless shell && shell.is_a?(Loom::Shell::Core) raise "missing shell for mod #{self} => #{shell}" end unless loom_config && loom_config.is_a?(Loom::Config) raise "missing config for mod #{self} => #{loom_config}" end @shell = shell @loom = shell.shell_api @mods = shell.mod_loader @loom_config = loom_config # The action proxy is a facade (or is it a proxy? i don't know) for the mod provided to # patterns by the ShellApi (the 'loom' object). The ShellApi calls back to the mod_loader on # method missing which instantiates a new Module object and returns the action_proxy. @action_proxy = self.class.action_proxy self, shell.shell_api @action_args = nil @action_block = nil end
register_mod(name, **opts, &block)
click to toggle source
Registers a mod as a new namespace on the loom object. Mods
add actions either via a `mod_block` or via registering actions. Only 1 mod_block may be registered per module (which should be fixed), otherwise actions are imported to add module behavior. See loom/lib/loomext/coremods.rb and files.rb for examples.
# File lib/loom/mods/module.rb, line 57 def register_mod(name, **opts, &block) Loom.log.debug2(self) { "registered mod => #{name}" } # TODO: allow multiple mod_blocks per mod. Should probably stop # dynamically defining :mod_block to do so. Current behavior, is the # last register_mod w/ a mod_block wins. This is obvsiously shitty. if block_given? Loom.log.debug2(self) { "acting as mod_block => #{name}:#{block}" } define_method :mod_block, &block end # TODO: Currently registering a block for a mod is different than # importing actions because of how the mod gets executed. When actions # are imorted, the mod is treated as an object providing access to the # actions (via the action_proxy), the action proxy is provided to the # calling pattern via {#execute}. When a block is registered, then the # mod is only a sinlge method executed immediately via #{execute}. The # method signature for the block and action proxy method are the # same... this should be simplified. ModLoader.register_mod self, name, **opts end
required_commands(*cmds)
click to toggle source
# File lib/loom/mods/module.rb, line 79 def required_commands(*cmds) @required_commands ||= [] @required_commands.push *cmds unless cmds.empty? @required_commands end
Private Class Methods
action_map()
click to toggle source
# File lib/loom/mods/module.rb, line 123 def action_map @action_map ||= ActionProxy.new_action_map end
Public Instance Methods
execute(*args, &pattern_block)
click to toggle source
# File lib/loom/mods/module.rb, line 35 def execute(*args, &pattern_block) if respond_to? :mod_block Loom.log.debug3(self) { "executing mod block => #{args} #{pattern_block}" } mod_block *args, &pattern_block else Loom.log.debug3(self) { "initing action => #{args}" } init_action *args, &pattern_block # TODO: ooohhh... the action_proxy code path is fucking # crazy. ActionProxy needs some documentation. action_proxy end end
init_action(*args, &pattern_block)
click to toggle source
# File lib/loom/mods/module.rb, line 30 def init_action(*args, &pattern_block) @action_args = args @action_block = pattern_block end