Class: Sabrina::Plugin

Inherits:
Object
  • Object
show all
Defined in:
lib/sabrina/plugin.rb,
lib/sabrina/plugin/load.rb,
lib/sabrina/plugin/register.rb

Overview

The base class for plugins that improve classes with the ability to handle additional data. The #initialize method for every plugin should accept a target class instance as the parameter. The #initialize method of the target class should contain a call to load_plugins.

When a class has been enhanced by a plugin, it will gain a read-only attribute #plugins that will contain a set of all plugins registered with that class. Class instances will gain a read-only attribute #plugins that will contain a hash of SHORT_NAME => (plugin instance) pairs.

Each plugin will also expose a set of FEATURES. For every feature, two instance methods will be added to the target object: #feature, which will call #feature on every plugin instance that supports it, and #feature_shortname, which will call #feature on the instance of the plugin identified by SHORT_NAME (assuming it supports that feature).

For clarity, plugins should be contained within the Plugins namespace.

Defined Under Namespace

Modules: Load, Register

Constant Summary collapse

ENHANCES =

What class this plugin enhances. This should be required before the plugin.

The target class should have load_plugins at the end of the init.

Monster
PLUGIN_NAME =

Plugin name goes here.

'Generic Plugin'
SHORT_NAME =

Short name should contain only a-z, 0-9, and underscores. This will be the suffix for target instance methods.

'genericplugin'
FEATURES =

Tells the enhanced class what public instance methods the plugin should expose.

This should be a set of symbols.

Common features include :reread, :write, :save, :load.

Set.new [:reread, :write, :save, :load]

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, *_args) ⇒ Plugin

Generates a new Sabrina::Plugin object.

Parameters:

  • parent (Object)


113
114
115
# File 'lib/sabrina/plugin.rb', line 113

def initialize(parent, *_args)
  @parent = parent
end

Class Method Details

.feature_all(f) ⇒ Proc

Generate a #feature method.

Parameters:

  • f (Symbol)

    feature.

Returns:

  • (Proc)


84
85
86
87
88
89
# File 'lib/sabrina/plugin.rb', line 84

def feature_all(f)
  proc do |*args|
    targets = @plugins.select { |_key, val| val.feature?(f) }
    targets.values.map { |val| val.method(f).call(*args) }
  end
end

.feature_this(f, n) ⇒ Proc

Generate a #feature_shortname method.

Parameters:

  • f (Symbol)

    feature.

Returns:

  • (Proc)


95
96
97
98
99
# File 'lib/sabrina/plugin.rb', line 95

def feature_this(f, n)
  proc do |*args|
    @plugins.fetch(n).method(f).call(*args)
  end
end

.featuresObject

See Also:



67
68
69
# File 'lib/sabrina/plugin.rb', line 67

def features
  self::FEATURES
end

.inherited(subclass) ⇒ Object

Automagically registers new plugins with target.



72
73
74
75
76
77
78
# File 'lib/sabrina/plugin.rb', line 72

def inherited(subclass)
  target.extend(Plugin::Register)
  Plugin::Load.include_in(target)

  target.register_plugin(subclass)
  super
end

.plugin_nameObject

See Also:



52
53
54
# File 'lib/sabrina/plugin.rb', line 52

def plugin_name
  self::PLUGIN_NAME
end

.short_nameObject

See Also:



62
63
64
# File 'lib/sabrina/plugin.rb', line 62

def short_name
  self::SHORT_NAME.downcase.gsub(/[^a-z0-9_]/, '')
end

.targetObject

See Also:



57
58
59
# File 'lib/sabrina/plugin.rb', line 57

def target
  self::ENHANCES
end

.to_sString

Provides a short description of the plugin’s functionality.

Returns:

  • (String)


104
105
106
# File 'lib/sabrina/plugin.rb', line 104

def to_s
  "\'#{short_name}\': enhances #{target.name}, supports #{features.to_a}"
end

Instance Method Details

#feature?(f) ⇒ Boolean

Whether a plugin instance supports a feature.

Returns:

  • (Boolean)


134
135
136
# File 'lib/sabrina/plugin.rb', line 134

def feature?(f)
  self.class.features.include?(f)
end

#reread(*_args) ⇒ Array

Drop internal data and force reloading from ROM.

Returns:

  • (Array)

    Any return data from child methods.



120
121
122
# File 'lib/sabrina/plugin.rb', line 120

def reread(*_args)
  children.map(&:reload_from_rom)
end

#to_sString

Subclasses should override this to provide a useful textual representation of instance data.

Returns:

  • (String)


141
142
143
# File 'lib/sabrina/plugin.rb', line 141

def to_s
  "<#{self.class.plugin_name}>"
end

#write(*_args) ⇒ Array

Write data to ROM.

Returns:

  • (Array)

    Any return data from child methods.



127
128
129
# File 'lib/sabrina/plugin.rb', line 127

def write(*_args)
  children.map(&:write_to_rom)
end