pixelflut 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9baf1f1bc33ff7224d647d35d142a7688c9bdc98d3c1195fbc247dfa0bd1c68f
4
- data.tar.gz: 98056e9d11872f5856de38e2fcfe3677d55a117cf9850e0ff62c0f862a8fdd73
3
+ metadata.gz: bc5f965ac963380d9f086a9d8fc8ae155fed8eda6e2a2466a57fc5ed9f38773c
4
+ data.tar.gz: 6350e684e3a17f65e3eb045f9d3ff0a8a988bce93f91460949441cd433194d96
5
5
  SHA512:
6
- metadata.gz: 5faac48d602c1d8bdc07b1786b5f74732a34c79370f140769ff3dcbc48156d8f433d05c7a62fbc353ca7bee88d697a820dc192c00a694f2f43df9dfe0c606fe7
7
- data.tar.gz: e337ed50dfe5e2192f0ee6c16568b8dba2b93a6376ba2e090df8f249a46390e3101797ba7c63f3ebeeeca054453191540a08b27d2c531b107b0338f982961189
6
+ metadata.gz: 92ea11881a51b23d2ba8cc3e79ce4eca85107c2640917875ab42022169a88fe22a3e5ec4875830e4dcd0a4266e03596f30528f0ee05c8b6fff001103c18a8926
7
+ data.tar.gz: c9037c48b74adf490248b186a0a29a7b54bc7cdf7f361031336bec2e6b25c96db303700facb64831ebc466b697f5f172132543f174cdc6ede7e9d5d383cfa879
data/TODO.md ADDED
@@ -0,0 +1,7 @@
1
+ # Pixelflut
2
+
3
+ ## Todo
4
+
5
+ - [ ] limit connections to _*one* per IP_
6
+ - [x] allow 10 (pixel-)actions per client
7
+ - [ ] mention the Gosu gem in the README
@@ -8,13 +8,30 @@ def options(cfg)
8
8
  opts.banner = 'usage: pxf server [options]'
9
9
  opts.separator(nil)
10
10
  opts.separator('valid options:')
11
- opts.on('-b', '--bind ADDR', String, 'bind to given address'){ |v| cfg.server.host = v }
12
- opts.on('-p', '--port PORT', Integer, 'select port(default: 1234)'){ |v| cfg.server.port = v }
13
- opts.on('-k', '--keep-alive', Float, 'set maximum keep-alive time'){ |v| cfg.server.keep_alive_time = v }
14
- opts.on('-r', '--read_buffer SIZE', Integer, 'set read buffer size (default: 1024)'){ |v| cfg.server.read_buffer_size = v }
15
- opts.on('-w', '--width WIDTH', Integer, 'set canvas width (default: 800)'){ |v| cfg.width = v }
16
- opts.on('-h', '--height HEIGHT', Integer, 'set canvas height (default: 600)'){ |v| cfg.height = v }
17
- opts.on('-f', '--[no-]fullscreen', 'run in fullscreen mode'){ |v| cfg.fullscreen = v }
11
+ opts.on('-b', '--bind ADDR', String, 'bind to given address') do |v|
12
+ cfg.server.host = v
13
+ end
14
+ opts.on('-p', '--port PORT', Integer, 'select port(default: 1234)') do |v|
15
+ cfg.server.port = v
16
+ end
17
+ opts.on('-k', '--keep-alive', Float, 'set maximum keep-alive time') do |v|
18
+ cfg.server.keep_alive_time = v
19
+ end
20
+ opts.on('-r', '--read_buffer SIZE', Integer, 'set read buffer size (default: 1024)') do |v|
21
+ cfg.server.read_buffer_size = v
22
+ end
23
+ opts.on('-c', '--commands NUMBER', Integer, 'set number of continious processed commands (default: 10)') do |v|
24
+ cfg.server.max_commands_at_once = v
25
+ end
26
+ opts.on('-w', '--width WIDTH', Integer, 'set canvas width (default: 800)') do |v|
27
+ cfg.width = v
28
+ end
29
+ opts.on('-h', '--height HEIGHT', Integer, 'set canvas height (default: 600)') do |v|
30
+ cfg.height = v
31
+ end
32
+ opts.on('-f', '--[no-]fullscreen', 'run in fullscreen mode') do |v|
33
+ cfg.fullscreen = v
34
+ end
18
35
  end
19
36
  end
20
37
 
@@ -40,6 +40,7 @@ module Pixelflut
40
40
  end
41
41
 
42
42
  def update
43
+ # self.caption = @image.changes
43
44
  @draw_image = nil unless 0 == @image.changes
44
45
  end
45
46
 
@@ -8,10 +8,11 @@ module Pixelflut
8
8
  :host,
9
9
  :port,
10
10
  :keep_alive_time,
11
- :read_buffer_size
11
+ :read_buffer_size,
12
+ :max_commands_at_once
12
13
  ) do
13
14
  def self.default
14
- new(nil, 1234, 1, 1024)
15
+ new(nil, 1234, 1, 1024, 10)
15
16
  end
16
17
  end
17
18
 
@@ -20,8 +21,14 @@ module Pixelflut
20
21
  def initialize(canvas, config = Configuration.default)
21
22
  @canvas, @config = canvas, config
22
23
  @socket, @connections = nil, {}
23
- @on_end = ->(conn){ @connections.delete(conn) }
24
- @size = "SIZE #{canvas.width} #{canvas.height}\n".freeze
24
+ @ccfg = Connection::Configuration.new(
25
+ keep_alive_time: config.keep_alive_time,
26
+ read_buffer_size: config.read_buffer_size,
27
+ max_commands_at_once: config.max_commands_at_once,
28
+ canvas: canvas,
29
+ size_result: "SIZE #{canvas.width} #{canvas.height}\n".freeze,
30
+ on_end: ->(conn){ @connections.delete(conn) }
31
+ ).freeze
25
32
  end
26
33
 
27
34
  def connection_count
@@ -30,10 +37,9 @@ module Pixelflut
30
37
 
31
38
  def update
32
39
  return create_socket unless @socket
33
- now = Time.now.to_f
34
40
  incoming = @socket.accept_nonblock(exception: false)
35
- create_connection(incoming, now) unless Symbol === incoming
36
- @connections.keys.each{ |con| con.update(now) }
41
+ create_connection(incoming) unless Symbol === incoming
42
+ @connections.keys.each(&:update)
37
43
  end
38
44
 
39
45
  def run
@@ -44,8 +50,8 @@ module Pixelflut
44
50
 
45
51
  private
46
52
 
47
- def create_connection(incoming, now)
48
- con = Connection.new(incoming, now, @config, @canvas, @size, @on_end)
53
+ def create_connection(incoming)
54
+ con = Connection.new(incoming, @ccfg)
49
55
  @connections[con] = con
50
56
  end
51
57
 
@@ -55,25 +61,37 @@ module Pixelflut
55
61
  end
56
62
 
57
63
  class Connection
58
- def initialize(socket, now, config, canvas, size, on_end)
59
- @socket, @last_tm, @config, @canvas, @size, @on_end = socket, now, config, canvas, size, on_end
60
- # @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
61
- @buffer = ''
64
+ Configuration = Struct.new(
65
+ :keep_alive_time,
66
+ :read_buffer_size,
67
+ :max_commands_at_once,
68
+ :canvas,
69
+ :size_result,
70
+ :on_end,
71
+ keyword_init: true
72
+ )
73
+
74
+ def initialize(socket, config)
75
+ @socket, @config = socket, config
76
+ # socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
77
+ @last_tm, @buffer = Time.now.to_f, ''
62
78
  end
63
79
 
64
80
  def close(_reason)
65
81
  socket, @socket = @socket, nil
66
82
  return unless socket
67
83
  socket.close
68
- @on_end.call(self)
84
+ @config.on_end.call(self)
85
+ false
69
86
  end
70
87
 
71
- def update(now)
88
+ def update
72
89
  index = @buffer.index("\n")
73
- return process_buffer(index, now) if index
90
+ return process_loop(index) if index
74
91
  read_size = @config.read_buffer_size - @buffer.size
75
92
  return close(:buffer_exceeded) if read_size <= 0
76
93
  str = @socket.recv_nonblock(read_size, exception: false)
94
+ now = Time.now.to_f
77
95
  return (now - @last_tm > @config.keep_alive_time ? close(:timeout) : nil) if Symbol === str
78
96
  return close(:closed_by_peer) if 0 == str.size
79
97
  @buffer += str
@@ -82,38 +100,48 @@ module Pixelflut
82
100
 
83
101
  private
84
102
 
85
- def next_command(index, now)
103
+ def next_command(index)
86
104
  @buffer = @buffer[index, @buffer.size - index]
87
- @last_tm = now
105
+ @last_tm = Time.now.to_f
106
+ true
88
107
  end
89
108
 
90
- def command_size(index, now)
91
- @socket.sendmsg_nonblock(@size)
92
- next_command(index, now)
109
+ def command_size(index)
110
+ @socket.sendmsg_nonblock(@config.size_result)
111
+ next_command(index)
93
112
  end
94
113
 
95
- def command_px(command, index, now)
114
+ def command_px(command, index)
96
115
  _, x, y, color = command.split(' ', 4)
97
116
  return close(:color_expected) unless color
98
- @canvas[x.to_i, y.to_i] = color
99
- next_command(index, now)
117
+ @config.canvas[x.to_i, y.to_i] = color
118
+ next_command(index)
100
119
  end
101
120
 
102
- def command_rc(command, index, now)
121
+ def command_rc(command, index)
103
122
  _, x1, y1, x2, y2, color = command.split(' ', 6)
104
123
  return close(:color_expected) unless color
105
- @canvas.draw_rect(x1.to_i, y1.to_i, x2.to_i, y2.to_i, color)
106
- next_command(index, now)
124
+ @config.canvas.draw_rect(x1.to_i, y1.to_i, x2.to_i, y2.to_i, color)
125
+ next_command(index)
126
+ end
127
+
128
+ def process_loop(index)
129
+ command_count = @config.max_commands_at_once
130
+ while process_buffer(index)
131
+ index = @buffer.index("\n") or return
132
+ command_count -= 1
133
+ break if command_count <= 0
134
+ end
107
135
  end
108
136
 
109
- def process_buffer(index, now)
137
+ def process_buffer(index)
110
138
  return close(:max_command_size_exceeded) if index > 31 # 'RC 9999 9999 9999 9999 RRGGBBAA'.size
111
139
  command = @buffer[0, index]
112
140
  index += 1
113
- return command_size(index, now) if command == 'SIZE'
141
+ return command_px(command, index) if command.start_with?('PX ')
142
+ return command_rc(command, index) if command.start_with?('RC ')
114
143
  return close(:quit) if command == 'QUIT'
115
- return command_px(command, index, now) if command.start_with?('PX ')
116
- return command_rc(command, index, now) if command.start_with?('RC ')
144
+ return command_size(index) if command == 'SIZE'
117
145
  close(:bad_command)
118
146
  end
119
147
  end
@@ -1,3 +1,3 @@
1
1
  module Pixelflut
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '0.0.5'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixelflut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Blumtritt
@@ -68,6 +68,7 @@ extra_rdoc_files:
68
68
  files:
69
69
  - ".gitignore"
70
70
  - README.md
71
+ - TODO.md
71
72
  - bin/pxf
72
73
  - bin/pxf-generate
73
74
  - bin/pxf-help