rubygame 2.3.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CREDITS +5 -0
- data/NEWS +88 -0
- data/README +8 -4
- data/ROADMAP +19 -43
- data/Rakefile +94 -10
- data/doc/macosx_install.rdoc +2 -2
- data/doc/windows_install.rdoc +2 -2
- data/ext/rubygame/rubygame_event.c +116 -0
- data/ext/rubygame/rubygame_event2.c +661 -0
- data/ext/rubygame/rubygame_event2.h +29 -0
- data/ext/rubygame/rubygame_joystick.c +106 -17
- data/ext/rubygame/rubygame_main.c +3 -0
- data/ext/rubygame/rubygame_shared.c +2 -5
- data/ext/rubygame/rubygame_shared.h +1 -0
- data/ext/rubygame/rubygame_surface.c +11 -9
- data/lib/rubygame.rb +14 -3
- data/lib/rubygame/event_actions.rb +203 -0
- data/lib/rubygame/event_handler.rb +454 -0
- data/lib/rubygame/event_hook.rb +112 -0
- data/lib/rubygame/event_triggers.rb +692 -0
- data/lib/rubygame/events.rb +44 -0
- data/lib/rubygame/events/joystick_events.rb +342 -0
- data/lib/rubygame/events/keyboard_events.rb +132 -0
- data/lib/rubygame/events/misc_events.rb +144 -0
- data/lib/rubygame/events/mouse_events.rb +155 -0
- data/lib/rubygame/ftor.rb +2 -2
- data/lib/rubygame/queue.rb +50 -29
- data/samples/demo_draw.rb +175 -0
- data/samples/demo_rubygame.rb +421 -165
- metadata +18 -5
@@ -0,0 +1,29 @@
|
|
1
|
+
/*--
|
2
|
+
* This file is one part of:
|
3
|
+
* Rubygame -- Ruby bindings to SDL to facilitate game creation
|
4
|
+
*
|
5
|
+
* Copyright (C) 2008 John Croisant
|
6
|
+
*
|
7
|
+
* This library is free software; you can redistribute it and/or
|
8
|
+
* modify it under the terms of the GNU Lesser General Public
|
9
|
+
* License as published by the Free Software Foundation; either
|
10
|
+
* version 2.1 of the License, or (at your option) any later version.
|
11
|
+
*
|
12
|
+
* This library is distributed in the hope that it will be useful,
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
* Lesser General Public License for more details.
|
16
|
+
*
|
17
|
+
* You should have received a copy of the GNU Lesser General Public
|
18
|
+
* License along with this library; if not, write to the Free Software
|
19
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
+
*++
|
21
|
+
*/
|
22
|
+
|
23
|
+
|
24
|
+
#ifndef _RUBYGAME_EVENT2_H
|
25
|
+
#define _RUBYGAME_EVENT2_H
|
26
|
+
|
27
|
+
extern void Rubygame_Init_Event2();
|
28
|
+
|
29
|
+
#endif
|
@@ -77,6 +77,79 @@ static void RBGM_JoystickClose(SDL_Joystick *joy)
|
|
77
77
|
}
|
78
78
|
|
79
79
|
|
80
|
+
|
81
|
+
/*
|
82
|
+
* call-seq:
|
83
|
+
* Joystick.activate_all() -> [joystick1, joystick2, ...]
|
84
|
+
*
|
85
|
+
* Activate all joysticks on the system, equivalent to calling
|
86
|
+
* Joystick.new for every joystick available. This will allow
|
87
|
+
* joystick-related events to be sent to the EventQueue for
|
88
|
+
* all joysticks.
|
89
|
+
*
|
90
|
+
* Returns:: Array of zero or more Joysticks.
|
91
|
+
*
|
92
|
+
*/
|
93
|
+
VALUE rbgm_joystick_activateall(VALUE module)
|
94
|
+
{
|
95
|
+
/* Initialize if it isn't already. */
|
96
|
+
if( !SDL_WasInit(SDL_INIT_JOYSTICK) )
|
97
|
+
{
|
98
|
+
if( SDL_Init(SDL_INIT_JOYSTICK) != 0 )
|
99
|
+
{
|
100
|
+
rb_raise( eSDLError, "Could not initialize SDL joystick." );
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
int num_joysticks = SDL_NumJoysticks();
|
105
|
+
int i = 0;
|
106
|
+
|
107
|
+
/* Collect Joystick instances in an Array. */
|
108
|
+
VALUE joysticks = rb_ary_new();
|
109
|
+
|
110
|
+
for(; i < num_joysticks; ++i )
|
111
|
+
{
|
112
|
+
rb_ary_push( joysticks, rbgm_joystick_new(module, INT2NUM(i)) );
|
113
|
+
}
|
114
|
+
|
115
|
+
return joysticks;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
/*
|
120
|
+
* call-seq:
|
121
|
+
* Joystick.deactivate_all()
|
122
|
+
*
|
123
|
+
* Deactivate all joysticks on the system. This will stop all
|
124
|
+
* joystick-related events from being sent to the EventQueue.
|
125
|
+
*
|
126
|
+
*/
|
127
|
+
VALUE rbgm_joystick_deactivateall(VALUE module)
|
128
|
+
{
|
129
|
+
/* Return right away if it wasn't active. */
|
130
|
+
if( !SDL_WasInit(SDL_INIT_JOYSTICK) )
|
131
|
+
{
|
132
|
+
return Qnil;
|
133
|
+
}
|
134
|
+
|
135
|
+
int num_joysticks = SDL_NumJoysticks();
|
136
|
+
int i = 0;
|
137
|
+
SDL_Joystick *joy;
|
138
|
+
|
139
|
+
for(; i < num_joysticks; ++i )
|
140
|
+
{
|
141
|
+
joy = SDL_JoystickOpen(i);
|
142
|
+
if(joy != NULL)
|
143
|
+
{
|
144
|
+
SDL_JoystickClose( joy );
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
return Qnil;
|
149
|
+
}
|
150
|
+
|
151
|
+
|
152
|
+
|
80
153
|
/*
|
81
154
|
* call-seq:
|
82
155
|
* new( n ) -> Joystick
|
@@ -206,25 +279,38 @@ VALUE rbgm_joystick_numbuttons( VALUE self )
|
|
206
279
|
/* Document-class: Rubygame::Joystick
|
207
280
|
*
|
208
281
|
* The Joystick class interfaces with joysticks, gamepads, and other
|
209
|
-
* similar hardware devices
|
210
|
-
*
|
282
|
+
* similar hardware devices used to play games. Each joystick may
|
283
|
+
* have zero or more #axes, #balls, #hats, and/or #buttons.
|
211
284
|
*
|
212
285
|
* After a Joystick object is successfully created, events for that
|
213
|
-
* Joystick will begin appearing on the
|
214
|
-
*
|
215
|
-
*
|
216
|
-
*
|
217
|
-
*
|
218
|
-
*
|
219
|
-
*
|
220
|
-
*
|
221
|
-
* -
|
222
|
-
*
|
223
|
-
*
|
224
|
-
*
|
225
|
-
*
|
226
|
-
*
|
227
|
-
*
|
286
|
+
* Joystick will begin appearing on the EventQueue when a button is
|
287
|
+
* pressed or released, a control stick is moved, etc.
|
288
|
+
*
|
289
|
+
* You can use Joystick.activate_all to start receiving events for
|
290
|
+
* all joysticks (equivalent to creating them all individually with
|
291
|
+
* Joystick.new). You can use Joystick.deactivate_all to stop
|
292
|
+
* receiving events for all joysticks.
|
293
|
+
*
|
294
|
+
* As of Rubygame 2.4, these are the current, "new-style" Joystick
|
295
|
+
* event classes:
|
296
|
+
*
|
297
|
+
* * Events::JoystickAxisMoved
|
298
|
+
* * Events::JoystickButtonPressed
|
299
|
+
* * Events::JoystickButtonReleased
|
300
|
+
* * Events::JoystickBallMoved
|
301
|
+
* * Events::JoystickHatMoved
|
302
|
+
*
|
303
|
+
* These old Joystick-related events are deprecated and will be
|
304
|
+
* removed in Rubygame 3.0:
|
305
|
+
*
|
306
|
+
* * JoyAxisEvent
|
307
|
+
* * JoyBallEvent
|
308
|
+
* * JoyHatEvent
|
309
|
+
* * JoyDownEvent
|
310
|
+
* * JoyUpEvent
|
311
|
+
*
|
312
|
+
* For more information about "new-style" events, see
|
313
|
+
* EventQueue.enable_new_style_events.
|
228
314
|
*
|
229
315
|
*/
|
230
316
|
void Rubygame_Init_Joystick()
|
@@ -237,6 +323,9 @@ void Rubygame_Init_Joystick()
|
|
237
323
|
rb_define_singleton_method(cJoy,"num_joysticks",rbgm_joy_numjoysticks,0);
|
238
324
|
rb_define_singleton_method(cJoy,"get_name",rbgm_joy_getname,1);
|
239
325
|
|
326
|
+
rb_define_singleton_method(cJoy,"activate_all",rbgm_joystick_activateall,0);
|
327
|
+
rb_define_singleton_method(cJoy,"deactivate_all",rbgm_joystick_deactivateall,0);
|
328
|
+
|
240
329
|
rb_define_singleton_method(cJoy,"new",rbgm_joystick_new,1);
|
241
330
|
rb_define_method(cJoy,"index",rbgm_joystick_index,0);
|
242
331
|
rb_define_method(cJoy,"name",rbgm_joystick_name,0);
|
@@ -22,6 +22,7 @@
|
|
22
22
|
#include "rubygame_shared.h"
|
23
23
|
#include "rubygame_main.h"
|
24
24
|
#include "rubygame_event.h"
|
25
|
+
#include "rubygame_event2.h"
|
25
26
|
#include "rubygame_gl.h"
|
26
27
|
#include "rubygame_joystick.h"
|
27
28
|
#include "rubygame_screen.h"
|
@@ -76,6 +77,7 @@ VALUE rbgm_init(VALUE module)
|
|
76
77
|
{
|
77
78
|
if(SDL_Init(SDL_INIT_EVERYTHING)==0)
|
78
79
|
{
|
80
|
+
SDL_EnableUNICODE(1);
|
79
81
|
return Qnil;
|
80
82
|
}
|
81
83
|
else
|
@@ -129,6 +131,7 @@ void Init_rubygame_core()
|
|
129
131
|
Rubygame_Init_Surface();
|
130
132
|
Rubygame_Init_Screen();
|
131
133
|
Rubygame_Init_Event();
|
134
|
+
Rubygame_Init_Event2();
|
132
135
|
Rubygame_Init_Joystick();
|
133
136
|
Rubygame_Init_GL();
|
134
137
|
|
@@ -263,10 +263,7 @@ void Init_rubygame_shared()
|
|
263
263
|
|
264
264
|
|
265
265
|
/* Rubygame::NamedResource mixin. See named_resource.rb. */
|
266
|
-
|
267
|
-
|
268
|
-
rb_require("rubygame/named_resource");
|
269
|
-
mNamedResource = rb_const_get(mRubygame, rb_intern("NamedResource"));
|
270
|
-
}
|
266
|
+
rb_require("rubygame/named_resource");
|
267
|
+
mNamedResource = rb_const_get(mRubygame, rb_intern("NamedResource"));
|
271
268
|
|
272
269
|
}
|
@@ -39,6 +39,7 @@ extern VALUE sanitized_symbol(char *);
|
|
39
39
|
extern Uint32 collapse_flags(VALUE);
|
40
40
|
extern VALUE convert_to_array(VALUE);
|
41
41
|
|
42
|
+
extern VALUE convert_color(VALUE);
|
42
43
|
extern SDL_Color make_sdl_color(VALUE);
|
43
44
|
extern void extract_rgb_u8_as_u8(VALUE, Uint8*, Uint8*, Uint8*);
|
44
45
|
extern void extract_rgba_u8_as_u8(VALUE, Uint8*, Uint8*, Uint8*, Uint8*);
|
@@ -333,10 +333,18 @@ VALUE rbgm_surface_get_colorkey( VALUE self )
|
|
333
333
|
|
334
334
|
Data_Get_Struct(self, SDL_Surface, surf);
|
335
335
|
colorkey = surf->format->colorkey;
|
336
|
-
|
336
|
+
|
337
|
+
if( surf->flags & SDL_SRCCOLORKEY )
|
338
|
+
{
|
339
|
+
SDL_GetRGB(colorkey, surf->format, &r, &g, &b);
|
340
|
+
return rb_ary_new3(3,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b));
|
341
|
+
}
|
342
|
+
else
|
343
|
+
{
|
344
|
+
/* No colorkey set. */
|
337
345
|
return Qnil;
|
338
|
-
|
339
|
-
|
346
|
+
}
|
347
|
+
|
340
348
|
}
|
341
349
|
|
342
350
|
/*
|
@@ -618,12 +626,6 @@ VALUE rbgm_surface_getat( int argc, VALUE *argv, VALUE self )
|
|
618
626
|
locked -= 1;
|
619
627
|
}
|
620
628
|
|
621
|
-
if((int *)color == NULL)
|
622
|
-
{
|
623
|
-
VALUE zero = INT2NUM(0);
|
624
|
-
return rb_ary_new3(4,zero,zero,zero,zero);
|
625
|
-
}
|
626
|
-
|
627
629
|
SDL_GetRGBA(color, surf->format, &r, &g, &b, &a);
|
628
630
|
return rb_ary_new3(4,UINT2NUM(r),UINT2NUM(g),UINT2NUM(b),UINT2NUM(a));
|
629
631
|
}
|
data/lib/rubygame.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#--
|
2
2
|
# Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
3
|
-
# Copyright (C) 2004-2007 John Croisant
|
3
|
+
# Copyright (C) 2004-2007, 2008 John Croisant
|
4
4
|
#
|
5
5
|
# This library is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU Lesser General Public
|
@@ -17,8 +17,15 @@
|
|
17
17
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
18
|
#++
|
19
19
|
|
20
|
-
# This
|
21
|
-
#
|
20
|
+
# This file is loaded when you "require 'rubygame'".
|
21
|
+
# It loads up the compiled C extensions and the rest of
|
22
|
+
# the Rubygame library modules.
|
23
|
+
|
24
|
+
|
25
|
+
# Prefer local library over global installed version.
|
26
|
+
$:.unshift( File.join( File.dirname(__FILE__), "..", "lib" ) )
|
27
|
+
$:.unshift( File.join( File.dirname(__FILE__), "..", "ext", "rubygame" ) )
|
28
|
+
|
22
29
|
|
23
30
|
require "rbconfig"
|
24
31
|
|
@@ -34,8 +41,12 @@ end
|
|
34
41
|
|
35
42
|
require "rubygame/color"
|
36
43
|
require "rubygame/constants"
|
44
|
+
|
37
45
|
require "rubygame/event"
|
46
|
+
require "rubygame/events"
|
38
47
|
require "rubygame/queue"
|
48
|
+
require "rubygame/event_handler"
|
49
|
+
|
39
50
|
require "rubygame/rect"
|
40
51
|
require "rubygame/sprite"
|
41
52
|
require "rubygame/clock"
|
@@ -0,0 +1,203 @@
|
|
1
|
+
#--
|
2
|
+
# Rubygame -- Ruby code and bindings to SDL to facilitate game creation
|
3
|
+
# Copyright (C) 2004-2008 John Croisant
|
4
|
+
#
|
5
|
+
# This library is free software; you can redistribute it and/or
|
6
|
+
# modify it under the terms of the GNU Lesser General Public
|
7
|
+
# License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License, or (at your option) any later version.
|
9
|
+
#
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
+
# Lesser General Public License for more details.
|
14
|
+
#
|
15
|
+
# You should have received a copy of the GNU Lesser General Public
|
16
|
+
# License along with this library; if not, write to the Free Software
|
17
|
+
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
18
|
+
#++
|
19
|
+
|
20
|
+
|
21
|
+
# This module contains all the event action classes that
|
22
|
+
# come with Rubygame.
|
23
|
+
#
|
24
|
+
# An event action class is simply a class which can be
|
25
|
+
# used as an action an EventHook. The action is used to
|
26
|
+
# cause some effect when the EventHook matches an event.
|
27
|
+
#
|
28
|
+
# The only requirement for an event action is this:
|
29
|
+
#
|
30
|
+
# * It must have a #perform method which takes exactly two
|
31
|
+
# arguments (the hook owner and an event). Return values
|
32
|
+
# are ignored.
|
33
|
+
#
|
34
|
+
# You can make your own custom event action classes and
|
35
|
+
# use them in an EventHook if they meet that requirement.
|
36
|
+
#
|
37
|
+
# Here is an overview of the event action classes that
|
38
|
+
# come with Rubygame as of version 2.4:
|
39
|
+
#
|
40
|
+
# BlockAction:: Calls a custom code block, passing it the
|
41
|
+
# hook owner and the event.
|
42
|
+
#
|
43
|
+
# MethodAction:: Calls one of the owner's methods, passing
|
44
|
+
# it the event.
|
45
|
+
#
|
46
|
+
# MultiAction:: Holds multiple other actions and performs
|
47
|
+
# each of them, in order.
|
48
|
+
#
|
49
|
+
module Rubygame::EventActions
|
50
|
+
|
51
|
+
|
52
|
+
# BlockAction is an event action used with EventHook. BlockAction
|
53
|
+
# takes a code block at initialization. When the action is performed,
|
54
|
+
# it executes the block, passing in the EventHook#owner and the event
|
55
|
+
# that is being handled as the two parameters to the block.
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
#
|
59
|
+
# hit_by_missile = KindOfTrigger.new( MissileCollisionEvent )
|
60
|
+
#
|
61
|
+
# take_damage = BlockAction.new { |owner, event|
|
62
|
+
# owner.health -= event.damage_amount
|
63
|
+
# }
|
64
|
+
#
|
65
|
+
# hook = EventHook.new( :owner => player_ship,
|
66
|
+
# :trigger => hit_by_missile,
|
67
|
+
# :action => take_damage )
|
68
|
+
#
|
69
|
+
#
|
70
|
+
# NOTE: It is also possible to pass a Proc or detached Method
|
71
|
+
# as the block, using the standard Ruby syntax for that:
|
72
|
+
#
|
73
|
+
# # Using a pre-built Proc.
|
74
|
+
#
|
75
|
+
# my_proc = Proc.new { |owner, event| do_something() }
|
76
|
+
#
|
77
|
+
# BlockAction.new( &my_proc )
|
78
|
+
#
|
79
|
+
#
|
80
|
+
# # Using a detached method.
|
81
|
+
#
|
82
|
+
# def a_method( owner, event )
|
83
|
+
# do_something
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# detached_method = method(:a_method)
|
87
|
+
#
|
88
|
+
# BlockAction.new( &detached_method )
|
89
|
+
#
|
90
|
+
#
|
91
|
+
class BlockAction
|
92
|
+
|
93
|
+
# Create a new BlockAction using the given code block.
|
94
|
+
#
|
95
|
+
# &block:: the code block to execute. Should take two parameters,
|
96
|
+
# owner and event. (Proc, required)
|
97
|
+
#
|
98
|
+
# May raise:: ArgumentError, if no block is provided.
|
99
|
+
#
|
100
|
+
def initialize( &block )
|
101
|
+
raise ArgumentError, "BlockAction needs a block" unless block_given?
|
102
|
+
@block = block
|
103
|
+
end
|
104
|
+
|
105
|
+
# Execute the code block, passing in owner and event as the two
|
106
|
+
# parameters to the block. This is automatically called by EventHook
|
107
|
+
# when an event matches the trigger. You should usually not call it
|
108
|
+
# in your own code.
|
109
|
+
#
|
110
|
+
# owner:: the owner of the EventHook, or nil if there is none.
|
111
|
+
# (Object, required)
|
112
|
+
# event:: the event that matched the trigger. (Object, required)
|
113
|
+
#
|
114
|
+
def perform( owner, event )
|
115
|
+
@block.call( owner, event )
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# MethodAction is an event action used with EventHook.
|
121
|
+
# MethodAction takes a symbol giving the name of a method. When
|
122
|
+
# it is performed, it calls that method on the owner, passing
|
123
|
+
# it the event that triggered the hook.
|
124
|
+
#
|
125
|
+
# Example:
|
126
|
+
#
|
127
|
+
# class Player
|
128
|
+
# def aim_at( event )
|
129
|
+
# self.crosshair_pos = event.pos
|
130
|
+
# end
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# player1 = Player.new
|
134
|
+
#
|
135
|
+
# EventHook.new( :owner => player1,
|
136
|
+
# :trigger => MouseMoveTrigger.new(),
|
137
|
+
# :action => MethodAction.new( :aim_at ) )
|
138
|
+
#
|
139
|
+
class MethodAction
|
140
|
+
|
141
|
+
# Create a new MethodAction using the given method name.
|
142
|
+
#
|
143
|
+
# method_name:: the method to call when performing.
|
144
|
+
# (Symbol, required)
|
145
|
+
#
|
146
|
+
def initialize( method_name )
|
147
|
+
@method_name = method_name
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# Call the method of the owner represented by @method_name,
|
152
|
+
# passing in the event as the only argument.
|
153
|
+
#
|
154
|
+
# If that causes ArgumentError (e.g. because the method doesn't
|
155
|
+
# take an argument), calls again without any arguments.
|
156
|
+
#
|
157
|
+
# If that also fails, this method re-raises the original error.
|
158
|
+
#
|
159
|
+
def perform( owner, event )
|
160
|
+
owner.method(@method_name).call( event )
|
161
|
+
rescue ArgumentError => s
|
162
|
+
begin
|
163
|
+
# Oops! Try again, without any argument.
|
164
|
+
owner.method(@method_name).call()
|
165
|
+
rescue ArgumentError
|
166
|
+
# That didn't work either. Raise the original error.
|
167
|
+
raise s
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
|
174
|
+
# MultiAction is an event action used with EventHook.
|
175
|
+
# It takes zero or more actions (e.g. BlockAction or MethodAction
|
176
|
+
# instances) at initialization.
|
177
|
+
#
|
178
|
+
# When MultiAction is performed, it performs all the given
|
179
|
+
# actions, in the order they were given, passing in the owner
|
180
|
+
# and event.
|
181
|
+
#
|
182
|
+
# As the name suggests, you can use MultiAction to cause
|
183
|
+
# multiple actions to occur when an EventHook is triggered.
|
184
|
+
#
|
185
|
+
class MultiAction
|
186
|
+
|
187
|
+
# Create a new MultiAction instance with the given sub-actions.
|
188
|
+
#
|
189
|
+
# *actions:: the actions to perform. (Action instances)
|
190
|
+
#
|
191
|
+
def initialize( *actions )
|
192
|
+
@actions = actions
|
193
|
+
end
|
194
|
+
|
195
|
+
# Performs all the sub-actions, in the order they were given,
|
196
|
+
# passing in the owner and event to each one.
|
197
|
+
#
|
198
|
+
def perform( owner, event )
|
199
|
+
@actions.each { |action| action.perform( owner, event ) }
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|