CVSROOT: /sources/gnash Module name: gnash Changes by: Sandro Santilli <strk> 07/11/21 17:11:53
Modified files: . : ChangeLog server : movie_root.cpp movie_root.h sprite_instance.cpp Log message: Generalize key and mouse character listeners management. CVSWeb URLs: http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4907&r2=1.4908 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.cpp?cvsroot=gnash&r1=1.125&r2=1.126 http://cvs.savannah.gnu.org/viewcvs/gnash/server/movie_root.h?cvsroot=gnash&r1=1.89&r2=1.90 http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.389&r2=1.390 Patches: Index: ChangeLog =================================================================== RCS file: /sources/gnash/gnash/ChangeLog,v retrieving revision 1.4907 retrieving revision 1.4908 diff -u -b -r1.4907 -r1.4908 --- ChangeLog 21 Nov 2007 09:21:48 -0000 1.4907 +++ ChangeLog 21 Nov 2007 17:11:52 -0000 1.4908 @@ -1,3 +1,10 @@ +2007-11-21 Sandro Santilli <[EMAIL PROTECTED]> + + * server/movie_root.{cpp,h}: generalize key and mouse + listeners management. + * server/sprite_instance.cpp (add_display_object): don't + attempt to remove a NULL pointer from the listeners set. + 2007-11-21 Chad Musick <[EMAIL PROTECTED]> * server/as_environment.h,.cpp: Initialize _original_target, as this Index: server/movie_root.cpp =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.cpp,v retrieving revision 1.125 retrieving revision 1.126 diff -u -b -r1.125 -r1.126 --- server/movie_root.cpp 16 Nov 2007 17:35:34 -0000 1.125 +++ server/movie_root.cpp 21 Nov 2007 17:11:52 -0000 1.126 @@ -783,7 +783,7 @@ // NOTE: can throw ActionLimitException advanceLiveChars(delta_time); - cleanup_key_listeners(); + cleanupUnloadedListeners(); // Process queued actions // NOTE: can throw ActionLimitException @@ -878,35 +878,30 @@ return getLevel(0)->call_method_args(method_name, method_arg_fmt, args); } -void movie_root::cleanup_key_listeners() +void movie_root::cleanupUnloadedListeners(CharacterList& ll) { // remove unloaded character listeners from movie_root - for (KeyListeners::iterator iter = m_key_listeners.begin(); iter != m_key_listeners.end(); ) + for (CharacterList::iterator iter = ll.begin(); iter != ll.end(); ) { - character* ch = dynamic_cast<character*>(iter->get()); - if ( ch && ch->isUnloaded() ) - { - m_key_listeners.erase(iter++); - } - else - { - ++iter; - } + character* ch = iter->get(); + if ( ch->isUnloaded() ) iter = ll.erase(iter++); + else ++iter; } } void movie_root::notify_key_listeners(key::code k, bool down) { - // log_msg("Notifying " SIZET_FMT " character listeners", + // log_msg("Notifying " SIZET_FMT " character Key listeners", // m_key_listeners.size()); - for (KeyListeners::iterator iter = m_key_listeners.begin(); - iter != m_key_listeners.end(); ++iter) + KeyListeners copy = m_key_listeners; + for (CharacterList::iterator iter = copy.begin(), itEnd=copy.end(); + iter != itEnd; ++iter) { // sprite, button & input_edit_text characters - character* ch = dynamic_cast<character*>(iter->get()); - if ( ch && ! ch->isUnloaded() ) + character* ch = iter->get(); + if ( ! ch->isUnloaded() ) { if(down) { @@ -915,67 +910,52 @@ ch->on_event(event_id(event_id::KEY_PRESS, key::codeMap[k][0])); } else + { ch->on_event(event_id(event_id::KEY_UP, key::INVALID)); } } + } assert(testInvariant()); } -void movie_root::add_key_listener(as_object* listener) +/* static private */ +void movie_root::add_listener(CharacterList& ll, character* listener) { - for(KeyListeners::iterator i = m_key_listeners.begin(), e = m_key_listeners.end(); - i != e; ++i) + assert(listener); + for(CharacterList::iterator i = ll.begin(), e = ll.end(); i != e; ++i) { // Conceptually, we don't need to add the same character twice. // but see edit_text_character::setFocus()... if(*i == listener) return; } - //for character listeners, first added last called - m_key_listeners.push_front(listener); + ll.push_front(listener); } -void movie_root::remove_key_listener(as_object* listener) +/* static private */ +void movie_root::remove_listener(CharacterList& ll, character* listener) { - for(KeyListeners::iterator iter = m_key_listeners.begin(); - iter != m_key_listeners.end(); ) - { - if(*iter == listener) + assert(listener); + for(CharacterList::iterator iter = ll.begin(); iter != ll.end(); ) { - m_key_listeners.erase(iter++); + if(*iter == listener) iter = ll.erase(iter); + else ++iter; } - else - { - iter++; - } - } -} - -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) +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) + CharacterList copy = m_mouse_listeners; + for (CharacterList::iterator iter = copy.begin(), itEnd=copy.end(); + iter != itEnd; ++iter) { - // sprite, button & input_edit_text characters - // TODO: invoke functions on non-characters ! - character* ch = dynamic_cast<character*>(iter->get()); - if ( ch ) + character* ch = iter->get(); + if ( ! ch->isUnloaded() ) { ch->on_event(event); } @@ -1274,11 +1254,10 @@ } // Mark character key listeners - for (KeyListeners::const_iterator i=m_key_listeners.begin(), e=m_key_listeners.end(); - i != e; ++i) - { - (*i)->setReachable(); - } + std::for_each(m_key_listeners.begin(), m_key_listeners.end(), boost::bind(&character::setReachable, _1)); + + // Mark character mouse listeners + std::for_each(m_mouse_listeners.begin(), m_mouse_listeners.end(), boost::bind(&character::setReachable, _1)); // Mark global key object if ( _keyobject ) _keyobject->setReachable(); Index: server/movie_root.h =================================================================== RCS file: /sources/gnash/gnash/server/movie_root.h,v retrieving revision 1.89 retrieving revision 1.90 diff -u -b -r1.89 -r1.90 --- server/movie_root.h 16 Nov 2007 13:24:30 -0000 1.89 +++ server/movie_root.h 21 Nov 2007 17:11:52 -0000 1.90 @@ -15,7 +15,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.89 2007/11/16 13:24:30 strk Exp $ */ +/* $Id: movie_root.h,v 1.90 2007/11/21 17:11:52 strk Exp $ */ /// \page events_handling Handling of user events /// @@ -412,20 +412,35 @@ void * get_userdata() { return m_userdata; } void set_userdata(void * ud ) { m_userdata = ud; } - /// Notify both the character listeners and general object listeners + /// Notify still loaded character listeners for key events DSOEXPORT void notify_key_listeners(key::code k, bool down); - /// Push a new character listener to the container after constructing the character - void add_key_listener(as_object* listener); + /// Push a new character listener for key events + void add_key_listener(character* listener) + { + add_listener(m_key_listeners, listener); + } - /// Remove a character from the container only when the character is unloaded - void remove_key_listener(as_object* listener); + /// Remove a character listener for key events + void remove_key_listener(character* listener) + { + remove_listener(m_key_listeners, listener); + } + /// Notify still loaded character listeners for mouse events DSOEXPORT void notify_mouse_listeners(const event_id& event); - void add_mouse_listener(as_object* listener); + /// Push a new character listener for mouse events + void add_mouse_listener(character* listener) + { + add_listener(m_mouse_listeners, listener); + } - void remove_mouse_listener(as_object* listener); + /// Remove a character listener for mouse events + void remove_mouse_listener(character* listener) + { + remove_listener(m_mouse_listeners, listener); + } /// Get the character having focus // @@ -499,7 +514,8 @@ /// - Mouse entities (m_mouse_button_state) /// - Timer targets (_intervalTimers) /// - Resources reachable by ActionQueue code (_actionQueue) - /// - Key listeners (_keyListeners || m_key_listeners) + /// - Key listeners (m_key_listeners) + /// - Mouse listeners (m_mouse_listeners) /// - global Key object (_keyobject) /// void markReachableResources() const; @@ -559,6 +575,14 @@ private: + /// Listeners container + typedef std::list< boost::intrusive_ptr<character> > CharacterList; + + /// key and mouse listeners container + typedef CharacterList KeyListeners; + typedef CharacterList MouseListeners; + + /// Take care of dragging, if needed void doMouseDrag(); @@ -592,12 +616,21 @@ /// Notify the global Key ActionScript object about a key status change key_as_object * notify_global_key(key::code k, bool down); - /// Remove all listeners with a ref-count of 1 - /// (only referenced as key listeners) - // in new design: - // remove unloaded characters and unregistered as_objects - // from the key listeners container. - void cleanup_key_listeners(); + /// Remove unloaded key and mouselisteners. + void cleanupUnloadedListeners() + { + cleanupUnloadedListeners(m_key_listeners); + cleanupUnloadedListeners(m_mouse_listeners); + } + + /// Erase unloaded characters from the given listeners list + static void cleanupUnloadedListeners(CharacterList& ll); + + /// Push a character listener to the front of given container, if not already present + static void add_listener(CharacterList& ll, character* elem); + + /// Remove a listener from the list + static void remove_listener(CharacterList& ll, character* elem); /// Return the current Stage object // @@ -638,20 +671,13 @@ TimerMap _intervalTimers; unsigned int _lastTimerId; - /// A set of as_objects kept by intrusive_ptr - /// TODO: dont' use std::use, we need to well control the calling order - typedef std::set< boost::intrusive_ptr<as_object> > ListenerSet; - - /// key listeners container - typedef std::list< boost::intrusive_ptr<as_object> > KeyListeners; - /// Characters for listening key events KeyListeners m_key_listeners; boost::intrusive_ptr<key_as_object> _keyobject; /// Objects listening for mouse events (down,up,move) - ListenerSet m_mouse_listeners; + MouseListeners 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.389 retrieving revision 1.390 diff -u -b -r1.389 -r1.390 --- server/sprite_instance.cpp 20 Nov 2007 00:44:03 -0000 1.389 +++ server/sprite_instance.cpp 21 Nov 2007 17:11:52 -0000 1.390 @@ -2889,7 +2889,7 @@ // it might be there(eg. button_character). // TODO: optimize this. This is not necessary if we don't create // instances blindly above. - _vm.getRoot().remove_key_listener(ch.get()); + if ( ch ) _vm.getRoot().remove_key_listener(ch.get()); move_display_object(depth, &color_transform, &mat, ratio, clip_depth); } _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit