orator 0.2.2 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +17 -17
- data/lib/generators/orator/config_generator.rb +2 -1
- data/lib/generators/orator/orator_generator.rb +15 -0
- data/lib/generators/templates/config.yml +2 -1
- data/lib/generators/templates/{handlers/example_handler.rb → orators/example_orator.rb} +5 -5
- data/lib/generators/templates/template_orator.rb +8 -0
- data/lib/orator/base.rb +181 -0
- data/lib/orator/cli.rb +36 -19
- data/lib/orator/event_handler.rb +5 -5
- data/lib/orator/version.rb +1 -1
- data/lib/orator.rb +4 -4
- data/spec/{base_handler_spec.rb → base_orator_spec.rb} +6 -6
- data/spec/event_handler_spec.rb +3 -3
- metadata +27 -19
- checksums.yaml +0 -15
- data/lib/generators/orator/handler_generator.rb +0 -15
- data/lib/generators/templates/template_handler.rb +0 -6
- data/lib/orator/handlers/base.rb +0 -183
- data/lib/orator/handlers.rb +0 -9
data/README.md
CHANGED
@@ -8,7 +8,7 @@ well as [em-websocket](https://github.com/igrigorik/em-websocket).
|
|
8
8
|
|
9
9
|
## Ruby on Rails Integration
|
10
10
|
Orator integrates easily with Ruby on Rails. Just add
|
11
|
-
|
11
|
+
|
12
12
|
gem 'orator'
|
13
13
|
|
14
14
|
to your Gemfile and `bundle install` away. In order to use it, you'll need to
|
@@ -19,18 +19,18 @@ add the following line to your `application.js` file:
|
|
19
19
|
Now you can use the orator client in your JavaScript! If the browser doesn't
|
20
20
|
support JavaScript, it'll fall back to a flash object.
|
21
21
|
|
22
|
-
|
22
|
+
### Server Orators
|
23
23
|
We'll start with the server-side stuff. A simple `rails g orator:config` will
|
24
|
-
place the file `orator_config.yml` in `config/`, and an example
|
25
|
-
`app/
|
26
|
-
documentation to it). Let's set up a
|
24
|
+
place the file `orator_config.yml` in `config/`, and an example orator in
|
25
|
+
`app/orators`. Feel free to modify the configuration file (I'll add
|
26
|
+
documentation to it). Let's set up a orator here:
|
27
27
|
|
28
28
|
```Ruby
|
29
|
-
class
|
29
|
+
class TestOrator < Orator::Base
|
30
30
|
```
|
31
31
|
|
32
32
|
This is important. Orator will not accept the Handler unless it is a child
|
33
|
-
of `Orator::
|
33
|
+
of `Orator::Base`. `Orator::Base` implements methods that
|
34
34
|
are used by Orator.
|
35
35
|
|
36
36
|
```Ruby
|
@@ -72,15 +72,15 @@ Either way, we're outputting a message that we received.
|
|
72
72
|
```Ruby
|
73
73
|
end
|
74
74
|
|
75
|
-
Orator.
|
75
|
+
Orator.add_orator(TestOrator)
|
76
76
|
```
|
77
77
|
|
78
|
-
Here we register our
|
79
|
-
But say we also want to handle a `socket.open` event. Our
|
78
|
+
Here we register our orator with Orator, so it can use it for routing events.
|
79
|
+
But say we also want to handle a `socket.open` event. Our orator above can't
|
80
80
|
handle that, sadly, so we use this method:
|
81
81
|
|
82
82
|
```Ruby
|
83
|
-
Orator.
|
83
|
+
Orator.add_orator do |events|
|
84
84
|
events.on('socket.open') do |data|
|
85
85
|
self.user = {}
|
86
86
|
|
@@ -94,7 +94,7 @@ end
|
|
94
94
|
```
|
95
95
|
|
96
96
|
So when the socket opens in `socket.open`, we set `#user` to an empty hash and
|
97
|
-
send a ping message (whose response will be handled by our
|
97
|
+
send a ping message (whose response will be handled by our TestOrator). When
|
98
98
|
we receive the `user.alias` message, we set the key-pair `:name => json["name"]`
|
99
99
|
on the `#user` hash. Cool, eh?
|
100
100
|
|
@@ -102,11 +102,11 @@ To run the server, run `orator --command start` in the root rails directory.
|
|
102
102
|
To daemonize it, run `orator --command start -d`. To stop, run
|
103
103
|
`orator --command stop`.
|
104
104
|
|
105
|
-
|
105
|
+
### JavaScript Client
|
106
106
|
Let's go through an example together.
|
107
107
|
|
108
|
-
```JavaScript
|
109
|
-
$(document).ready(function() {
|
108
|
+
```JavaScript
|
109
|
+
$(document).ready(function() {
|
110
110
|
Orator.setup("ws://host:port/path?query", function(events){
|
111
111
|
```
|
112
112
|
|
@@ -114,7 +114,7 @@ $(document).ready(function() {
|
|
114
114
|
events and routing, as well. There are some locally defined events that are
|
115
115
|
triggered even if the server hadn't sent them, such as `socket.open` and
|
116
116
|
`socket.close`.
|
117
|
-
|
117
|
+
|
118
118
|
```JavaScript
|
119
119
|
events.on('some.event', function() {})
|
120
120
|
```
|
@@ -123,7 +123,7 @@ Here we're binding some event named `some.event` to an empty function. Boring.
|
|
123
123
|
Note that the name of the event doesn't matter here.
|
124
124
|
|
125
125
|
```JavaScript
|
126
|
-
events.on('test.ping', function() {
|
126
|
+
events.on('test.ping', function() {
|
127
127
|
this.server.send('test.pong', { message: 'pong' });
|
128
128
|
});
|
129
129
|
```
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Orator
|
2
|
+
module Generators
|
3
|
+
class OratorGenerator < Rails::Generators::Base
|
4
|
+
|
5
|
+
source_root File.expand_path('../../templates', __FILE__)
|
6
|
+
argument :orator_name, :required => true,
|
7
|
+
:desc => "The name of the orator to generate."
|
8
|
+
|
9
|
+
def copy_configuration
|
10
|
+
template "template_orator.rb", "app/orators/#{orator_name}_orator.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
class
|
1
|
+
class ExampleOrator < Orator::Base
|
2
2
|
|
3
|
-
# This defines the name of the
|
4
|
-
# be able to correctly route your events to this
|
3
|
+
# This defines the name of the orator. THIS IS REQUIRED. Orator will not
|
4
|
+
# be able to correctly route your events to this orator if it is not put
|
5
5
|
# here.
|
6
|
-
#
|
6
|
+
#orator_name 'example'
|
7
7
|
|
8
8
|
# This defines a before event. It can take a block or a symbol. If it's a
|
9
9
|
# symbol, it'll call the method.
|
@@ -28,4 +28,4 @@ class ExampleHandler < Orator::Handlers::Base
|
|
28
28
|
|
29
29
|
end
|
30
30
|
|
31
|
-
#Orator.
|
31
|
+
#Orator.add_orator(ExampleOrator)
|
data/lib/orator/base.rb
ADDED
@@ -0,0 +1,181 @@
|
|
1
|
+
module Orator
|
2
|
+
|
3
|
+
# A base for the orators to split off of. It handles contexts and running
|
4
|
+
# methods. Most of the methods defined in this class are prefixed with
|
5
|
+
# two dashes to prevent polluting the namespace.
|
6
|
+
#
|
7
|
+
# @abstract
|
8
|
+
class Base
|
9
|
+
|
10
|
+
# Initialize the orator with the context.
|
11
|
+
#
|
12
|
+
# @param context [Object]
|
13
|
+
def initialize(context)
|
14
|
+
@__context = context
|
15
|
+
end
|
16
|
+
|
17
|
+
# This triggers an event if it's defined on this orator. If it is not
|
18
|
+
# defined, it raises an error.
|
19
|
+
#
|
20
|
+
# @param event [Symbol, String] the event to trigger.
|
21
|
+
# @raise [NoMethodError] if the event isn't defined on the orator.
|
22
|
+
# @return [Array<Object>, nil] the values of the trigger, or nil if the
|
23
|
+
# event was prevented.
|
24
|
+
def __trigger(event, *args)
|
25
|
+
orator, method_name = event.to_s.split('.')
|
26
|
+
__check_event(orator, method_name)
|
27
|
+
|
28
|
+
__run_callbacks(:before)
|
29
|
+
out = __run_event(method_name, args) unless @__prevent_event
|
30
|
+
__run_callbacks(:after)
|
31
|
+
|
32
|
+
out
|
33
|
+
end
|
34
|
+
|
35
|
+
# Checks the event list to see if this class responds to it.
|
36
|
+
#
|
37
|
+
# @return [Set<Symbol, Proc>, nil]
|
38
|
+
def __method_exists?(method)
|
39
|
+
__event_list[method]
|
40
|
+
end
|
41
|
+
|
42
|
+
# A map of the events that determine how this class will respond.
|
43
|
+
#
|
44
|
+
# @return [Hash]
|
45
|
+
# @see [ClassMethods::event_list]
|
46
|
+
def __event_list
|
47
|
+
self.class.event_list
|
48
|
+
end
|
49
|
+
|
50
|
+
# This tells the orator to not execute the events in the class. This
|
51
|
+
# should only be called in a `before` block.
|
52
|
+
def prevent_event
|
53
|
+
@__prevent_event = true
|
54
|
+
end
|
55
|
+
|
56
|
+
# Handles missing methods by delegating them to the context. Should
|
57
|
+
# never be called directly.
|
58
|
+
#
|
59
|
+
# @return [Object]
|
60
|
+
def method_missing(method, *args, &block)
|
61
|
+
super unless respond_to_missing?(method)
|
62
|
+
|
63
|
+
@__context.public_send(method, *args, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Lets Ruby know that there are some undefined methods on this class.
|
67
|
+
#
|
68
|
+
# @return [Boolean]
|
69
|
+
def respond_to_missing?(method, include_private = false)
|
70
|
+
@__context.respond_to?(method, include_private)
|
71
|
+
end
|
72
|
+
|
73
|
+
# This forwards {#send} on to the context.
|
74
|
+
#
|
75
|
+
# @return [Object]
|
76
|
+
def send(*args, &block)
|
77
|
+
@__context.send(*args, &block)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Run the event.
|
83
|
+
def __run_event(method_name, args)
|
84
|
+
result = __event_list[method_name].map do |responder|
|
85
|
+
responder = method(responder) if responder.is_a? Symbol
|
86
|
+
instance_exec *args, &responder
|
87
|
+
end
|
88
|
+
|
89
|
+
result
|
90
|
+
end
|
91
|
+
|
92
|
+
# Check the event, making sure that this orator can respond to it.
|
93
|
+
def __check_event(orator, method)
|
94
|
+
if orator != self.class.orator_name
|
95
|
+
raise NoMethodError,
|
96
|
+
"Event #{orator} does not match #{self.class.name}"
|
97
|
+
return
|
98
|
+
elsif !__method_exists?(method)
|
99
|
+
raise NoMethodError,
|
100
|
+
"Method #{method} does not exist on #{self.class.name}"
|
101
|
+
return
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Runs the callbacks.
|
106
|
+
def __run_callbacks(type)
|
107
|
+
self.class.send("#{type}_list").map do |cb|
|
108
|
+
if cb.is_a? Symbol
|
109
|
+
method(cb).call
|
110
|
+
else
|
111
|
+
instance_exec &cb
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
module ClassMethods
|
117
|
+
|
118
|
+
# This manages the orator's name. If an argument is passed, the name
|
119
|
+
# is set to that. Otherwise, it returns the orator's name.
|
120
|
+
#
|
121
|
+
# @param value [String, nil] the new name.
|
122
|
+
# @return [String] the orator name.
|
123
|
+
def orator_name(value = nil)
|
124
|
+
if value
|
125
|
+
@_orator_name = value
|
126
|
+
end
|
127
|
+
|
128
|
+
@_orator_name
|
129
|
+
end
|
130
|
+
|
131
|
+
# This registers a method for this orator.
|
132
|
+
#
|
133
|
+
# @param event [Symbol] the event to register it to.
|
134
|
+
# @return [void]
|
135
|
+
def on(event, method = nil, &block)
|
136
|
+
event_list[event.to_s] ||= []
|
137
|
+
|
138
|
+
if block_given?
|
139
|
+
event_list[event.to_s] << block
|
140
|
+
else
|
141
|
+
event_list[event.to_s] << (method || event).to_sym
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# The event matchings. The keys are the event name, the values can be
|
146
|
+
# an array of mappings or a the mapping itself.
|
147
|
+
#
|
148
|
+
# @return [Hash] the event list.
|
149
|
+
def event_list
|
150
|
+
@event_list ||= {}
|
151
|
+
end
|
152
|
+
|
153
|
+
# This registers this orator with the event handler by telling it what
|
154
|
+
# methods it responds to.
|
155
|
+
#
|
156
|
+
# @param event_handler [EventHandler]
|
157
|
+
def register_with(event_handler)
|
158
|
+
event_list.keys.each do |event|
|
159
|
+
event_handler.on("#{self.orator_name}.#{event}", self)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
[:before, :after].each do |type|
|
164
|
+
module_eval <<-METHOD, __FILE__, __LINE__
|
165
|
+
def #{type}(method = nil, &block)
|
166
|
+
#{type}_list << (method || block)
|
167
|
+
end
|
168
|
+
|
169
|
+
def #{type}_list
|
170
|
+
@#{type}_list ||= Set.new
|
171
|
+
end
|
172
|
+
METHOD
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
extend ClassMethods
|
177
|
+
orator_name ''
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
data/lib/orator/cli.rb
CHANGED
@@ -61,17 +61,18 @@ module Orator
|
|
61
61
|
|
62
62
|
def start
|
63
63
|
daemonize? do
|
64
|
-
|
64
|
+
load_orators
|
65
|
+
require_files
|
65
66
|
server = Orator::Server.new(yaml_options[:server_options])
|
66
|
-
|
67
|
+
orators = self.class.orators
|
67
68
|
|
68
69
|
puts "Starting server..." if Orator.debug
|
69
70
|
server.run do
|
70
|
-
|
71
|
-
if
|
72
|
-
|
71
|
+
orators.each do |orator|
|
72
|
+
if orator.is_a? Proc
|
73
|
+
orator.call(self)
|
73
74
|
else
|
74
|
-
|
75
|
+
orator.register_with(self)
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
@@ -99,20 +100,20 @@ module Orator
|
|
99
100
|
exit
|
100
101
|
end
|
101
102
|
|
102
|
-
# Add a
|
103
|
+
# Add a orator to be used by the server.
|
103
104
|
#
|
104
|
-
# @param klass [Class] the class to use as
|
105
|
-
# @return [Array<Class>] a list of
|
105
|
+
# @param klass [Class] the class to use as aorator.
|
106
|
+
# @return [Array<Class>] a list of orators that will be used for the
|
106
107
|
# server.
|
107
|
-
def self.
|
108
|
-
|
108
|
+
def self.add_orator(klass = nil, &block)
|
109
|
+
orators << (klass || block)
|
109
110
|
end
|
110
111
|
|
111
|
-
# A list of
|
112
|
+
# A list of orators.
|
112
113
|
#
|
113
|
-
# @return [Array<Class>] the
|
114
|
-
def self.
|
115
|
-
@
|
114
|
+
# @return [Array<Class>] the orators.
|
115
|
+
def self.orators
|
116
|
+
@orators ||= []
|
116
117
|
end
|
117
118
|
|
118
119
|
private
|
@@ -138,16 +139,32 @@ module Orator
|
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
141
|
-
# Loads the
|
142
|
+
# Loads the orators from the YAML file by requiring each file.
|
142
143
|
#
|
143
144
|
# @return [void]
|
144
|
-
def
|
145
|
-
|
146
|
-
Dir[yaml_options[:
|
145
|
+
def load_orators
|
146
|
+
return unless yaml_options[:orators_path]
|
147
|
+
Dir[yaml_options[:orators_path]].each do |file|
|
147
148
|
load file
|
148
149
|
end
|
149
150
|
end
|
150
151
|
|
152
|
+
# This loads files that are deemed required by the configuration file.
|
153
|
+
#
|
154
|
+
# @return [void]
|
155
|
+
def require_files
|
156
|
+
return unless yaml_options[:require]
|
157
|
+
requires = if yaml_options[:require].is_a? Array
|
158
|
+
yaml_options[:require]
|
159
|
+
else
|
160
|
+
[yaml_options[:require]]
|
161
|
+
end
|
162
|
+
|
163
|
+
requires.each do |r|
|
164
|
+
Dir[r].each { |f| load f }
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
151
168
|
# Daemonizes the block, if it's applicable.
|
152
169
|
#
|
153
170
|
# @yields [] in the new process, if daemonized; otherwise, a normal yield.
|
data/lib/orator/event_handler.rb
CHANGED
@@ -14,15 +14,15 @@ module Orator
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# This adds an event to the set. It can accept a block or a class. If
|
17
|
-
# it's a class, the class should inherit from [
|
17
|
+
# it's a class, the class should inherit from [Base]. If both
|
18
18
|
# a class and a block is given, the block is preferred.
|
19
19
|
#
|
20
20
|
# @param event [String, Symbol] the event to bind it to.
|
21
|
-
# @param klass [
|
21
|
+
# @param klass [Base, nil] the class that contains the method to
|
22
22
|
# use for the event.
|
23
23
|
# @param count [Numeric, nil] the number of times to run this event. No
|
24
24
|
# value is an infinite number of times.
|
25
|
-
# @raise [ArgumentError] if klass isn't a subclass of
|
25
|
+
# @raise [ArgumentError] if klass isn't a subclass of Base.
|
26
26
|
# @return [void]
|
27
27
|
def on(event, klass = nil, count = nil, &block)
|
28
28
|
puts "Binding #{event} to #{klass || block}..." if Orator.debug
|
@@ -30,7 +30,7 @@ module Orator
|
|
30
30
|
|
31
31
|
if block_given?
|
32
32
|
data[:block] = block
|
33
|
-
elsif klass and klass <
|
33
|
+
elsif klass and klass < Base
|
34
34
|
data[:class] = klass
|
35
35
|
else
|
36
36
|
raise ArgumentError, "No class or block was given."
|
@@ -52,7 +52,7 @@ module Orator
|
|
52
52
|
puts "Running event #{event}..." if Orator.debug
|
53
53
|
events(event).map do |event|
|
54
54
|
puts "Found responder #{event[:block] || event[:class]}" if Orator.debug
|
55
|
-
|
55
|
+
|
56
56
|
run_event(event, context, args)
|
57
57
|
if event[:count] then event[:count] -= 1 end
|
58
58
|
end
|
data/lib/orator/version.rb
CHANGED
data/lib/orator.rb
CHANGED
@@ -5,10 +5,10 @@ require 'set'
|
|
5
5
|
require 'ostruct'
|
6
6
|
require 'em-websocket'
|
7
7
|
|
8
|
+
require 'orator/base'
|
8
9
|
require 'orator/server'
|
9
10
|
require 'orator/client'
|
10
11
|
require 'orator/version'
|
11
|
-
require 'orator/handlers'
|
12
12
|
require 'orator/event_handler'
|
13
13
|
require 'orator/middle_ground'
|
14
14
|
|
@@ -19,8 +19,8 @@ module Orator
|
|
19
19
|
class << self; attr_accessor :debug; end
|
20
20
|
Orator.debug = false
|
21
21
|
|
22
|
-
def self.
|
23
|
-
Orator::CLI.
|
22
|
+
def self.add_orator(*args, &block)
|
23
|
+
Orator::CLI.add_orator(*args, &block)
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
describe Orator::
|
1
|
+
describe Orator::Base do
|
2
2
|
it "should call before blocks" do
|
3
3
|
something = double('something')
|
4
4
|
something.should_receive(:to_call)
|
5
5
|
klass = Class.new(described_class) do
|
6
|
-
|
6
|
+
orator_name 'test'
|
7
7
|
before { something.to_call }
|
8
8
|
on 'some_event'
|
9
9
|
def some_event; end
|
@@ -21,7 +21,7 @@ describe Orator::Handlers::Base do
|
|
21
21
|
something = double('something')
|
22
22
|
something.should_not_receive(:to_call)
|
23
23
|
klass = Class.new(described_class) do
|
24
|
-
|
24
|
+
orator_name 'test'
|
25
25
|
before { prevent_event }
|
26
26
|
on('some_event') { something.to_call }
|
27
27
|
end
|
@@ -33,7 +33,7 @@ describe Orator::Handlers::Base do
|
|
33
33
|
event_handler = double('event_handler')
|
34
34
|
|
35
35
|
klass = Class.new(described_class) do
|
36
|
-
|
36
|
+
orator_name 'test'
|
37
37
|
|
38
38
|
on('some_event') { }
|
39
39
|
end
|
@@ -48,7 +48,7 @@ describe Orator::Handlers::Base do
|
|
48
48
|
something.should_not_receive(:to_call)
|
49
49
|
|
50
50
|
klass = Class.new(described_class) do
|
51
|
-
|
51
|
+
orator_name 'test'
|
52
52
|
|
53
53
|
before :do_something
|
54
54
|
|
@@ -63,7 +63,7 @@ describe Orator::Handlers::Base do
|
|
63
63
|
it "should be able to use a different method" do
|
64
64
|
|
65
65
|
klass = Class.new(described_class) do
|
66
|
-
|
66
|
+
orator_name 'test'
|
67
67
|
|
68
68
|
on 'some_event', :other_method
|
69
69
|
def other_method; end
|
data/spec/event_handler_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
describe Orator::EventHandler do
|
2
2
|
it "should initalize with block" do
|
3
|
-
expect {
|
4
|
-
EventHandler.new { raise StandardError }
|
3
|
+
expect {
|
4
|
+
EventHandler.new { raise StandardError }
|
5
5
|
}.to raise_error(StandardError)
|
6
6
|
end
|
7
7
|
|
@@ -13,7 +13,7 @@ describe Orator::EventHandler do
|
|
13
13
|
subject.events.first[:block].should be_kind_of Proc
|
14
14
|
end
|
15
15
|
|
16
|
-
class SomeClass < Orator::
|
16
|
+
class SomeClass < Orator::Base; end
|
17
17
|
|
18
18
|
it "should accept a class for an event" do
|
19
19
|
subject.on(:some_event, SomeClass)
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.2
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Jeremy Rodi
|
@@ -13,6 +14,7 @@ dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: em-websocket
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: oj
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: swf_fu
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,6 +62,7 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: rspec
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
67
|
- - ~>
|
60
68
|
- !ruby/object:Gem::Version
|
@@ -62,6 +70,7 @@ dependencies:
|
|
62
70
|
type: :development
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
75
|
- - ~>
|
67
76
|
- !ruby/object:Gem::Version
|
@@ -75,53 +84,52 @@ executables:
|
|
75
84
|
extensions: []
|
76
85
|
extra_rdoc_files: []
|
77
86
|
files:
|
87
|
+
- lib/tasks/orator.rake
|
88
|
+
- lib/orator.rb
|
89
|
+
- lib/orator/engine.rb
|
90
|
+
- lib/orator/server.rb
|
91
|
+
- lib/orator/base.rb
|
78
92
|
- lib/orator/middle_ground.rb
|
93
|
+
- lib/orator/event_handler.rb
|
79
94
|
- lib/orator/version.rb
|
80
|
-
- lib/orator/handlers.rb
|
81
|
-
- lib/orator/server.rb
|
82
95
|
- lib/orator/cli.rb
|
83
96
|
- lib/orator/client.rb
|
84
|
-
- lib/
|
85
|
-
- lib/orator/engine.rb
|
86
|
-
- lib/orator/event_handler.rb
|
87
|
-
- lib/generators/orator/handler_generator.rb
|
88
|
-
- lib/generators/orator/config_generator.rb
|
89
|
-
- lib/generators/templates/template_handler.rb
|
97
|
+
- lib/generators/templates/template_orator.rb
|
90
98
|
- lib/generators/templates/config.yml
|
91
|
-
- lib/generators/templates/
|
92
|
-
- lib/orator.rb
|
93
|
-
- lib/
|
99
|
+
- lib/generators/templates/orators/example_orator.rb
|
100
|
+
- lib/generators/orator/config_generator.rb
|
101
|
+
- lib/generators/orator/orator_generator.rb
|
94
102
|
- bin/orator
|
103
|
+
- spec/event_handler_spec.rb
|
104
|
+
- spec/middle_ground_spec.rb
|
95
105
|
- spec/client_spec.rb
|
106
|
+
- spec/base_orator_spec.rb
|
96
107
|
- spec/spec_helper.rb
|
97
|
-
- spec/middle_ground_spec.rb
|
98
|
-
- spec/event_handler_spec.rb
|
99
|
-
- spec/base_handler_spec.rb
|
100
108
|
- README.md
|
101
109
|
- Rakefile
|
102
110
|
- LICENSE
|
103
111
|
homepage: http://github.com/redjazz96/orator
|
104
112
|
licenses: []
|
105
|
-
metadata: {}
|
106
113
|
post_install_message:
|
107
114
|
rdoc_options: []
|
108
115
|
require_paths:
|
109
116
|
- lib
|
110
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
111
119
|
requirements:
|
112
120
|
- - ! '>='
|
113
121
|
- !ruby/object:Gem::Version
|
114
122
|
version: '0'
|
115
123
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
116
125
|
requirements:
|
117
126
|
- - ! '>='
|
118
127
|
- !ruby/object:Gem::Version
|
119
128
|
version: '0'
|
120
129
|
requirements: []
|
121
130
|
rubyforge_project:
|
122
|
-
rubygems_version:
|
131
|
+
rubygems_version: 1.8.24
|
123
132
|
signing_key:
|
124
|
-
specification_version:
|
133
|
+
specification_version: 3
|
125
134
|
summary: Magic for your browser.
|
126
135
|
test_files: []
|
127
|
-
has_rdoc: false
|
checksums.yaml
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
---
|
2
|
-
!binary "U0hBMQ==":
|
3
|
-
metadata.gz: !binary |-
|
4
|
-
OGNmZTliMTc2ZjkxYTM1NzU0YmE2MzY4ODE5MTQ0Y2EyYzBlODU1ZQ==
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YmJhNDE5ZDI1YmY3OGQ5MjlkMTY5OGE0YTNhZjU5Y2JlMTFmOThhZA==
|
7
|
-
!binary "U0hBNTEy":
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
NTI3YjA0NjdlMjBjOWU4Zjk0NWI1MGMyYmE0YzkzNzVjMzQ4YTE3NzhhNWQ5
|
10
|
-
NDc0MGRkODIzZDhlMjg0ZGQ1ZDYyYzA0MDgwM2U5ZWI3YzMzNDc3YWZkNDRj
|
11
|
-
NDE4NDc1MmYxMjk4YTY0OTk0NzkzNjg2MmQyMWI2NGIwNWMxMDI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NGRmM2U1NmVmNWI0YmFiNDM5NjBkMGUwNDYyYzgzYmQ0ZWE4YWEwNmFmMmI5
|
14
|
-
NjRkNGZhMmZlZTlkYzRmOWI2ZDE0OTY4Y2NhODQxY2MxODRhZGQ0NDk1N2Jl
|
15
|
-
MDYxM2ZiZmU0NDhjMmU0N2FiODk2Mzc3OWYyOWMxYzBjODMyNDI=
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Orator
|
2
|
-
module Generators
|
3
|
-
class HandlerGenerator < Rails::Generators::Base
|
4
|
-
|
5
|
-
source_root File.expand_path('../../templates', __FILE__)
|
6
|
-
argument :handler_name, :required => true,
|
7
|
-
:desc => "The name of the handler to use."
|
8
|
-
|
9
|
-
def copy_configuration
|
10
|
-
template "template_handler.rb", "app/handlers/#{handler_name}_handler.rb"
|
11
|
-
end
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/orator/handlers/base.rb
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
module Orator
|
2
|
-
module Handlers
|
3
|
-
|
4
|
-
# A base for the handlers to split off of. It handles contexts and running
|
5
|
-
# methods. Most of the methods defined in this class are prefixed with
|
6
|
-
# two dashes to prevent polluting the namespace.
|
7
|
-
#
|
8
|
-
# @abstract
|
9
|
-
class Base
|
10
|
-
|
11
|
-
# Initialize the handler with the context.
|
12
|
-
#
|
13
|
-
# @param context [Object]
|
14
|
-
def initialize(context)
|
15
|
-
@__context = context
|
16
|
-
end
|
17
|
-
|
18
|
-
# This triggers an event if it's defined on this handler. If it is not
|
19
|
-
# defined, it raises an error.
|
20
|
-
#
|
21
|
-
# @param event [Symbol, String] the event to trigger.
|
22
|
-
# @raise [NoMethodError] if the event isn't defined on the handler.
|
23
|
-
# @return [Array<Object>, nil] the values of the trigger, or nil if the
|
24
|
-
# event was prevented.
|
25
|
-
def __trigger(event, *args)
|
26
|
-
handler, method_name = event.to_s.split('.')
|
27
|
-
__check_event(handler, method_name)
|
28
|
-
|
29
|
-
__run_callbacks(:before)
|
30
|
-
out = __run_event(method_name, args) unless @__prevent_event
|
31
|
-
__run_callbacks(:after)
|
32
|
-
|
33
|
-
out
|
34
|
-
end
|
35
|
-
|
36
|
-
# Checks the event list to see if this class responds to it.
|
37
|
-
#
|
38
|
-
# @return [Set<Symbol, Proc>, nil]
|
39
|
-
def __method_exists?(method)
|
40
|
-
__event_list[method]
|
41
|
-
end
|
42
|
-
|
43
|
-
# A map of the events that determine how this class will respond.
|
44
|
-
#
|
45
|
-
# @return [Hash]
|
46
|
-
# @see [ClassMethods::event_list]
|
47
|
-
def __event_list
|
48
|
-
self.class.event_list
|
49
|
-
end
|
50
|
-
|
51
|
-
# This tells the handler to not execute the events in the class. This
|
52
|
-
# should only be called in a `before` block.
|
53
|
-
def prevent_event
|
54
|
-
@__prevent_event = true
|
55
|
-
end
|
56
|
-
|
57
|
-
# Handles missing methods by delegating them to the context. Should
|
58
|
-
# never be called directly.
|
59
|
-
#
|
60
|
-
# @return [Object]
|
61
|
-
def method_missing(method, *args, &block)
|
62
|
-
super unless respond_to_missing?(method)
|
63
|
-
|
64
|
-
@__context.public_send(method, *args, &block)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Lets Ruby know that there are some undefined methods on this class.
|
68
|
-
#
|
69
|
-
# @return [Boolean]
|
70
|
-
def respond_to_missing?(method, include_private = false)
|
71
|
-
@__context.respond_to?(method, include_private)
|
72
|
-
end
|
73
|
-
|
74
|
-
# This forwards {#send} on to the context.
|
75
|
-
#
|
76
|
-
# @return [Object]
|
77
|
-
def send(*args, &block)
|
78
|
-
@__context.send(*args, &block)
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
# Run the event.
|
84
|
-
def __run_event(method_name, args)
|
85
|
-
result = __event_list[method_name].map do |responder|
|
86
|
-
responder = method(responder) if responder.is_a? Symbol
|
87
|
-
instance_exec *args, &responder
|
88
|
-
end
|
89
|
-
|
90
|
-
result
|
91
|
-
end
|
92
|
-
|
93
|
-
# Check the event, making sure that this handler can respond to it.
|
94
|
-
def __check_event(handler, method)
|
95
|
-
if handler != self.class.handler_name
|
96
|
-
raise NoMethodError,
|
97
|
-
"Event #{handler} does not match #{self.class.name}"
|
98
|
-
return
|
99
|
-
elsif !__method_exists?(method)
|
100
|
-
raise NoMethodError,
|
101
|
-
"Method #{method} does not exist on #{self.class.name}"
|
102
|
-
return
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# Runs the callbacks.
|
107
|
-
def __run_callbacks(type)
|
108
|
-
self.class.send("#{type}_list").map do |cb|
|
109
|
-
if cb.is_a? Symbol
|
110
|
-
method(cb).call
|
111
|
-
else
|
112
|
-
instance_exec &cb
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
module ClassMethods
|
118
|
-
|
119
|
-
# This manages the handler's name. If an argument is passed, the name
|
120
|
-
# is set to that. Otherwise, it returns the handler's name.
|
121
|
-
#
|
122
|
-
# @param value [String, nil] the new name.
|
123
|
-
# @return [String] the handler name.
|
124
|
-
def handler_name(value = nil)
|
125
|
-
if value
|
126
|
-
@_handler_name = value
|
127
|
-
end
|
128
|
-
|
129
|
-
@_handler_name
|
130
|
-
end
|
131
|
-
|
132
|
-
# This registers a method for this Handler.
|
133
|
-
#
|
134
|
-
# @param event [Symbol] the event to register it to.
|
135
|
-
# @return [void]
|
136
|
-
def on(event, method = nil, &block)
|
137
|
-
event_list[event.to_s] ||= []
|
138
|
-
|
139
|
-
if block_given?
|
140
|
-
event_list[event.to_s] << block
|
141
|
-
else
|
142
|
-
event_list[event.to_s] << (method || event).to_sym
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# The event matchings. The keys are the event name, the values can be
|
147
|
-
# an array of mappings or a the mapping itself.
|
148
|
-
#
|
149
|
-
# @return [Hash] the event list.
|
150
|
-
def event_list
|
151
|
-
@event_list ||= {}
|
152
|
-
end
|
153
|
-
|
154
|
-
# This registers this handler with the event handler by telling it what
|
155
|
-
# methods it responds to.
|
156
|
-
#
|
157
|
-
# @param event_handler [EventHandler]
|
158
|
-
def register_with(event_handler)
|
159
|
-
event_list.keys.each do |event|
|
160
|
-
event_handler.on("#{self.handler_name}.#{event}", self)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
[:before, :after].each do |type|
|
165
|
-
module_eval <<-METHOD, __FILE__, __LINE__
|
166
|
-
def #{type}(method = nil, &block)
|
167
|
-
#{type}_list << (method || block)
|
168
|
-
end
|
169
|
-
|
170
|
-
def #{type}_list
|
171
|
-
@#{type}_list ||= Set.new
|
172
|
-
end
|
173
|
-
METHOD
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
extend ClassMethods
|
178
|
-
handler_name ''
|
179
|
-
|
180
|
-
end
|
181
|
-
|
182
|
-
end
|
183
|
-
end
|