[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/button_character_instanc...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/button_character_instanc... |
Date: |
Tue, 20 Feb 2007 10:00:48 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 07/02/20 10:00:48
Modified files:
. : ChangeLog
server : button_character_instance.cpp character.cpp
character.h movie_root.cpp movie_root.h
sprite_instance.cpp sprite_instance.h
testsuite/misc-ming.all: attachMovieTest.c
Log message:
* testsuite/misc-ming.all/attachMovieTest.c:
print instance name on mouse down/up events.
* server/button_character_instance.cpp (on_button_event):
survive on unhandled event handler.
* server/character.{cpp,h}: add getter_setter for
onMouseDown, onMouseUp and onMouseMove; add has_mouse_event()
method.
* server/movie_root.{cpp,h}:
Add mouse listeners. Change key listeners to use std::set
(more appropriate) and to use intrusive_ptr (safer);
Notify mouse listeners on move and click events, don't
duplicate notification on *active* entity as these events
(mouse up,down,move) are not restricted to entity under the
mouse.
* server/sprite_instance.{cpp,h}: (on_event): if a builtin
handler is invoked, don't go look for functions; register
as a mouse listener if have mouse event handlers.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2402&r2=1.2403
http://cvs.savannah.gnu.org/viewcvs/gnash/server/button_character_instance.cpp?cvsroot=gnash&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.cpp?cvsroot=gnash&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.42&r2=1.43
http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.174&r2=1.175
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.70&r2=1.71
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/attachMovieTest.c?cvsroot=gnash&r1=1.5&r2=1.6
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2402
retrieving revision 1.2403
diff -u -b -r1.2402 -r1.2403
--- ChangeLog 20 Feb 2007 09:31:17 -0000 1.2402
+++ ChangeLog 20 Feb 2007 10:00:48 -0000 1.2403
@@ -1,3 +1,23 @@
+2007-02-20 Sandro Santilli <address@hidden>
+
+ * testsuite/misc-ming.all/attachMovieTest.c:
+ print instance name on mouse down/up events.
+ * server/button_character_instance.cpp (on_button_event):
+ survive on unhandled event handler.
+ * server/character.{cpp,h}: add getter_setter for
+ onMouseDown, onMouseUp and onMouseMove; add has_mouse_event()
+ method.
+ * server/movie_root.{cpp,h}:
+ Add mouse listeners. Change key listeners to use std::set
+ (more appropriate) and to use intrusive_ptr (safer);
+ Notify mouse listeners on move and click events, don't
+ duplicate notification on *active* entity as these events
+ (mouse up,down,move) are not restricted to entity under the
+ mouse.
+ * server/sprite_instance.{cpp,h}: (on_event): if a builtin
+ handler is invoked, don't go look for functions; register
+ as a mouse listener if have mouse event handlers.
+
2007-02-20 Udo Giacomozzi <address@hidden>
* extensions/fileio/fileio.cpp: Fixed some compiler warnings
Index: server/button_character_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/button_character_instance.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- server/button_character_instance.cpp 12 Feb 2007 20:56:51 -0000
1.28
+++ server/button_character_instance.cpp 20 Feb 2007 10:00:48 -0000
1.29
@@ -464,9 +464,9 @@
break;
case event_id::RELEASE:
- case event_id::MOUSE_UP:
case event_id::ROLL_OVER:
case event_id::DRAG_OUT:
+ case event_id::MOUSE_UP:
new_state = OVER;
break;
@@ -477,7 +477,8 @@
break;
default:
- assert(0); // missed a case?
+ //assert(0); // missed a case?
+ log_error("Unhandled button event %s",
event.get_function_name().c_str());
break;
};
Index: server/character.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/character.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- server/character.cpp 13 Feb 2007 14:21:01 -0000 1.19
+++ server/character.cpp 20 Feb 2007 10:00:48 -0000 1.20
@@ -18,7 +18,7 @@
//
//
-/* $Id: character.cpp,v 1.19 2007/02/13 14:21:01 udog Exp $ */
+/* $Id: character.cpp,v 1.20 2007/02/20 10:00:48 strk Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -300,6 +300,51 @@
}
void
+character::onmouseup_getset(const fn_call& fn)
+{
+ character* ptr = ensure_character(fn.this_ptr);
+
+ if ( fn.nargs == 0 ) // getter
+ {
+ ptr->get_event_handler(event_id::MOUSE_UP, fn.result);
+ }
+ else // setter
+ {
+ ptr->set_event_handler(event_id::MOUSE_UP, fn.arg(0));
+ }
+}
+
+void
+character::onmousedown_getset(const fn_call& fn)
+{
+ character* ptr = ensure_character(fn.this_ptr);
+
+ if ( fn.nargs == 0 ) // getter
+ {
+ ptr->get_event_handler(event_id::MOUSE_DOWN, fn.result);
+ }
+ else // setter
+ {
+ ptr->set_event_handler(event_id::MOUSE_DOWN, fn.arg(0));
+ }
+}
+
+void
+character::onmousemove_getset(const fn_call& fn)
+{
+ character* ptr = ensure_character(fn.this_ptr);
+
+ if ( fn.nargs == 0 ) // getter
+ {
+ ptr->get_event_handler(event_id::MOUSE_MOVE, fn.result);
+ }
+ else // setter
+ {
+ ptr->set_event_handler(event_id::MOUSE_MOVE, fn.arg(0));
+ }
+}
+
+void
character::onload_getset(const fn_call& fn)
{
character* ptr = ensure_character(fn.this_ptr);
@@ -646,11 +691,41 @@
}
}
+void
+character::set_event_handler(const event_id& id, const as_value& method)
+{
+ _event_handlers[id] = method;
+
+ //log_msg("Setting handler for event %s",
id.get_function_name().c_str());
+
+ // Set the character as a listener iff the
+ // kind of event is a KEY or MOUSE one
+ if ( method.is_function() )
+ {
+ switch (id.m_id)
+ {
+ case event_id::KEY_PRESS:
+ has_keypress_event();
+ break;
+ case event_id::MOUSE_UP:
+ case event_id::MOUSE_DOWN:
+ case event_id::MOUSE_MOVE:
+ //log_msg("Registering character as having mouse events");
+ has_mouse_event();
+ break;
+ default:
+ break;
+ }
+ }
+ // todo: drop the character as a listener
+ // if it gets no valid handlers for
+ // mouse or keypress events.
+}
} // namespace gnash
-// Local Variables:
-// mode: C++
+// local variables:
+// mode: c++
// indent-tabs-mode: t
-// End:
+// end:
Index: server/character.h
===================================================================
RCS file: /sources/gnash/gnash/server/character.h,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- server/character.h 13 Feb 2007 14:21:01 -0000 1.49
+++ server/character.h 20 Feb 2007 10:00:48 -0000 1.50
@@ -18,7 +18,7 @@
//
//
-/* $Id: character.h,v 1.49 2007/02/13 14:21:01 udog Exp $ */
+/* $Id: character.h,v 1.50 2007/02/20 10:00:48 strk Exp $ */
#ifndef GNASH_CHARACTER_H
#define GNASH_CHARACTER_H
@@ -150,6 +150,12 @@
static void onreleaseoutside_getset(const fn_call& fn);
+ static void onmouseup_getset(const fn_call& fn);
+
+ static void onmousedown_getset(const fn_call& fn);
+
+ static void onmousemove_getset(const fn_call& fn);
+
static void x_getset(const fn_call& fn);
static void y_getset(const fn_call& fn);
@@ -297,17 +303,35 @@
return true;
}
- void set_event_handler(const event_id& id, const as_value& method)
- {
- _event_handlers[id] = method;
- if (id.m_id == event_id::KEY_PRESS)
- {
- has_keypress_event();
- }
- }
+ /// Set a function handler for the given event
+ //
+ /// Mark the character as having mouse or keypress event
+ /// handlers if this is the case.
+ ///
+ void set_event_handler(const event_id& id, const as_value& method);
+ /// \brief
+ /// Call this when a character get equipped
+ /// with a keypress event handler
+ //
+ /// TODO: provide a function to *unset*
+ /// the flag. This should happen
+ /// when keypress event handler is
+ /// set to undefined or equivalent..
+ ///
virtual void has_keypress_event() {}
+ /// \brief
+ /// Call this when a character get equipped
+ /// with a mouse event handler (move,down,up)
+ //
+ /// TODO: provide a function to *unset*
+ /// the flag. This should happen
+ /// when all mouse event handlers are
+ /// set to undefined or equivalent..
+ ///
+ virtual void has_mouse_event() {}
+
// Movie interfaces. By default do nothing. sprite_instance and some
others override these.
virtual void display() {}
Index: server/movie_root.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.cpp,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -b -r1.42 -r1.43
--- server/movie_root.cpp 15 Feb 2007 11:14:52 -0000 1.42
+++ server/movie_root.cpp 20 Feb 2007 10:00:48 -0000 1.43
@@ -128,6 +128,7 @@
m_mouse_x = x;
m_mouse_y = y;
+ notify_mouse_listeners(event_id(event_id::MOUSE_MOVE));
return fire_mouse_event();
}
@@ -137,11 +138,18 @@
{
assert(testInvariant());
- if (mouse_pressed) {
+ //log_msg("Mouse click notification");
+ if (mouse_pressed)
+ {
m_mouse_buttons |= button_mask;
- } else {
+ notify_mouse_listeners(event_id(event_id::MOUSE_DOWN));
+ }
+ else
+ {
m_mouse_buttons &= ~button_mask;
+ notify_mouse_listeners(event_id(event_id::MOUSE_UP));
}
+
return fire_mouse_event();
}
@@ -225,7 +233,6 @@
{
// onRelease
active_entity->on_button_event(event_id::RELEASE);
-
active_entity->on_button_event(event_id::MOUSE_UP);
// TODO: have on_button_event return
// wheter the action must trigger
// a redraw.
@@ -314,7 +321,6 @@
if (active_entity != NULL)
{
active_entity->on_button_event(event_id::PRESS);
-
active_entity->on_button_event(event_id::MOUSE_DOWN);
// TODO: have on_button_event return
// wheter the action must trigger
// a redraw.
@@ -547,19 +553,16 @@
void movie_root::notify_keypress_listeners(key::code k)
{
- for (std::vector< as_object* >::iterator iter =
m_keypress_listeners.begin();
+ for (ListenerSet::iterator iter = m_keypress_listeners.begin();
iter != m_keypress_listeners.end(); ++iter)
{
- if (*iter == NULL)
+ // sprite, button & input_edit_text characters
+ // TODO: invoke functions on non-characters !
+ character* ch = dynamic_cast<character*>(iter->get());
+ if ( ch )
{
- continue;
+ ch->on_event(event_id(event_id::KEY_PRESS, k));
}
-
- boost::intrusive_ptr<as_object> listener = *iter; // Hold an
owning reference.
-
- // sprite, button & input_edit_text characters
- character* ch = (character*) listener.get();
- ch->on_event(event_id(event_id::KEY_PRESS, (key::code) k));
}
assert(testInvariant());
@@ -567,33 +570,45 @@
void movie_root::add_keypress_listener(as_object* listener)
{
- std::vector< as_object* >::const_iterator end =
m_keypress_listeners.end();
- for (std::vector< as_object* >::iterator iter =
m_keypress_listeners.begin();
- iter != end; ++iter)
- {
- if (*iter == NULL)
- {
- // Already in the list.
- return;
- }
- }
- m_keypress_listeners.push_back(listener);
-
+ m_keypress_listeners.insert(listener);
assert(testInvariant());
}
void movie_root::remove_keypress_listener(as_object* listener)
{
- for (std::vector< as_object* >::iterator iter =
m_keypress_listeners.begin();
- iter != m_keypress_listeners.end(); )
+ m_keypress_listeners.erase(listener);
+ assert(testInvariant());
+}
+
+void movie_root::add_mouse_listener(as_object* listener)
+{
+ m_mouse_listeners.insert(listener);
+ assert(testInvariant());
+}
+
+void movie_root::remove_mouse_listener(as_object* listener)
+{
+ m_mouse_listeners.erase(listener);
+ assert(testInvariant());
+}
+
+void movie_root::notify_mouse_listeners(const event_id& event)
+{
+ //log_msg("Notifying " SIZET_FMT " listeners about %s",
+ // m_mouse_listeners.size(),
event.get_function_name().c_str());
+
+ for (ListenerSet::iterator iter = m_mouse_listeners.begin();
+ iter != m_mouse_listeners.end(); ++iter)
{
- if (*iter == listener)
+ // sprite, button & input_edit_text characters
+ // TODO: invoke functions on non-characters !
+ character* ch = dynamic_cast<character*>(iter->get());
+ if ( ch )
{
- iter = m_keypress_listeners.erase(iter);
- continue;
+ ch->on_event(event);
}
- iter++;
}
+
assert(testInvariant());
}
Index: server/movie_root.h
===================================================================
RCS file: /sources/gnash/gnash/server/movie_root.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- server/movie_root.h 9 Feb 2007 13:38:50 -0000 1.36
+++ server/movie_root.h 20 Feb 2007 10:00:48 -0000 1.37
@@ -14,7 +14,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-/* $Id: movie_root.h,v 1.36 2007/02/09 13:38:50 strk Exp $ */
+/* $Id: movie_root.h,v 1.37 2007/02/20 10:00:48 strk Exp $ */
/// \page events_handling Handling of user events
///
@@ -78,6 +78,9 @@
#include "sprite_instance.h" // for inlines
#include "timers.h" // for composition
+#include <vector>
+#include <set>
+
// Forward declarations
// none needed
@@ -342,6 +345,10 @@
void add_keypress_listener(as_object* listener);
void remove_keypress_listener(as_object* listener);
+ DSOEXPORT void notify_mouse_listeners(const event_id& event);
+ void add_mouse_listener(as_object* listener);
+ void remove_mouse_listener(as_object* listener);
+
/// Get the character having focus
//
/// @return the character having focus or NULL of none.
@@ -394,7 +401,15 @@
typedef std::vector<Timer> TimerList;
TimerList _intervalTimers;
- std::vector< as_object* > m_keypress_listeners;
+ /// A set of as_objects kept by intrusive_ptr
+ typedef std::set< boost::intrusive_ptr<as_object> > ListenerSet;
+
+ /// Objects listening for keypress events
+ ListenerSet m_keypress_listeners;
+
+ /// Objects listening for mouse events (down,up,move)
+ ListenerSet m_mouse_listeners;
+
character* m_active_input_text;
float m_time_remainder;
Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.174
retrieving revision 1.175
diff -u -b -r1.174 -r1.175
--- server/sprite_instance.cpp 19 Feb 2007 21:40:32 -0000 1.174
+++ server/sprite_instance.cpp 20 Feb 2007 10:00:48 -0000 1.175
@@ -1457,6 +1457,15 @@
gettersetter = new builtin_function(&character::onload_getset, NULL);
o.init_property("onLoad", *gettersetter, *gettersetter);
+ gettersetter = new builtin_function(&character::onmouseup_getset, NULL);
+ o.init_property("onMouseUp", *gettersetter, *gettersetter);
+
+ gettersetter = new builtin_function(&character::onmousedown_getset,
NULL);
+ o.init_property("onMouseDown", *gettersetter, *gettersetter);
+
+ gettersetter = new builtin_function(&character::onmousemove_getset,
NULL);
+ o.init_property("onMouseMove", *gettersetter, *gettersetter);
+
}
static as_object*
@@ -1642,6 +1651,7 @@
m_init_actions_executed(),
m_as_environment(),
m_has_keypress_event(false),
+ m_has_mouse_event(false),
_text_variables(),
m_sound_stream_id(-1),
_target(), // don't initialize now, as parent can be assigned later
@@ -1672,6 +1682,11 @@
_vm.getRoot().remove_keypress_listener(this);
}
+ if (m_has_mouse_event)
+ {
+ _vm.getRoot().remove_mouse_listener(this);
+ }
+
m_display_list.clear();
}
@@ -2150,7 +2165,8 @@
}
}
-bool sprite_instance::on_event(const event_id& id)
+bool
+sprite_instance::on_event(const event_id& id)
{
testInvariant();
@@ -2171,6 +2187,14 @@
}
}
+ // If we called a built-in event handler
+ // we stop here. If we don't do this,
+ // MOUSE_UP, MOUSE_DOWN and MOUSE_MOVE will
+ // be called twice !
+ // Don't know if this is generally valid for every
+ // kind of event, but we do have testcases for this one...
+ if ( called ) return true;
+
// Check for member function.
{
// In ActionScript 2.0, event method names are CASE SENSITIVE.
@@ -2550,11 +2574,6 @@
m_as_environment.set_variable(path, val);
}
-void sprite_instance::has_keypress_event()
-{
- m_has_keypress_event = true;
-}
-
void sprite_instance::advance_sprite(float delta_time)
{
//GNASH_REPORT_FUNCTION;
@@ -2694,11 +2713,19 @@
#endif
on_event(event_id::LOAD); // clip onload
- //
if (m_has_keypress_event)
{
_vm.getRoot().add_keypress_listener(this);
}
+ // Mouse events listening is done in has_mouse_event directly.
+ // This shows to work better for attachMovieTest.swf,
+ // but might actually be a completely unrelated issue.
+ // In particular, copying event handlers in attachMovie should
+ // be more closely inspected (and need more ad-hoc testcases)
+ //if (m_has_mouse_event)
+ //{
+ //_vm.getRoot().add_mouse_listener(this);
+ //}
}
advance_sprite(delta_time);
@@ -3324,8 +3351,13 @@
event_id(event_id::ROLL_OUT),
event_id(event_id::DRAG_OVER),
event_id(event_id::DRAG_OUT),
- event_id(event_id::MOUSE_DOWN),
- event_id(event_id::MOUSE_UP)
+ // MOUSE_{DOWN,UP,MOVE} are handled
+ // differently, in that they are called
+ // reguardles of mouse position
+ // See has_mouse_event
+ //event_id(event_id::MOUSE_DOWN),
+ //event_id(event_id::MOUSE_UP)
+ //event_id(event_id::MOUSE_MOVE)
};
int swfversion = _vm.getSWFVersion();
@@ -3778,4 +3810,11 @@
return true;
}
+void
+sprite_instance::has_mouse_event()
+{
+ m_has_mouse_event = true;
+ _vm.getRoot().add_mouse_listener(this);
+}
+
} // namespace gnash
Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -b -r1.70 -r1.71
--- server/sprite_instance.h 19 Feb 2007 21:40:32 -0000 1.70
+++ server/sprite_instance.h 20 Feb 2007 10:00:48 -0000 1.71
@@ -17,7 +17,7 @@
//
//
-/* $Id: sprite_instance.h,v 1.70 2007/02/19 21:40:32 strk Exp $ */
+/* $Id: sprite_instance.h,v 1.71 2007/02/20 10:00:48 strk Exp $ */
// Stateful live Sprite instance
@@ -110,7 +110,11 @@
TAG_DLIST = 1<<1
};
- virtual void has_keypress_event();
+ virtual void has_keypress_event() {
+ m_has_keypress_event = true;
+ }
+
+ virtual void has_mouse_event();
/// \brief
/// Return this sprite's relative root as
@@ -213,6 +217,9 @@
/// Return true if we have any mouse event handlers.
+ //
+ /// NOTE: this function currently does not consider
+ /// general mouse event handlers MOUSE_MOVE, MOUSE
virtual bool can_handle_mouse_event() const;
/// \brief
@@ -710,6 +717,8 @@
bool m_has_keypress_event;
+ bool m_has_mouse_event;
+
/// A container for textfields, indexed by their variable name
typedef std::map< std::string,
boost::intrusive_ptr<edit_text_character> > TextfieldMap;
Index: testsuite/misc-ming.all/attachMovieTest.c
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/attachMovieTest.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- testsuite/misc-ming.all/attachMovieTest.c 19 Feb 2007 23:16:59 -0000
1.5
+++ testsuite/misc-ming.all/attachMovieTest.c 20 Feb 2007 10:00:48 -0000
1.6
@@ -47,8 +47,8 @@
SWFMovieClip_add(mc, (SWFBlock)sh);
/* This is here just to turn the clip into an active one */
add_clip_actions(mc, "onRollOver = function() {};");
- add_clip_actions(mc, "onMouseDown = function() { _root.mouseDown++;
_root.note('mouseDown '+_root.mouseDown); };");
- add_clip_actions(mc, "onMouseUp = function() { _root.mouseUp++;
_root.note('mouseUp '+_root.mouseUp); };");
+ add_clip_actions(mc, "onMouseDown = function() { _root.mouseDown++;
_root.note(_name+' mouseDown '+_root.mouseDown); };");
+ add_clip_actions(mc, "onMouseUp = function() { _root.mouseUp++;
_root.note(_name+' mouseUp '+_root.mouseUp); };");
SWFMovieClip_nextFrame(mc);
SWFMovie_addExport(mo, (SWFBlock)mc, "redsquare");