pixelflut 0.0.4 → 0.0.5

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.
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