flammarion 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +12 -0
- data/lib/flammarion.rb +1 -1
- data/lib/flammarion/engraving.rb +0 -5
- data/lib/flammarion/revelator.rb +64 -17
- data/lib/flammarion/server.rb +34 -40
- data/lib/flammarion/version.rb +1 -1
- data/lib/html/build/stylesheets/all.css +8 -5
- data/lib/html/build/stylesheets/buttons.css +7 -5
- data/lib/html/build/stylesheets/engraving.css +1 -0
- data/lib/html/source/stylesheets/buttons.styl +4 -2
- data/lib/html/source/stylesheets/colors.styl +1 -0
- data/lib/html/source/stylesheets/engraving.styl +2 -0
- data/lib/rubame/rubame.rb +223 -0
- metadata +22 -5
data/LICENSE
CHANGED
@@ -91,3 +91,15 @@ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRU
|
|
91
91
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
92
92
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
93
93
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
94
|
+
|
95
|
+
## Rubame
|
96
|
+
|
97
|
+
(The MIT License)
|
98
|
+
|
99
|
+
Copyright © 2013 Mark Saward
|
100
|
+
|
101
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
102
|
+
|
103
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
104
|
+
|
105
|
+
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/flammarion.rb
CHANGED
data/lib/flammarion/engraving.rb
CHANGED
data/lib/flammarion/revelator.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'launchy'
|
3
|
+
require 'timeout'
|
4
|
+
|
1
5
|
module Flammarion
|
2
6
|
# Raised when flammarion cannot find any way to display an engraving.
|
3
7
|
# On Linux, Flammarion will first try to launch Electron using the command
|
@@ -14,40 +18,83 @@ module Flammarion
|
|
14
18
|
# @todo This all needs a lot of clean up
|
15
19
|
module Revelator
|
16
20
|
CHROME_PATH = ENV["FLAMMARION_REVELATOR_PATH"] || 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
|
17
|
-
|
21
|
+
|
22
|
+
def open_a_window(options = {})
|
23
|
+
if RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/
|
24
|
+
development_mode = ENV["FLAMMARION_DEVELOPMENT"] == "true"
|
25
|
+
else
|
26
|
+
development_mode = system("lsof -i:#{4567}", out: '/dev/null') and File.exist?("#{File.dirname(__FILE__)}/../html/source/index.html.slim")
|
27
|
+
end
|
28
|
+
host = "file://#{File.dirname(File.absolute_path(__FILE__))}/../html/build/index.html"
|
29
|
+
host = "http://localhost:4567/" if development_mode
|
30
|
+
|
31
|
+
@expect_title = options[:title] || "Flammarion-#{rand.to_s[2..-1]}"
|
32
|
+
url = "#{host}?path=#{@window_id}&port=#{server.port}&title=#{@expect_title}"
|
33
|
+
@browser_options = options.merge({url: url, development_mode: development_mode})
|
34
|
+
@requested_browser = ENV["FLAMMARION_BROWSER"] || options[:browser]
|
35
|
+
|
36
|
+
@browser = @@browsers.find do |browser|
|
37
|
+
next if @requested_browser and browser.name.to_s != @requested_browser
|
38
|
+
begin
|
39
|
+
__send__(browser.name, @browser_options)
|
40
|
+
rescue Exception
|
41
|
+
next
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
raise SetupError.new("You must have either electron or google-chrome installed and accesible via your path.") unless @browser
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
def wait_for_a_connection
|
50
|
+
Timeout.timeout(20) { sleep 0.5 while @sockets.empty? }
|
51
|
+
rescue Timeout::Error
|
52
|
+
raise SetupError.new("Timed out while waiting for a connecting using #{@browser.name}.")
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
@@browsers = []
|
57
|
+
def self.browser(name, &block)
|
58
|
+
@@browsers << OpenStruct.new(name: name, method:define_method(name, block))
|
59
|
+
end
|
60
|
+
|
61
|
+
browser :chrome_windows do |options|
|
62
|
+
return false unless RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/
|
18
63
|
file_path = File.absolute_path(File.join(File.dirname(__FILE__), ".."))
|
19
64
|
file_path = `cygpath -w '#{file_path}'`.strip if RbConfig::CONFIG["host_os"] == "cygwin"
|
20
65
|
resource = %[file\://#{file_path}/html/build/index.html]
|
21
|
-
resource = "http://localhost:4567/" if
|
66
|
+
resource = "http://localhost:4567/" if options[:development_mode]
|
22
67
|
chrome_path = CHROME_PATH
|
23
68
|
chrome_path = `cygpath -u '#{CHROME_PATH}'`.strip if RbConfig::CONFIG["host_os"] == "cygwin"
|
24
|
-
|
69
|
+
return false unless File.exist?(chrome_path)
|
25
70
|
Process.detach(spawn(chrome_path, %[--app=#{resource}?path=#{@window_id}&port=#{server.port}&title="#{options[:title] || "Flammarion%20Engraving"}"]))
|
26
71
|
end
|
27
72
|
|
28
|
-
|
29
|
-
return open_a_window_on_windows(options) if RbConfig::CONFIG["host_os"] =~ /cygwin|mswin|mingw/
|
30
|
-
developmentMode = system("lsof -i:#{4567}", out: '/dev/null') and File.exist?("#{File.dirname(__FILE__)}/../html/source/index.html.slim")
|
31
|
-
host = "file://#{File.dirname(File.absolute_path(__FILE__))}/../html/build/index.html"
|
32
|
-
host = "http://localhost:4567/" if developmentMode
|
33
|
-
|
34
|
-
@expect_title = options[:title] || "Flammarion-#{rand.to_s[2..-1]}"
|
35
|
-
|
73
|
+
browser :electron do |options|
|
36
74
|
if which('electron') then
|
37
|
-
Process.detach(spawn("electron #{File.dirname(File.absolute_path(__FILE__))}/../../electron '#{
|
38
|
-
return
|
75
|
+
Process.detach(spawn("electron #{File.dirname(File.absolute_path(__FILE__))}/../../electron '#{options[:url]}'"))
|
76
|
+
return true
|
39
77
|
end
|
78
|
+
false
|
79
|
+
end
|
40
80
|
|
81
|
+
browser :chrome do |options|
|
41
82
|
%w[google-chrome google-chrome-stable chromium chromium-browser chrome].each do |executable|
|
42
83
|
next unless which(executable)
|
43
|
-
@chrome.in, @chrome.out, @chrome.err, @chrome.thread = Open3.popen3("#{executable} --app='#{
|
44
|
-
|
84
|
+
@chrome.in, @chrome.out, @chrome.err, @chrome.thread = Open3.popen3("#{executable} --app='#{options[:url]}'")
|
85
|
+
return true if @chrome.in
|
45
86
|
end
|
87
|
+
return false
|
88
|
+
end
|
46
89
|
|
47
|
-
|
90
|
+
browser :www do |options|
|
91
|
+
# Last ditch effort to display something
|
92
|
+
Launchy.open(options[:url].gsub(/\s/, "%20")) do |error|
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
return true
|
48
96
|
end
|
49
97
|
|
50
|
-
private
|
51
98
|
def which(cmd)
|
52
99
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
53
100
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
data/lib/flammarion/server.rb
CHANGED
@@ -26,52 +26,47 @@ module Flammarion
|
|
26
26
|
at_exit { sleep 0.1 }
|
27
27
|
end
|
28
28
|
def start_server_internal
|
29
|
-
EM.run {
|
30
29
|
@port = 7870
|
31
30
|
@port = rand(65000 - 1024) + 1024 if Gem.win_platform?
|
32
31
|
begin
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
@server = Rubame::Server.new("0.0.0.0", @port)
|
33
|
+
while true do
|
34
|
+
@started = true
|
35
|
+
@server.run do |ws|
|
36
|
+
ws.onopen {
|
37
|
+
log "WebSocket connection open"
|
38
|
+
if @windows.include?(ws.handshake.path)
|
39
|
+
@windows[ws.handshake.path].sockets << ws
|
40
|
+
@windows[ws.handshake.path].on_connect.call() if @windows[ws.handshake.path].on_connect
|
41
|
+
@socket_paths[ws] = ws.handshake.path
|
42
|
+
else
|
43
|
+
log "No such window: #{handshake.path}"
|
44
|
+
end
|
45
|
+
}
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
ws.onclose do
|
48
|
+
log "Connection closed";
|
49
|
+
@windows[@socket_paths[ws]].disconnect(ws) if @windows[@socket_paths[ws]]
|
50
|
+
end
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
ws.onmessage { |msg|
|
53
|
+
Thread.new do
|
54
|
+
begin
|
55
|
+
@windows[@socket_paths[ws]].process_message(msg)
|
56
|
+
rescue Exception => e
|
57
|
+
Kernel.puts "#{e.message.to_s.red}\n#{e.backtrace.join("\n").light_red}"
|
58
|
+
if binding.respond_to? :pry
|
59
|
+
binding.pry
|
60
|
+
else
|
61
|
+
raise
|
62
|
+
end
|
60
63
|
end
|
61
64
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
ws.onerror { |err|
|
66
|
-
if binding.respond_to? :pry
|
67
|
-
binding.pry
|
68
|
-
else
|
69
|
-
raise
|
70
|
-
end
|
71
|
-
}
|
65
|
+
}
|
66
|
+
end
|
72
67
|
end
|
73
|
-
rescue RuntimeError
|
74
|
-
if
|
68
|
+
rescue RuntimeError, Errno::EADDRINUSE
|
69
|
+
if $!.message == "no acceptor (port is in use or requires root privileges)" or $!.is_a? Errno::EADDRINUSE
|
75
70
|
@port = rand(65000 - 1024) + 1024
|
76
71
|
retry
|
77
72
|
else
|
@@ -79,9 +74,8 @@ module Flammarion
|
|
79
74
|
end
|
80
75
|
end
|
81
76
|
@started = true
|
82
|
-
}
|
83
77
|
rescue Exception => e
|
84
|
-
unless e.is_a? SystemExit
|
78
|
+
unless e.is_a? SystemExit or e.is_a? Interrupt
|
85
79
|
Kernel.puts "Error in server:"
|
86
80
|
binding.pry if binding.respond_to? :pry
|
87
81
|
Kernel.puts e.message
|
data/lib/flammarion/version.rb
CHANGED
@@ -175,7 +175,7 @@
|
|
175
175
|
.full-button {
|
176
176
|
background-color: #eee;
|
177
177
|
color: #333;
|
178
|
-
font-family:
|
178
|
+
font-family: monospace;
|
179
179
|
border: 1px solid #242424;
|
180
180
|
padding: 1em;
|
181
181
|
text-decoration: none;
|
@@ -224,7 +224,7 @@
|
|
224
224
|
.inline-dropdown {
|
225
225
|
background-color: #eee;
|
226
226
|
color: #333;
|
227
|
-
font-family:
|
227
|
+
font-family: monospace;
|
228
228
|
border: 1px solid #242424;
|
229
229
|
padding: 1em;
|
230
230
|
text-decoration: none;
|
@@ -282,6 +282,8 @@ input:focus::-webkit-input-placeholder {
|
|
282
282
|
-moz-user-select: none;
|
283
283
|
-ms-user-select: none;
|
284
284
|
user-select: none;
|
285
|
+
font-family: monospace;
|
286
|
+
min-height: 1.4em;
|
285
287
|
}
|
286
288
|
.inline-checkbox > span {
|
287
289
|
vertical-align: middle;
|
@@ -322,7 +324,7 @@ input:focus::-webkit-input-placeholder {
|
|
322
324
|
#toolbar {
|
323
325
|
background-color: #000;
|
324
326
|
margin: 0px;
|
325
|
-
font-family:
|
327
|
+
font-family: monospace;
|
326
328
|
height: calc(2% + 15px);
|
327
329
|
}
|
328
330
|
.tool-button {
|
@@ -377,7 +379,7 @@ input:focus::-webkit-input-placeholder {
|
|
377
379
|
.inline-button {
|
378
380
|
background-color: #eee;
|
379
381
|
color: #333;
|
380
|
-
font-family:
|
382
|
+
font-family: monospace;
|
381
383
|
border: 1px solid #242424;
|
382
384
|
padding: 1em;
|
383
385
|
text-decoration: none;
|
@@ -408,7 +410,7 @@ input:focus::-webkit-input-placeholder {
|
|
408
410
|
.floating-button {
|
409
411
|
background-color: #eee;
|
410
412
|
color: #333;
|
411
|
-
font-family:
|
413
|
+
font-family: monospace;
|
412
414
|
border: 1px solid #242424;
|
413
415
|
padding: 1em;
|
414
416
|
text-decoration: none;
|
@@ -699,6 +701,7 @@ p a:hover {
|
|
699
701
|
-moz-user-select: text;
|
700
702
|
-ms-user-select: text;
|
701
703
|
user-select: text;
|
704
|
+
font-family: monospace;
|
702
705
|
}
|
703
706
|
.pane > .pane {
|
704
707
|
width: calc(100% + 16px);
|
@@ -1,7 +1,7 @@
|
|
1
1
|
.full-button {
|
2
2
|
background-color: #eee;
|
3
3
|
color: #333;
|
4
|
-
font-family:
|
4
|
+
font-family: monospace;
|
5
5
|
border: 1px solid #242424;
|
6
6
|
padding: 1em;
|
7
7
|
text-decoration: none;
|
@@ -50,7 +50,7 @@
|
|
50
50
|
.inline-dropdown {
|
51
51
|
background-color: #eee;
|
52
52
|
color: #333;
|
53
|
-
font-family:
|
53
|
+
font-family: monospace;
|
54
54
|
border: 1px solid #242424;
|
55
55
|
padding: 1em;
|
56
56
|
text-decoration: none;
|
@@ -108,6 +108,8 @@ input:focus::-webkit-input-placeholder {
|
|
108
108
|
-moz-user-select: none;
|
109
109
|
-ms-user-select: none;
|
110
110
|
user-select: none;
|
111
|
+
font-family: monospace;
|
112
|
+
min-height: 1.4em;
|
111
113
|
}
|
112
114
|
.inline-checkbox > span {
|
113
115
|
vertical-align: middle;
|
@@ -148,7 +150,7 @@ input:focus::-webkit-input-placeholder {
|
|
148
150
|
#toolbar {
|
149
151
|
background-color: #000;
|
150
152
|
margin: 0px;
|
151
|
-
font-family:
|
153
|
+
font-family: monospace;
|
152
154
|
height: calc(2% + 15px);
|
153
155
|
}
|
154
156
|
.tool-button {
|
@@ -203,7 +205,7 @@ input:focus::-webkit-input-placeholder {
|
|
203
205
|
.inline-button {
|
204
206
|
background-color: #eee;
|
205
207
|
color: #333;
|
206
|
-
font-family:
|
208
|
+
font-family: monospace;
|
207
209
|
border: 1px solid #242424;
|
208
210
|
padding: 1em;
|
209
211
|
text-decoration: none;
|
@@ -234,7 +236,7 @@ input:focus::-webkit-input-placeholder {
|
|
234
236
|
.floating-button {
|
235
237
|
background-color: #eee;
|
236
238
|
color: #333;
|
237
|
-
font-family:
|
239
|
+
font-family: monospace;
|
238
240
|
border: 1px solid #242424;
|
239
241
|
padding: 1em;
|
240
242
|
text-decoration: none;
|
@@ -4,7 +4,7 @@
|
|
4
4
|
buttony(raised = false)
|
5
5
|
background-color lighten($bg-color, 0%)
|
6
6
|
color darken($fg-color, 0%)
|
7
|
-
font-family
|
7
|
+
font-family $main-font
|
8
8
|
border $normal-border
|
9
9
|
padding 1em
|
10
10
|
text-decoration none
|
@@ -54,6 +54,8 @@ input:focus::-webkit-input-placeholder
|
|
54
54
|
padding 0.2em
|
55
55
|
-webkit-user-select none
|
56
56
|
user-select none
|
57
|
+
font-family $main-font
|
58
|
+
min-height 1.4em
|
57
59
|
& > span
|
58
60
|
vertical-align middle
|
59
61
|
& input[type=checkbox]
|
@@ -81,7 +83,7 @@ input:focus::-webkit-input-placeholder
|
|
81
83
|
#toolbar
|
82
84
|
background-color #000
|
83
85
|
margin 0px
|
84
|
-
font-family
|
86
|
+
font-family $main-font
|
85
87
|
height calc(2% + 15px)
|
86
88
|
|
87
89
|
.tool-button
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'websocket'
|
2
|
+
require 'socket'
|
3
|
+
require 'fiber'
|
4
|
+
|
5
|
+
module Rubame
|
6
|
+
class Server
|
7
|
+
def initialize(host, port)
|
8
|
+
Socket.do_not_reverse_lookup
|
9
|
+
@hostname = host
|
10
|
+
@port = port
|
11
|
+
|
12
|
+
@reading = []
|
13
|
+
@writing = []
|
14
|
+
|
15
|
+
@clients = {} # Socket as key, and Client as value
|
16
|
+
|
17
|
+
@socket = TCPServer.new(@hostname, @port)
|
18
|
+
@reading.push @socket
|
19
|
+
end
|
20
|
+
|
21
|
+
def accept
|
22
|
+
socket = @socket.accept_nonblock
|
23
|
+
@reading.push socket
|
24
|
+
handshake = WebSocket::Handshake::Server.new
|
25
|
+
client = Rubame::Client.new(socket, handshake, self)
|
26
|
+
|
27
|
+
while line = socket.gets
|
28
|
+
client.handshake << line
|
29
|
+
break if client.handshake.finished?
|
30
|
+
end
|
31
|
+
if client.handshake.valid?
|
32
|
+
@clients[socket] = client
|
33
|
+
client.write handshake.to_s
|
34
|
+
client.opened = true
|
35
|
+
return client
|
36
|
+
else
|
37
|
+
close(client)
|
38
|
+
end
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def read(client)
|
43
|
+
|
44
|
+
pairs = client.socket.recvfrom(2000)
|
45
|
+
messages = []
|
46
|
+
|
47
|
+
if pairs[0].length == 0
|
48
|
+
close(client)
|
49
|
+
else
|
50
|
+
client.frame << pairs[0]
|
51
|
+
|
52
|
+
while f = client.frame.next
|
53
|
+
if (f.type == :close)
|
54
|
+
close(client)
|
55
|
+
return messages
|
56
|
+
else
|
57
|
+
messages.push f
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
return messages
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def close(client)
|
68
|
+
@reading.delete client.socket
|
69
|
+
@clients.delete client.socket
|
70
|
+
begin
|
71
|
+
client.socket.close
|
72
|
+
rescue
|
73
|
+
end
|
74
|
+
client.closed = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def run(time = 0, &blk)
|
78
|
+
readable, writable = IO.select(@reading, @writing, nil, 0)
|
79
|
+
|
80
|
+
if readable
|
81
|
+
readable.each do |socket|
|
82
|
+
client = @clients[socket]
|
83
|
+
if socket == @socket
|
84
|
+
client = accept
|
85
|
+
else
|
86
|
+
msg = read(client)
|
87
|
+
client.messaged = msg
|
88
|
+
end
|
89
|
+
|
90
|
+
blk.call(client) if client and blk
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Check for lazy send items
|
95
|
+
timer_start = Time.now
|
96
|
+
time_passed = 0
|
97
|
+
begin
|
98
|
+
@clients.each do |s, c|
|
99
|
+
c.send_some_lazy(5)
|
100
|
+
end
|
101
|
+
time_passed = Time.now - timer_start
|
102
|
+
end while time_passed < time
|
103
|
+
end
|
104
|
+
|
105
|
+
def stop
|
106
|
+
@socket.close
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Client
|
111
|
+
attr_accessor :socket, :handshake, :frame, :opened, :messaged, :closed
|
112
|
+
|
113
|
+
def initialize(socket, handshake, server)
|
114
|
+
@socket = socket
|
115
|
+
@handshake = handshake
|
116
|
+
@frame = WebSocket::Frame::Incoming::Server.new(:version => @handshake.version)
|
117
|
+
@opened = false
|
118
|
+
@messaged = []
|
119
|
+
@lazy_queue = []
|
120
|
+
@lazy_current_queue = nil
|
121
|
+
@closed = false
|
122
|
+
@server = server
|
123
|
+
end
|
124
|
+
|
125
|
+
def write(data)
|
126
|
+
@socket.write data
|
127
|
+
end
|
128
|
+
|
129
|
+
def send(data)
|
130
|
+
frame = WebSocket::Frame::Outgoing::Server.new(:version => @handshake.version, :data => data, :type => :text)
|
131
|
+
begin
|
132
|
+
@socket.write frame
|
133
|
+
@socket.flush
|
134
|
+
rescue
|
135
|
+
@server.close(self) unless @closed
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def lazy_send(data)
|
140
|
+
@lazy_queue.push data
|
141
|
+
end
|
142
|
+
|
143
|
+
def get_lazy_fiber
|
144
|
+
# Create the fiber if needed
|
145
|
+
if @lazy_fiber == nil or !@lazy_fiber.alive?
|
146
|
+
@lazy_fiber = Fiber.new do
|
147
|
+
@lazy_current_queue.each do |data|
|
148
|
+
send(data)
|
149
|
+
Fiber.yield unless @lazy_current_queue[-1] == data
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
return @lazy_fiber
|
155
|
+
end
|
156
|
+
|
157
|
+
def send_some_lazy(count)
|
158
|
+
# To save on cpu cycles, we don't want to be chopping and changing arrays, which could get quite large. Instead,
|
159
|
+
# we iterate over an array which we are sure won't change out from underneath us.
|
160
|
+
unless @lazy_current_queue
|
161
|
+
@lazy_current_queue = @lazy_queue
|
162
|
+
@lazy_queue = []
|
163
|
+
end
|
164
|
+
|
165
|
+
completed = 0
|
166
|
+
begin
|
167
|
+
get_lazy_fiber.resume
|
168
|
+
completed += 1
|
169
|
+
end while (@lazy_queue.count > 0 or @lazy_current_queue.count > 0) and completed < count
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
def onopen(&blk)
|
174
|
+
if @opened
|
175
|
+
begin
|
176
|
+
blk.call
|
177
|
+
ensure
|
178
|
+
@opened = false
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def onmessage(&blk)
|
184
|
+
if @messaged.size > 0
|
185
|
+
begin
|
186
|
+
@messaged.each do |x|
|
187
|
+
blk.call(x.to_s)
|
188
|
+
end
|
189
|
+
ensure
|
190
|
+
@messaged = []
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def onclose(&blk)
|
196
|
+
if @closed
|
197
|
+
begin
|
198
|
+
blk.call
|
199
|
+
ensure
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
line = 0
|
206
|
+
end
|
207
|
+
|
208
|
+
if __FILE__==$0
|
209
|
+
server = Rubame::Server.new("0.0.0.0", 25222)
|
210
|
+
while (!$quit)
|
211
|
+
server.run do |client|
|
212
|
+
client.onopen do
|
213
|
+
puts "Server reports: client open"
|
214
|
+
end
|
215
|
+
client.onmessage do |mess|
|
216
|
+
puts "Server reports: message received: #{mess}"
|
217
|
+
end
|
218
|
+
client.onclose do
|
219
|
+
puts "Server reports: client closed"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flammarion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,16 +9,16 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-01-
|
12
|
+
date: 2016-01-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: rubame
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 0.0.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 0.0.2
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: colorize
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,6 +123,22 @@ dependencies:
|
|
123
123
|
- - ! '>='
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: launchy
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :runtime
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
126
142
|
- !ruby/object:Gem::Dependency
|
127
143
|
name: bundler
|
128
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,6 +194,7 @@ executables: []
|
|
178
194
|
extensions: []
|
179
195
|
extra_rdoc_files: []
|
180
196
|
files:
|
197
|
+
- lib/rubame/rubame.rb
|
181
198
|
- lib/html/Gemfile.lock
|
182
199
|
- lib/html/source/index.html.slim
|
183
200
|
- lib/html/source/layouts/layout.erb
|