Play around with a custom, immutable callback library to replace Hooks
This commit is contained in:
parent
9454536b12
commit
b9f0330869
2
Gemfile
2
Gemfile
|
@ -6,6 +6,8 @@ gem 'yard', '~> 0.8', require: false
|
||||||
|
|
||||||
# Test tools
|
# Test tools
|
||||||
gem 'pry', '~> 0.10', group: :development, require: false
|
gem 'pry', '~> 0.10', group: :development, require: false
|
||||||
|
gem 'pry-byebug'
|
||||||
|
gem 'pry-stack_explorer'
|
||||||
gem 'aruba', '~> 0.6', require: false
|
gem 'aruba', '~> 0.6', require: false
|
||||||
gem 'rspec', '~> 3.0', require: false
|
gem 'rspec', '~> 3.0', require: false
|
||||||
gem 'fivemat', '~> 1.3', require: false
|
gem 'fivemat', '~> 1.3', require: false
|
||||||
|
|
|
@ -271,10 +271,10 @@ module Middleman
|
||||||
@extensions.activate_all
|
@extensions.activate_all
|
||||||
|
|
||||||
run_hook :after_configuration
|
run_hook :after_configuration
|
||||||
config_context.execute_after_configuration_callbacks
|
config_context.execute_callbacks(:after_configuration)
|
||||||
|
|
||||||
run_hook :ready
|
run_hook :ready
|
||||||
@config_context.execute_ready_callbacks
|
@config_context.execute_callbacks(:ready)
|
||||||
end
|
end
|
||||||
|
|
||||||
def evaluate_configuration
|
def evaluate_configuration
|
||||||
|
@ -299,10 +299,10 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run any `configure` blocks for the current environment.
|
# Run any `configure` blocks for the current environment.
|
||||||
config_context.execute_configure_callbacks(config[:environment])
|
config_context.execute_callbacks([:configure, config[:environment]])
|
||||||
|
|
||||||
# Run any `configure` blocks for the current mode.
|
# Run any `configure` blocks for the current mode.
|
||||||
config_context.execute_configure_callbacks(config[:mode])
|
config_context.execute_callbacks([:configure, config[:mode]])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether we're in server mode
|
# Whether we're in server mode
|
||||||
|
|
|
@ -62,7 +62,7 @@ module Middleman
|
||||||
|
|
||||||
# Run hooks
|
# Run hooks
|
||||||
@app.run_hook :after_build, self
|
@app.run_hook :after_build, self
|
||||||
@app.config_context.execute_after_build_callbacks(self)
|
@app.config_context.execute_callbacks(:after_build, [self])
|
||||||
|
|
||||||
!@has_error
|
!@has_error
|
||||||
end
|
end
|
||||||
|
|
49
middleman-core/lib/middleman-core/callback_manager.rb
Normal file
49
middleman-core/lib/middleman-core/callback_manager.rb
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
require 'hamster'
|
||||||
|
require 'middleman-core/contracts'
|
||||||
|
|
||||||
|
# Immutable Callback Management, complete with Contracts validation.
|
||||||
|
module Middleman
|
||||||
|
class CallbackManager
|
||||||
|
include Contracts
|
||||||
|
|
||||||
|
Contract Any
|
||||||
|
def initialize
|
||||||
|
@callbacks = ::Hamster.hash
|
||||||
|
end
|
||||||
|
|
||||||
|
Contract RespondTo[:define_singleton_method], ArrayOf[Symbol], Maybe[Proc] => Any
|
||||||
|
def install_methods!(install_target, names, &block)
|
||||||
|
manager = self
|
||||||
|
|
||||||
|
names.each do |name|
|
||||||
|
method_name = block_given? ? block.call(name) : name
|
||||||
|
|
||||||
|
install_target.define_singleton_method(method_name) do |*keys, &b|
|
||||||
|
key_set = keys.unshift(name)
|
||||||
|
manager.add(key_set.length > 1 ? key_set : key_set.first, &b)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
install_target.define_singleton_method(:execute_callbacks) do |keys, *args|
|
||||||
|
manager.execute(keys, args, self)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Contract Or[Symbol, ArrayOf[Symbol]], Proc => Any
|
||||||
|
def add(keys, &block)
|
||||||
|
immutable_keys = keys.is_a?(Symbol) ? keys : ::Hamster::Vector.new(keys)
|
||||||
|
|
||||||
|
@callbacks = @callbacks.put(immutable_keys) do |v|
|
||||||
|
v.nil? ? ::Hamster.set(block) : v.add(block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Contract Or[Symbol, ArrayOf[Symbol]], Maybe[ArrayOf[Any]], Maybe[RespondTo[:instance_exec]] => Any
|
||||||
|
def execute(keys, args=[], scope=self)
|
||||||
|
immutable_keys = keys.is_a?(Symbol) ? keys : ::Hamster::Vector.new(keys)
|
||||||
|
|
||||||
|
callbacks = @callbacks.get(immutable_keys)
|
||||||
|
callbacks && callbacks.each { |b| scope.instance_exec(*args, &b) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,5 @@
|
||||||
require 'rack/mime'
|
require 'rack/mime'
|
||||||
|
require 'middleman-core/callback_manager'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
class ConfigContext
|
class ConfigContext
|
||||||
|
@ -14,10 +15,8 @@ module Middleman
|
||||||
@app = app
|
@app = app
|
||||||
@template_context_class = template_context_class
|
@template_context_class = template_context_class
|
||||||
|
|
||||||
@ready_callbacks = []
|
@callbacks = ::Middleman::CallbackManager.new
|
||||||
@after_build_callbacks = []
|
@callbacks.install_methods!(self, [:ready, :after_build, :after_configuration, :configure])
|
||||||
@after_configuration_callbacks = []
|
|
||||||
@configure_callbacks = {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def helpers(*helper_modules, &block)
|
def helpers(*helper_modules, &block)
|
||||||
|
@ -43,48 +42,6 @@ module Middleman
|
||||||
instance_eval File.read(other_config), other_config, 1
|
instance_eval File.read(other_config), other_config, 1
|
||||||
end
|
end
|
||||||
|
|
||||||
def ready(&block)
|
|
||||||
@ready_callbacks << block
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute_ready_callbacks
|
|
||||||
@ready_callbacks.each do |b|
|
|
||||||
instance_exec(&b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_build(&block)
|
|
||||||
@after_build_callbacks << block
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute_after_build_callbacks(*args)
|
|
||||||
@after_build_callbacks.each do |b|
|
|
||||||
instance_exec(*args, &b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_configuration(&block)
|
|
||||||
@after_configuration_callbacks << block
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute_after_configuration_callbacks
|
|
||||||
@after_configuration_callbacks.each do |b|
|
|
||||||
instance_exec(&b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def configure(key, &block)
|
|
||||||
@configure_callbacks[key] ||= []
|
|
||||||
@configure_callbacks[key] << block
|
|
||||||
end
|
|
||||||
|
|
||||||
def execute_configure_callbacks(key)
|
|
||||||
@configure_callbacks[key] ||= []
|
|
||||||
@configure_callbacks[key].each do |b|
|
|
||||||
instance_exec(&b)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def set(key, default=nil, &block)
|
def set(key, default=nil, &block)
|
||||||
config.define_setting(key, default) unless config.defines_setting?(key)
|
config.define_setting(key, default) unless config.defines_setting?(key)
|
||||||
@app.config[key] = block_given? ? block : default
|
@app.config[key] = block_given? ? block : default
|
||||||
|
|
Loading…
Reference in a new issue