module Pakyow::Support::Hookable::CommonMethods

Methods included at the class and instance level.

Public Instance Methods

add_hook(type, event, name, priority, exec, hook) click to toggle source

@api private

# File lib/pakyow/support/hookable.rb, line 162
def add_hook(type, event, name, priority, exec, hook)
  if priority.is_a?(Symbol)
    priority = PRIORITIES[priority]
  end

  if known_event?(event) || known_hook?(event)
    hook = {
      type: type,
      event: event.to_sym,
      name: name ? name.to_sym : nil,
      priority: priority,
      block: hook,
      exec: exec
    }

    (@__hook_hash[type.to_sym][event.to_sym] ||= []) << hook
    @__hooks << hook
  else
    raise ArgumentError, "#{event} is not a known hook event"
  end

  reprioritize!(type, event)
  pipeline!(type, event)

  if known_hook?(event)
    traverse_events_for_hook(event) do |hook_event|
      pipeline!(:before, hook_event); pipeline!(:after, hook_event)
    end
  end
end
call_hooks(type, event, *args) click to toggle source

Calls all registered hooks of type, for event.

@param type [Symbol] The type of event (e.g. before / after). @param event [Symbol] The name of the event.

# File lib/pakyow/support/hookable.rb, line 146
def call_hooks(type, event, *args)
  hooks(type, event).each do |hook|
    if hook[:exec]
      instance_exec(*args, &hook[:block])
    else
      hook[:block].call(*args)
    end
  end
end
hooks(type, event) click to toggle source

@api private

# File lib/pakyow/support/hookable.rb, line 157
def hooks(type, event)
  __hook_pipeline[type][event] || []
end
performing(event, *args) { || ... } click to toggle source

Calls all registered hooks for `event`, yielding between them.

@param event [Symbol] The name of the event.

# File lib/pakyow/support/hookable.rb, line 134
def performing(event, *args)
  call_hooks(:before, event, *args)
  value = yield
  call_hooks(:after, event, *args)
  value
end
pipeline!(type, event) click to toggle source

@api private

# File lib/pakyow/support/hookable.rb, line 213
def pipeline!(type, event)
  __hook_pipeline[type.to_sym][event.to_sym] = @__hook_hash.dig(type.to_sym, event.to_sym).to_a.flat_map { |hook|
    [@__hook_pipeline[:before][hook[:name]].to_a, hook, @__hook_pipeline[:after][hook[:name]].to_a].flatten
  }
end
reprioritize!(type, event) click to toggle source

@api private

# File lib/pakyow/support/hookable.rb, line 202
def reprioritize!(type, event)
  @__hook_hash[type.to_sym][event.to_sym] = @__hook_hash[type.to_sym][event.to_sym].group_by { |hook|
    hook[:priority]
  }.sort { |a, b|
    b[0] <=> a[0]
  }.flat_map { |group|
    group[1]
  }
end
traverse_events_for_hook(name) { |hook| ... } click to toggle source

@api private

# File lib/pakyow/support/hookable.rb, line 194
def traverse_events_for_hook(name, &block)
  if hook = @__hooks.find { |h| h[:name] == name.to_sym }
    yield hook[:event]
    traverse_events_for_hook(hook[:event], &block)
  end
end