>+ if ( ch->isUnloaded() ) iter = ll.erase(iter++); Was this intended? " iter = ll.erase(iter++);"
--zou On Nov 22, 2007 1:11 AM, Sandro Santilli <[EMAIL PROTECTED]> wrote: > 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 > _______________________________________________ Gnash-commit mailing list Gnash-commit@gnu.org http://lists.gnu.org/mailman/listinfo/gnash-commit