chingu 0.9rc7 → 0.9rc8
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/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
|