Class: Amun::EventManager

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/amun/event_manager.rb

Overview

Event manager

Stores a stack of methods to call for each event, when an event is triggered it executes methods in Last-In-First-Out if a method returned true it continue execution of the next item in stack, if the method returned false it will stop executing the rest of stack.

Usage

could be used to register keyboard events, registering a set of actions to be executed when a key combination is pressed, the stack implementation will help stop execution at certain action if it needs to hijack that key.

Also could be used to as instrumentation tool between modules, some modules register for event, and others fire it when happens, e.g Window module needs to update it’s title when a file is saved, so it register update_title method to after_file_save event, when the Buffer module saves a file it should trigger that event, which executed the update_title.

Constant Summary collapse

INTERRUPTED =

Event is interrupted and no need to continue

:interrupted
CONTINUE =

Event is to be continued

:continue
CHAINED =

Event needs to be chained, will wait for next event

:chained

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeEventManager

Returns a new instance of EventManager.



30
31
32
33
# File 'lib/amun/event_manager.rb', line 30

def initialize
  @bindings = Hash.new { |h, k| h[k] = [] }
  @chains = Set.new
end

Class Method Details

.clearObject

clear the globally bound events if you need to reset this class to its default state, this method should clear all events and its associated objects/methods



156
157
158
# File 'lib/amun/event_manager.rb', line 156

def clear
  @instance = nil
end

.join(event, *event_managers) ⇒ Object

trigger an array of event_managers with an event and return one of the 3 statuses (INTERRUPTED, CHAINED, CONTINUE)

if any manager returned false or INTERRUPTED will not execute further and return INTERRUPTED,

if it faced an event that wants to chain the event it will return CHAINED if all next managers returned CONTINUE or also CHAINED

will return CONTINUE if all manangers returned continue

event(Symbol)

an event to trigger on all provided managers

*event_managers(*Array)

you can pass as many event managers as

you like as parameters to this method, it will be triggered in order



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/amun/event_manager.rb', line 138

def join(event, *event_managers)
  event_managers.inject(CONTINUE) do |result, manager|
    case manager.trigger(event)
    when INTERRUPTED, false
      break INTERRUPTED
    when CHAINED
      CHAINED
    else
      result
    end
  end
end

Instance Method Details

#bind(event, object, method) ⇒ Object

register an objectsmethod to be executed when the event is triggered

event(String)

and event to bind the method to

object(Object)

an object or class, that respond to method

method(Symbol)

a method name that should be executed when the event

is triggered



42
43
44
45
46
47
48
49
# File 'lib/amun/event_manager.rb', line 42

def bind(event, object, method)
  if !object.nil? && !object.respond_to?(method)
    raise ArgumentError, "#{method} : is not a method for #{object}"
  end

  add_chain(event.to_s)
  @bindings[event.to_s].unshift(object: object, method: method)
end

#bind_all(object, method) ⇒ Object

bind an object method to be executed when any event is triggered it uses a stack called all to register this method, this stack will be executed after the event specific stack is executed and didn’t stop execution



68
69
70
# File 'lib/amun/event_manager.rb', line 68

def bind_all(object, method)
  bind "all", object, method
end

#trigger(event) ⇒ Object

execute event stack of methods in Last-In-First-Out, then execute methods registered to be executed after all events with #bind_all method if any method in this chain returned false, it will stop the rest of the stack.

a chained event is an event that contain a space between 2 or more events lie “C-c C-x” so this event should be executed when these 2 events occure after each other, if you tried to trigger the first part C-c the trigger method will return CHAINED, assuming that C-c is not handled and also if handled the handle execution didn’t return false to interrupt the execution



94
95
96
97
98
99
# File 'lib/amun/event_manager.rb', line 94

def trigger(event)
  return INTERRUPTED unless trigger_for_event(event, event) &&
                            trigger_for_event("all", event)
  return CHAINED if chained?(event)
  CONTINUE
end

#unbind(event, object, method) ⇒ Object

remove all occurence of method from the event stack

event(String)

the event name

object(Object)

object that we #bind it’s method before

method(Symbol)

method name we #bind before



56
57
58
59
60
61
62
# File 'lib/amun/event_manager.rb', line 56

def unbind(event, object, method)
  @bindings[event].delete_if do |binding|
    binding[:object] == object && binding[:method] == method
  end
  @bindings.delete(event) if @bindings[event].empty?
  update_chains
end

#unbind_all(object, method) ⇒ Object

remove the method from executing after every event, only if you registered this method with #bind_all,

this won’t remove the method if it was registered with #bind



76
77
78
# File 'lib/amun/event_manager.rb', line 76

def unbind_all(object, method)
  unbind "all", object, method
end