chingu 0.9rc7 → 0.9rc8
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/example15_trait_timer2.rb +1 -1
- data/examples/example7_gfx_helpers.rb +23 -11
- data/examples/game1.rb +299 -15
- data/examples/high_score_list.yml +22 -22
- data/examples/media/city3.png +0 -0
- data/examples/media/enemy_plane.png +0 -0
- data/lib/chingu.rb +1 -1
- data/lib/chingu/animation.rb +58 -38
- data/lib/chingu/game_state_manager.rb +11 -41
- data/lib/chingu/game_states/edit.rb +5 -2
- data/lib/chingu/game_states/enter_name.rb +3 -3
- data/lib/chingu/game_states/network_client.rb +88 -67
- data/lib/chingu/game_states/network_server.rb +66 -103
- data/lib/chingu/game_states/network_state.rb +71 -0
- data/lib/chingu/gosu_ext/sample.rb +79 -0
- data/lib/chingu/gosu_ext/song.rb +96 -0
- data/lib/chingu/helpers/game_object.rb +5 -1
- data/lib/chingu/helpers/game_state.rb +2 -0
- data/lib/chingu/simple_menu.rb +2 -2
- data/lib/chingu/text.rb +25 -10
- data/lib/chingu/traits/sprite.rb +3 -3
- data/lib/chingu/viewport.rb +18 -14
- data/lib/chingu/window.rb +54 -0
- data/spec/chingu/animation_spec.rb +41 -3
- data/spec/chingu/game_state_manager_spec.rb +50 -3
- data/spec/chingu/network_spec.rb +144 -11
- metadata +20 -15
@@ -63,7 +63,11 @@ module Chingu
|
|
63
63
|
objects.each do |object|
|
64
64
|
object.each_pair do |klassname, attributes|
|
65
65
|
begin
|
66
|
-
klass =
|
66
|
+
klass = Object
|
67
|
+
names = klassname.split('::')
|
68
|
+
names.each do |name|
|
69
|
+
klass = klass.const_defined?(name) ? klass.const_get(name) : klass.const_missing(name)
|
70
|
+
end
|
67
71
|
unless klass.class == "GameObject" && !except.include?(klass)
|
68
72
|
puts "Creating #{klassname.to_s}: #{attributes.to_s}" if debug
|
69
73
|
object = klass.create(attributes)
|
@@ -31,6 +31,7 @@ module Chingu
|
|
31
31
|
#
|
32
32
|
module GameState
|
33
33
|
extend Forwardable
|
34
|
+
|
34
35
|
def_delegator :game_state_manager, :game_states
|
35
36
|
def_delegator :game_state_manager, :push_game_state
|
36
37
|
def_delegator :game_state_manager, :pop_game_state
|
@@ -38,6 +39,7 @@ module Chingu
|
|
38
39
|
def_delegator :game_state_manager, :transitional_game_state
|
39
40
|
def_delegator :game_state_manager, :current_game_state
|
40
41
|
def_delegator :game_state_manager, :clear_game_states
|
42
|
+
def_delegator :game_state_manager, :pop_until_game_state
|
41
43
|
end
|
42
44
|
|
43
45
|
end
|
data/lib/chingu/simple_menu.rb
CHANGED
@@ -49,8 +49,8 @@ module Chingu
|
|
49
49
|
elsif key.is_a? Image
|
50
50
|
GameObject.new(options.merge!(:image => key))
|
51
51
|
elsif key.is_a? GameObject
|
52
|
-
|
53
|
-
|
52
|
+
key.options.merge!(options.dup)
|
53
|
+
key
|
54
54
|
end
|
55
55
|
|
56
56
|
item.options[:on_select] = method(:on_select)
|
data/lib/chingu/text.rb
CHANGED
@@ -84,23 +84,20 @@ module Chingu
|
|
84
84
|
|
85
85
|
if options[:background]
|
86
86
|
@background = GameObject.new(:image => options[:background])
|
87
|
-
|
88
|
-
@
|
89
|
-
@background.zorder -= 1
|
90
|
-
@background.x -= @padding
|
91
|
-
@background.y -= @padding
|
92
|
-
@background.width = self.width + @padding * 2
|
93
|
-
@background.height = self.height + @padding * 2
|
87
|
+
bg_update
|
88
|
+
@no_bg_update = options[:no_bg_update] || false # always update background attribute
|
94
89
|
end
|
95
90
|
|
96
91
|
self.height = options[:height] if options[:height]
|
97
|
-
end
|
98
|
-
|
92
|
+
end
|
93
|
+
|
94
|
+
|
99
95
|
#
|
100
96
|
# Set a new text, a new image is created.
|
101
97
|
#
|
102
98
|
def text=(text)
|
103
|
-
@text
|
99
|
+
return if text.dup == @text # Have to make a dup for content comparison
|
100
|
+
@text = text.dup # Make a copy, again to have a different Objectid
|
104
101
|
create_image
|
105
102
|
end
|
106
103
|
|
@@ -111,6 +108,14 @@ module Chingu
|
|
111
108
|
@gosu_font.text_width(@text, @factor_x)
|
112
109
|
end
|
113
110
|
|
111
|
+
#
|
112
|
+
# Update the background attributes if necessary unless specified
|
113
|
+
#
|
114
|
+
def update
|
115
|
+
super
|
116
|
+
bg_update if @background and !@no_bg_update
|
117
|
+
end
|
118
|
+
|
114
119
|
#
|
115
120
|
# Draws @background if present + our text in @image
|
116
121
|
#
|
@@ -131,5 +136,15 @@ module Chingu
|
|
131
136
|
@image = Gosu::Image.from_text($window, @text, @font, @size)
|
132
137
|
end
|
133
138
|
end
|
139
|
+
|
140
|
+
def bg_update
|
141
|
+
@background.attributes = self.attributes
|
142
|
+
@background.color = ::Gosu::Color::WHITE
|
143
|
+
@background.zorder -= 1
|
144
|
+
@background.x -= @padding
|
145
|
+
@background.y -= @padding
|
146
|
+
@background.width = self.width + @padding * 2
|
147
|
+
@background.height = self.height + @padding * 2
|
148
|
+
end
|
134
149
|
end
|
135
150
|
end
|
data/lib/chingu/traits/sprite.rb
CHANGED
@@ -97,9 +97,9 @@ module Chingu
|
|
97
97
|
raise ArgumentError.new("No image set") if image.nil?
|
98
98
|
|
99
99
|
@image = if String === image
|
100
|
-
# 1) Try
|
101
|
-
# 2) Try
|
102
|
-
Gosu::Image.new($window, image,false)
|
100
|
+
# 1) Try looking up the picture using Chingus Image-cache
|
101
|
+
# 2) Try loading the image the normal way
|
102
|
+
Gosu::Image[image] rescue Gosu::Image.new($window, image,false)
|
103
103
|
elsif image.respond_to? :call
|
104
104
|
image.call
|
105
105
|
else
|
data/lib/chingu/viewport.rb
CHANGED
@@ -28,10 +28,10 @@ module Chingu
|
|
28
28
|
#
|
29
29
|
#
|
30
30
|
# TODO:
|
31
|
-
# Implement use of viewports angle, center_x, center_y
|
31
|
+
# Implement use of viewports angle, center_x, center_y
|
32
32
|
#
|
33
33
|
class Viewport
|
34
|
-
attr_accessor :x, :y, :x_target, :y_target, :x_lag, :y_lag, :game_area
|
34
|
+
attr_accessor :x, :y, :x_target, :y_target, :x_lag, :y_lag, :factor_x, :factor_y, :game_area
|
35
35
|
|
36
36
|
def initialize(options = {})
|
37
37
|
@x = options[:x] || 0
|
@@ -40,6 +40,8 @@ module Chingu
|
|
40
40
|
@y_target = options[:y_target] || @y
|
41
41
|
@x_lag = options[:x_lag] || 0
|
42
42
|
@y_lag = options[:y_lag] || 0
|
43
|
+
@factor_x = options[:factor_x] || 1
|
44
|
+
@factor_y = options[:factor_y] || 1
|
43
45
|
@game_area = Chingu::Rect.new(options[:game_area] || [@x, @y, $window.width, $window.height])
|
44
46
|
end
|
45
47
|
|
@@ -57,8 +59,8 @@ module Chingu
|
|
57
59
|
# TODO: Add support for x,y here!
|
58
60
|
#
|
59
61
|
def center_around(object)
|
60
|
-
self.x = object.x - $window.width / 2
|
61
|
-
self.y = object.y - $window.height / 2
|
62
|
+
self.x = object.x * @factor_x - $window.width / 2
|
63
|
+
self.y = object.y * @factor_y - $window.height / 2
|
62
64
|
end
|
63
65
|
|
64
66
|
#
|
@@ -114,14 +116,14 @@ module Chingu
|
|
114
116
|
# Modify viewports x and y from target_x / target_y and x_lag / y_lag
|
115
117
|
# Use this to have the viewport "slide" after the player
|
116
118
|
#
|
117
|
-
def move_towards_target
|
119
|
+
def move_towards_target
|
118
120
|
if @x_target && @x != @x_target
|
119
|
-
x_step = @x_target - @x
|
121
|
+
x_step = @x_target * @factor_x - @x
|
120
122
|
self.x = @x + x_step * (1.0 - @x_lag)
|
121
123
|
end
|
122
|
-
|
124
|
+
|
123
125
|
if @y_target && @y != @y_target
|
124
|
-
y_step = @y_target - @y
|
126
|
+
y_step = @y_target * @factor_y - @y
|
125
127
|
self.y = @y + y_step * (1.0 - @y_lag)
|
126
128
|
end
|
127
129
|
end
|
@@ -132,9 +134,9 @@ module Chingu
|
|
132
134
|
def x=(x)
|
133
135
|
@x = x
|
134
136
|
if @game_area
|
135
|
-
@x = @game_area.x
|
136
|
-
@x = @game_area.width
|
137
|
-
end
|
137
|
+
@x = @game_area.x * @factor_x if @x < @game_area.x * @factor_x
|
138
|
+
@x = @game_area.width * @factor_x - $window.width if @x > @game_area.width * @factor_x - $window.width
|
139
|
+
end
|
138
140
|
end
|
139
141
|
|
140
142
|
#
|
@@ -143,8 +145,8 @@ module Chingu
|
|
143
145
|
def y=(y)
|
144
146
|
@y = y
|
145
147
|
if @game_area
|
146
|
-
@y = @game_area.y
|
147
|
-
@y = @game_area.height
|
148
|
+
@y = @game_area.y * @factor_y if @y < @game_area.y * @factor_y
|
149
|
+
@y = @game_area.height * @factor_y - $window.height if @y > @game_area.height * @factor_y - $window.height
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
@@ -152,7 +154,9 @@ module Chingu
|
|
152
154
|
# Apply the X/Y viewport-translation, used by trait "viewport"
|
153
155
|
#
|
154
156
|
def apply(&block)
|
155
|
-
$window.translate(-@x.to_i, -@y.to_i
|
157
|
+
$window.translate(-@x.to_i, -@y.to_i) do
|
158
|
+
$window.scale(@factor_x, @factor_y, 0, 0, &block)
|
159
|
+
end
|
156
160
|
end
|
157
161
|
|
158
162
|
def to_s
|
data/lib/chingu/window.rb
CHANGED
@@ -64,6 +64,8 @@ module Chingu
|
|
64
64
|
@milliseconds_since_last_tick = 0
|
65
65
|
@factor = 1
|
66
66
|
@cursor = false
|
67
|
+
@times_muted = 0
|
68
|
+
@volume = DEFAULT_VOLUME
|
67
69
|
|
68
70
|
setup
|
69
71
|
end
|
@@ -194,5 +196,57 @@ module Chingu
|
|
194
196
|
|
195
197
|
$window = nil
|
196
198
|
end
|
199
|
+
|
200
|
+
# GLOBAL SOUND SETTINGS
|
201
|
+
|
202
|
+
DEFAULT_VOLUME = 1.0 # However, 0.5 is a better value for general use.
|
203
|
+
|
204
|
+
# Set the global volume of all Samples and Songs, not affected by Window being muted.
|
205
|
+
def volume=(value)
|
206
|
+
raise "Bad volume setting" unless value.is_a? Numeric
|
207
|
+
|
208
|
+
old_volume = @volume
|
209
|
+
@volume = [[value, 1.0].min, 0.0].max.to_f
|
210
|
+
|
211
|
+
Song.send(:recalculate_volumes, old_volume, @volume)
|
212
|
+
|
213
|
+
volume
|
214
|
+
end
|
215
|
+
|
216
|
+
# Volume of all Samples and Songs, not affected by the Window being muted.
|
217
|
+
attr_reader :volume
|
218
|
+
|
219
|
+
# Actual volume of all Samples and Songs, affected by the Window being muted.
|
220
|
+
def effective_volume
|
221
|
+
muted? ? 0.0 : @volume
|
222
|
+
end
|
223
|
+
|
224
|
+
# Mute the window and all Samples and Songs played.
|
225
|
+
# Muting stacks, so sound will only be heard if the number of unmutes is the same as the number of mutes.
|
226
|
+
def mute
|
227
|
+
unless muted?
|
228
|
+
Song.send(:resources).each_value {|song| song.send :mute }
|
229
|
+
end
|
230
|
+
@times_muted += 1
|
231
|
+
|
232
|
+
self
|
233
|
+
end
|
234
|
+
|
235
|
+
# Unmute the window and all Samples and Songs played.
|
236
|
+
# Muting stacks, so sound will only be heard if the number of unmutes is the same as the number of mutes.
|
237
|
+
def unmute
|
238
|
+
raise "Can't unmute when not muted" unless muted?
|
239
|
+
@times_muted -= 1
|
240
|
+
unless muted?
|
241
|
+
Song.send(:resources).each_value {|song| song.send :unmute }
|
242
|
+
end
|
243
|
+
|
244
|
+
self
|
245
|
+
end
|
246
|
+
|
247
|
+
# Is the window currently muted?
|
248
|
+
def muted?
|
249
|
+
@times_muted > 0
|
250
|
+
end
|
197
251
|
end
|
198
252
|
end
|
@@ -6,8 +6,9 @@ module Chingu
|
|
6
6
|
@game = Chingu::Window.new
|
7
7
|
@test_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'images')
|
8
8
|
Gosu::Image.autoload_dirs << @test_dir
|
9
|
-
@
|
10
|
-
@
|
9
|
+
@file = "droid_11x15.bmp"
|
10
|
+
@animation_clean = Animation.new(:file => @file)
|
11
|
+
@animation = Animation.new(:file => @file, :delay => 0)
|
11
12
|
end
|
12
13
|
|
13
14
|
after :each do
|
@@ -33,8 +34,45 @@ module Chingu
|
|
33
34
|
@anim = Animation.new(:file => "images/droid_11x15.bmp")
|
34
35
|
@anim.frames.count.should == 14
|
35
36
|
end
|
37
|
+
|
38
|
+
it "should load from a Gosu image" do
|
39
|
+
Dir.chdir(File.dirname(File.expand_path(__FILE__)))
|
40
|
+
@anim = Animation.new(:image => Gosu::Image["images/droid_11x15.bmp"], :size => [11, 15])
|
41
|
+
@anim.frames.count.should == 14
|
42
|
+
end
|
36
43
|
end
|
37
|
-
|
44
|
+
|
45
|
+
describe "Animation loading using :frames" do
|
46
|
+
it "should have the same frames" do
|
47
|
+
anim = Animation.new :frames => @animation_clean.frames
|
48
|
+
anim.frames.should == @animation_clean.frames
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should reject non-consistent frame sizes" do
|
52
|
+
->{ Animation.new :frames => @animation_clean.frames + [Gosu::Image[@file]]}.should raise_error ArgumentError
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "Animation loading using :image" do
|
57
|
+
before :each do
|
58
|
+
@anim = Animation.new :image => Gosu::Image[@file]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should have the same frames" do
|
62
|
+
@anim.frames.zip(@animation_clean.frames).all? { |a, b| a.to_blob == b.to_blob }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "Animation loading errors" do
|
67
|
+
it "should fail unless one of the creation params is given" do
|
68
|
+
->{ Animation.new }.should raise_error ArgumentError
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should fail if more than one creation params" do
|
72
|
+
->{ Animation.new :image => Gosu::Image[@file], :file => @file}.should raise_error ArgumentError
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
38
76
|
describe "Animation loading file: droid_11x15.bmp" do
|
39
77
|
it "should detect size and frames automatically from filename" do
|
40
78
|
@animation.size.should == [11,15]
|
@@ -60,22 +60,69 @@ module Chingu
|
|
60
60
|
describe "switch_game_state" do
|
61
61
|
before :each do
|
62
62
|
@game.push_game_state(Chingu::GameStates::Pause)
|
63
|
-
@game.switch_game_state(Chingu::GameStates::
|
63
|
+
@game.switch_game_state(Chingu::GameStates::Debug)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should replace current game state" do
|
67
|
-
@game.current_game_state.
|
67
|
+
@game.current_game_state.should be_a Chingu::GameStates::Debug
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should not change the total amount of game states" do
|
71
71
|
@game.game_states.count.should == 1
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
describe "pop_until_game_state" do
|
76
|
+
before :each do
|
77
|
+
@game.push_game_state(Chingu::GameStates::Pause)
|
78
|
+
@game.push_game_state(Chingu::GameStates::Debug)
|
79
|
+
@game.push_game_state(Chingu::GameStates::Debug)
|
80
|
+
@states = @game.game_state_manager.instance_variable_get(:@game_states).dup
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "with class" do
|
84
|
+
it "should finalize popped states" do
|
85
|
+
@states[1].should_receive(:finalize)
|
86
|
+
@states[2].should_receive(:finalize)
|
87
|
+
@game.pop_until_game_state(Chingu::GameStates::Pause)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should setup revealed states" do
|
91
|
+
@states[0].should_receive(:setup)
|
92
|
+
@states[1].should_receive(:setup)
|
93
|
+
@game.pop_until_game_state(Chingu::GameStates::Pause)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should pop down to the given game state" do
|
97
|
+
@game.pop_until_game_state(Chingu::GameStates::Pause)
|
98
|
+
@game.game_states.should eq [@states[0]]
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "with instance" do
|
103
|
+
it "should finalize popped states" do
|
104
|
+
@states[1].should_receive(:finalize)
|
105
|
+
@states[2].should_receive(:finalize)
|
106
|
+
@game.pop_until_game_state(@states[0])
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should setup revealed states" do
|
110
|
+
@states[0].should_receive(:setup)
|
111
|
+
@states[1].should_receive(:setup)
|
112
|
+
@game.pop_until_game_state(@states[0])
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should pop down to the given game state" do
|
116
|
+
@game.pop_until_game_state(@states[0])
|
117
|
+
@game.game_states.should eq [@states[0]]
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
74
121
|
|
75
122
|
describe "clear_game_states" do
|
76
123
|
it "should clear all game states" do
|
77
124
|
@game.push_game_state(Chingu::GameStates::Pause)
|
78
|
-
@game.
|
125
|
+
@game.push_game_state(Chingu::GameStates::Edit)
|
79
126
|
@game.clear_game_states
|
80
127
|
@game.game_states.count.should == 0
|
81
128
|
end
|
data/spec/chingu/network_spec.rb
CHANGED
@@ -16,14 +16,14 @@ module Chingu
|
|
16
16
|
|
17
17
|
describe Chingu::GameStates::NetworkServer do
|
18
18
|
it "should open listening port on start()" do
|
19
|
-
@server = described_class.new(:
|
19
|
+
@server = described_class.new(:address => "0.0.0.0", :port => 9999)
|
20
20
|
@server.should_receive(:on_start)
|
21
21
|
@server.start
|
22
22
|
@server.stop
|
23
23
|
end
|
24
24
|
|
25
25
|
it "client should timeout when connecting to blackhole ip" do
|
26
|
-
@client = Chingu::GameStates::NetworkClient.new(:
|
26
|
+
@client = Chingu::GameStates::NetworkClient.new(:address => "1.2.3.4", :port => 1234, :debug => true)
|
27
27
|
@client.connect
|
28
28
|
|
29
29
|
#@client.should_receive(:on_timeout) ## gives on_connection_refused instead, kind of ok.
|
@@ -32,15 +32,15 @@ module Chingu
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should call on_start_error() if failing" do
|
35
|
-
@server = described_class.new(:
|
35
|
+
@server = described_class.new(:address => "1.2.3.999", :port => 12345678) # crazy address:port
|
36
36
|
@server.should_receive(:on_start_error)
|
37
37
|
@server.start
|
38
38
|
@server.stop
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should call on_connect() and on_disconnect() when client connects" do
|
42
|
-
@server = described_class.new(:
|
43
|
-
@client = Chingu::GameStates::NetworkClient.new(:
|
42
|
+
@server = described_class.new(:address => "0.0.0.0", :port => 9999)
|
43
|
+
@client = Chingu::GameStates::NetworkClient.new(:address => "127.0.0.1", :port => 9999)
|
44
44
|
|
45
45
|
@server.should_receive(:on_start)
|
46
46
|
@server.should_receive(:on_connect).with(an_instance_of(TCPSocket))
|
@@ -58,19 +58,64 @@ module Chingu
|
|
58
58
|
end
|
59
59
|
|
60
60
|
describe Chingu::GameStates::NetworkClient do
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
describe "connect" do
|
62
|
+
it "should call on_connection_refused callback when connecting to closed port" do
|
63
|
+
@client = described_class.new(:address => "127.0.0.1", :port => 55421) # closed we assume
|
64
|
+
@client.should_receive(:on_connection_refused)
|
65
|
+
@client.connect
|
66
|
+
5.times { @client.update }
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not call on_timeout callback when unable to connect for less time than the timeout" do
|
70
|
+
@client = described_class.new(:address => "127.0.0.1", :port => 55421, :timeout => 250) # closed we assume
|
71
|
+
@client.connect
|
72
|
+
@client.should_not_receive(:on_timeout)
|
73
|
+
5.times { @client.update; sleep 0.01 }
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should call on_timeout callback when unable to connect for longer than the timeout" do
|
77
|
+
@client = described_class.new(:address => "127.0.0.1", :port => 55421, :timeout => 250) # closed we assume
|
78
|
+
@client.connect
|
79
|
+
@client.update
|
80
|
+
sleep 0.3
|
81
|
+
@client.should_receive(:on_timeout)
|
82
|
+
5.times { @client.update }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "Connecting" do
|
88
|
+
before :each do
|
89
|
+
@client = Chingu::GameStates::NetworkClient.new(:address => "127.0.0.1", :port => 9999)
|
90
|
+
@server = Chingu::GameStates::NetworkServer.new(:port => 9999)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should connect to the server, when the server starts before it" do
|
94
|
+
#@server.start
|
95
|
+
#@client.connect
|
96
|
+
#5.times { @client.update }
|
97
|
+
#@client.should be_connected
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should connect to the server, even when the server isn't initialy available" do
|
64
101
|
@client.connect
|
65
|
-
|
102
|
+
3.times { @client.update; sleep 0.2; @server.update; @client.flush }
|
103
|
+
@server.start
|
104
|
+
3.times { @client.update; sleep 0.2; @server.update; @client.flush }
|
105
|
+
@client.should be_connected
|
106
|
+
end
|
107
|
+
|
108
|
+
after :each do
|
109
|
+
@client.close
|
110
|
+
@server.close
|
66
111
|
end
|
67
112
|
end
|
68
113
|
|
69
114
|
describe "Network communication" do
|
70
115
|
before :each do
|
71
116
|
@server = Chingu::GameStates::NetworkServer.new(:port => 9999).start
|
72
|
-
@client = Chingu::GameStates::NetworkClient.new(:
|
73
|
-
@client2 = Chingu::GameStates::NetworkClient.new(:
|
117
|
+
@client = Chingu::GameStates::NetworkClient.new(:address => "127.0.0.1", :port => 9999).connect
|
118
|
+
@client2 = Chingu::GameStates::NetworkClient.new(:address => "127.0.0.1", :port => 9999).connect
|
74
119
|
@client.update until @client.connected?
|
75
120
|
@client2.update until @client2.connected?
|
76
121
|
end
|
@@ -123,6 +168,94 @@ module Chingu
|
|
123
168
|
end
|
124
169
|
end
|
125
170
|
end
|
171
|
+
|
172
|
+
describe "byte and packet counters" do
|
173
|
+
before :each do
|
174
|
+
@packet = "Hello! " * 10
|
175
|
+
@packet_length = Marshal.dump(@packet).length
|
176
|
+
@packet_length_with_header = @packet_length + 4
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should be zeroed initially" do
|
180
|
+
[@client, @client2, @server].each do |network|
|
181
|
+
network.packets_sent.should be 0
|
182
|
+
network.bytes_sent.should be 0
|
183
|
+
network.packets_received.should be 0
|
184
|
+
network.bytes_received.should be 0
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe "client to server" do
|
189
|
+
before :each do
|
190
|
+
@client.send_msg(@packet)
|
191
|
+
@server.update
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "client" do
|
195
|
+
it "should increment counters correctly when sending a message" do
|
196
|
+
@client.packets_sent.should eq 1
|
197
|
+
@client.bytes_sent.should eq @packet_length_with_header
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "server" do
|
202
|
+
it "should increment counters correctly when receiving a message" do
|
203
|
+
@server.packets_received.should eq 1
|
204
|
+
@server.bytes_received.should eq @packet_length_with_header
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "server to client" do
|
210
|
+
before :each do
|
211
|
+
@server.update
|
212
|
+
@server.send_msg(@server.sockets[0], @packet)
|
213
|
+
@client.update
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "server" do
|
217
|
+
it "should increment sent counters" do
|
218
|
+
@server.packets_sent.should eq 1
|
219
|
+
@server.bytes_sent.should eq @packet_length_with_header
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "client" do
|
224
|
+
it "should increment received counters" do
|
225
|
+
@client.packets_received.should eq 1
|
226
|
+
@client.bytes_received.should eq @packet_length_with_header
|
227
|
+
@client2.packets_received.should eq 0
|
228
|
+
@client2.bytes_received.should eq 0
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "server to clients" do
|
234
|
+
before :each do
|
235
|
+
@server.update
|
236
|
+
@server.broadcast_msg(@packet)
|
237
|
+
@client.update
|
238
|
+
@client2.update
|
239
|
+
end
|
240
|
+
|
241
|
+
describe "server" do
|
242
|
+
it "should increment sent counters" do
|
243
|
+
# Single message, broadcast to two clients.
|
244
|
+
@server.packets_sent.should eq 2
|
245
|
+
@server.bytes_sent.should eq @packet_length_with_header * 2
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe "clients" do
|
250
|
+
it "should increment received counters" do
|
251
|
+
[@client, @client2].each do |client|
|
252
|
+
client.packets_received.should eq 1
|
253
|
+
client.bytes_received.should eq @packet_length_with_header
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
126
259
|
end
|
127
260
|
end
|
128
261
|
end
|