gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-


From: Benjamin Wolsey
Subject: [Gnash-commit] [SCM] Gnash branch, master, updated. release_0_8_9_final-391-ga06bc2e
Date: Thu, 30 Jun 2011 12:17:39 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Gnash".

The branch, master has been updated
       via  a06bc2eb2a756d6e3b5b9e068cf70681c141b90d (commit)
       via  e6bc37fdcce364ad5a2fc3665cb83fab77cd62b4 (commit)
       via  6ee35292b5abbddacd0e7e162ee9e261216ebf2d (commit)
       via  d483827991e5dae34bd2f295b67d10a0c9232d3e (commit)
       via  1ae532a0053d47d01f967ef5d0ba9aff97625d81 (commit)
       via  366ba1369cf600128cf421f26bf1e309cf98c0fe (commit)
       via  3db73486d8b99425a707e6ab04acf37942303eb8 (commit)
       via  5d184071bdf2132d1a499e178423f9ce69b4a32c (commit)
       via  7922b200024f5eb81de98a0816deb9168154c4a3 (commit)
       via  1eb11eb0b70aa5001ea29fc4b185e21868e5ffa0 (commit)
       via  6f1126a57321cd96255ee017898e16e985f68c9e (commit)
       via  e86189d410e04bed0224ecaa77a7c394f656da07 (commit)
      from  eb85c80269b7af2a4c9b5cb26d65c4b0bd6719bb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit//commit/?id=a06bc2eb2a756d6e3b5b9e068cf70681c141b90d


commit a06bc2eb2a756d6e3b5b9e068cf70681c141b90d
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 13:51:30 2011 +0200

    Test more and log_unimpl.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index d7592ea..11e90cf 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -1019,6 +1019,7 @@ as_value
 button_blendMode(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    LOG_ONCE(log_unimpl("Button.blendMode"));
     UNUSED(obj);
     return as_value();
 }
@@ -1027,6 +1028,7 @@ as_value
 button_cacheAsBitmap(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    LOG_ONCE(log_unimpl("Button.cacheAsBitmap"));
     UNUSED(obj);
     return as_value();
 }
@@ -1035,6 +1037,7 @@ as_value
 button_filters(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    LOG_ONCE(log_unimpl("Button.filters"));
     UNUSED(obj);
     return as_value();
 }
@@ -1043,6 +1046,7 @@ as_value
 button_scale9Grid(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    LOG_ONCE(log_unimpl("Button.scale9Grid"));
     UNUSED(obj);
     return as_value();
 }
@@ -1051,6 +1055,7 @@ as_value
 button_getTabIndex(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    LOG_ONCE(log_unimpl("Button.getTabIndex"));
     UNUSED(obj);
     return as_value();
 }
@@ -1059,6 +1064,7 @@ as_value
 button_setTabIndex(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    LOG_ONCE(log_unimpl("Button.setTabIndex"));
     UNUSED(obj);
     return as_value();
 }
@@ -1066,7 +1072,9 @@ button_setTabIndex(const fn_call& fn)
 as_value
 button_getDepth(const fn_call& fn)
 {
-    Button* obj = ensure<IsDisplayObject<Button> >(fn);
+    // This does exactly the same as MovieClip.getDepth, but appears to be
+    // a separate function.
+    DisplayObject* obj = ensure<IsDisplayObject<> >(fn);
     return as_value(obj->get_depth());
 }
 
diff --git a/testsuite/actionscript.all/MovieClip.as 
b/testsuite/actionscript.all/MovieClip.as
index 8910152..351772b 100644
--- a/testsuite/actionscript.all/MovieClip.as
+++ b/testsuite/actionscript.all/MovieClip.as
@@ -119,11 +119,11 @@ endOfTest = function()
 #endif
 
 #if OUTPUT_VERSION == 6
-       check_totals(926); // SWF6
+       check_totals(928); // SWF6
 #endif
 
 #if OUTPUT_VERSION == 7
-       check_totals(959); // SWF7
+       check_totals(961); // SWF7
 #endif
 
 #if OUTPUT_VERSION >= 8
@@ -568,6 +568,11 @@ var mc3 = createEmptyMovieClip("mc3_mc", 50);
 check(mc3 != undefined);
 check_equals(mc3.getDepth(), 50);
 
+mc3.bd = Button.prototype.getDepth;
+check_equals(mc3.bd(), undefined);
+
+check(Button.prototype.getDepth != MovieClip.prototype.getDepth);
+
 #if OUTPUT_VERSION > 6 // {
 check_equals(getInstanceAtDepth(50), mc3);
 #endif // }

http://git.savannah.gnu.org/cgit//commit/?id=e6bc37fdcce364ad5a2fc3665cb83fab77cd62b4


commit e6bc37fdcce364ad5a2fc3665cb83fab77cd62b4
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 13:39:01 2011 +0200

    Test and implement Button.getDepth().
    
    It's only a very simple test.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index d4721dd..d7592ea 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -1067,8 +1067,7 @@ as_value
 button_getDepth(const fn_call& fn)
 {
     Button* obj = ensure<IsDisplayObject<Button> >(fn);
-    UNUSED(obj);
-    return as_value();
+    return as_value(obj->get_depth());
 }
 
 } // anonymous namespace
diff --git a/testsuite/misc-ming.all/ButtonPropertiesTest.c 
b/testsuite/misc-ming.all/ButtonPropertiesTest.c
index 355df04..3bb53bf 100644
--- a/testsuite/misc-ming.all/ButtonPropertiesTest.c
+++ b/testsuite/misc-ming.all/ButtonPropertiesTest.c
@@ -173,8 +173,8 @@ main(int argc, char **argv)
             "   check_equals(props(), 'instance' + c++);"
             "};"
             );
-                   
-    //add_actions(mo, "onEnterFrame = function() { props(); trace (s); };");
+             
+    check_equals(mo, "square1.button.getDepth()", "-16383");
     add_actions(mo, "stop();");
        SWFMovie_nextFrame(mo); /* showFrame */
 

http://git.savannah.gnu.org/cgit//commit/?id=6ee35292b5abbddacd0e7e162ee9e261216ebf2d


commit 6ee35292b5abbddacd0e7e162ee9e261216ebf2d
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 13:23:41 2011 +0200

    Expect pass.

diff --git a/testsuite/misc-ming.all/KeyEventOrder.c 
b/testsuite/misc-ming.all/KeyEventOrder.c
index 5e8cef1..607d952 100644
--- a/testsuite/misc-ming.all/KeyEventOrder.c
+++ b/testsuite/misc-ming.all/KeyEventOrder.c
@@ -195,7 +195,7 @@ main(int argc, char** argv)
 
   SWFMovie_nextFrame(mo);
 
-  xcheck_equals(mo, "_root.order",
+  check_equals(mo, "_root.order",
           "'mc2,mc1,o1,o2,button1,mc2,mc1,o1,o2,button3,'");
   
   SWFMovie_nextFrame(mo);

http://git.savannah.gnu.org/cgit//commit/?id=d483827991e5dae34bd2f295b67d10a0c9232d3e


commit d483827991e5dae34bd2f295b67d10a0c9232d3e
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 13:14:53 2011 +0200

    Don't use notifyEvent().
    
    The notifyEvent function is largely overkill because it handles far more
    events than generally required. In this case a Button-specific function
    is better.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index 39eb43c..d4721dd 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -354,7 +354,7 @@ Button::isEnabled()
 
 
 void
-Button::notifyEvent(const event_id& id)
+Button::keyPress(const event_id& id)
 {
     if (unloaded()) {
         // We don't respond to events while unloaded
diff --git a/libcore/Button.h b/libcore/Button.h
index 898c3ba..19f3509 100644
--- a/libcore/Button.h
+++ b/libcore/Button.h
@@ -86,7 +86,7 @@ public:
     virtual bool trackAsMenu();
 
        // called from keypress listener only
-       void notifyEvent(const event_id& id);
+       void keyPress(const event_id& id);
 
     /// Render this Button.
        virtual void display(Renderer& renderer, const Transform& xform);
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 1e346a1..bf0f720 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -619,15 +619,17 @@ movie_root::keyEvent(key::code k, bool down)
         ButtonKeys::const_iterator it =
             _buttonKeys.find(key::codeMap[k][key::SWF]);
 
+        // TODO: this searches through all ButtonActions for the correct
+        // one, even though we could easily know which one it's going to be
+        // because we search through them all to register the key codes.
         if (it != _buttonKeys.end()) {
             if (!it->second.first->unloaded()) {
-                it->second.first->notifyEvent(event_id(event_id::KEY_PRESS, 
k));
+                it->second.first->keyPress(event_id(event_id::KEY_PRESS, k));
             }
         }
-    }
 
-    // If we're focused on an editable text field, finally the text is updated
-    if (down) {
+        // If we're focused on an editable text field, finally the text
+        // is updated
         TextField* tf = dynamic_cast<TextField*>(_currentFocus);
         if (tf) tf->notifyEvent(event_id(event_id::KEY_PRESS, k));
     }

http://git.savannah.gnu.org/cgit//commit/?id=1ae532a0053d47d01f967ef5d0ba9aff97625d81


commit 1ae532a0053d47d01f967ef5d0ba9aff97625d81
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 12:58:28 2011 +0200

    Documentation, drop debugging, cleanup.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index 49cdf22..39eb43c 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -26,6 +26,7 @@
 
 #include <boost/bind.hpp>
 #include <utility>
+#include <functional>
 
 #include "DefineButtonTag.h"
 #include "as_value.h"
@@ -204,7 +205,8 @@ private:
     as_environment& _env;
 };
 
-class ButtonActionPusher {
+class ButtonActionPusher
+{
 public:
     ButtonActionPusher(movie_root& mr, DisplayObject* this_ptr)
         :
@@ -222,7 +224,8 @@ private:
     DisplayObject* _tp;
 };
 
-class ButtonKeyRegisterer {
+class ButtonKeyRegisterer : public std::unary_function<int, void>
+{
 public:
     ButtonKeyRegisterer(movie_root& mr, Button* this_ptr)
         :
@@ -230,9 +233,9 @@ public:
         _tp(this_ptr)
     {}
 
-    void operator()(const SWF::ButtonAction& b) const
+    void operator()(int code) const
     {
-        _mr.registerButtonKey(b.getKeyCode(), _tp);
+        _mr.registerButtonKey(code, _tp);
     }
 
 private:
@@ -855,7 +858,7 @@ Button::construct(as_object* initObj)
     // Register key events.
     if (_def->hasKeyPressHandler()) {
         ButtonKeyRegisterer r(stage(), this);
-        _def->forEachAction(r);
+        _def->visitKeyCodes(r);
     }
 
 }
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 1453bfe..1e346a1 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -926,8 +926,6 @@ movie_root::timeToNextFrame() const
 void
 movie_root::display()
 {
-//    GNASH_REPORT_FUNCTION;
-
     assert(testInvariant());
 
     clearInvalidated();
@@ -1797,7 +1795,6 @@ std::string
 movie_root::callExternalJavascript(const std::string &name, 
                                    const std::vector<as_value> &fnargs)
 {
-    // GNASH_REPORT_FUNCTION;
     std::string result;
     // If the browser is connected, we send an Invoke message to the
     // browser.
@@ -1824,7 +1821,6 @@ std::string
 movie_root::callExternalCallback(const std::string &name, 
                  const std::vector<as_value> &fnargs)
 {
-    // GNASH_REPORT_FUNCTION;
 
     MovieClip *mc = getLevel(0);
     as_object *obj = getObject(mc);
@@ -1875,8 +1871,6 @@ movie_root::callExternalCallback(const std::string &name,
 void
 movie_root::removeButtonKey(Button* listener)
 {
-    GNASH_REPORT_FUNCTION;
-
     // Remove the button and the key associated with it from the map.
     for (ButtonKeys::iterator i = _buttonKeys.begin(), e = _buttonKeys.end();
             i != e;) {
@@ -1891,15 +1885,12 @@ movie_root::removeButtonKey(Button* listener)
 void
 movie_root::registerButtonKey(int code, Button* listener)
 {
-    log_debug("Adding listener for code %s", +code);
-
     const size_t frame = _rootMovie->get_current_frame();
-    ButtonKeys::iterator it = _buttonKeys.find(code);
+    ButtonKeys::const_iterator it = _buttonKeys.find(code);
 
     if (it != _buttonKeys.end() && it->second.second < frame) {
         return;
     }
-
     _buttonKeys[code] = std::make_pair(listener, frame);
 }
 
diff --git a/libcore/movie_root.h b/libcore/movie_root.h
index 4e10753..2e6e4ed 100644
--- a/libcore/movie_root.h
+++ b/libcore/movie_root.h
@@ -391,6 +391,12 @@ public:
     }
 
     /// Push a new DisplayObject listener for key events
+    //
+    /// Each button can register several events for its actions. Only one
+    /// event can be registered for each key. The key code is unique to
+    /// Buttons: it is neither ascii nor the key-specific code.
+    //
+    /// @param c    The SWF key code for the button event.
     void registerButtonKey(int c, Button* listener);
 
     /// Remove a DisplayObject listener for key events
diff --git a/libcore/swf/DefineButtonTag.h b/libcore/swf/DefineButtonTag.h
index 304ba3c..40b76ec 100644
--- a/libcore/swf/DefineButtonTag.h
+++ b/libcore/swf/DefineButtonTag.h
@@ -157,6 +157,8 @@ public:
         return (_conditions & KEYPRESS);
     }
 
+private:
+
     /// Return the keycode triggering this action
     //
     /// Return 0 if no key is supposed to trigger us
@@ -164,8 +166,6 @@ public:
         return (_conditions & KEYPRESS) >> 9;
     }
 
-private:
-
     enum Condition
     {
         IDLE_TO_OVER_UP = 1 << 0,
@@ -251,12 +251,15 @@ public:
         }
     }
 
+    /// Invoke a functor for each key code that should trigger an action.
+    //
+    /// Note: the key code is neither ascii nor a key index, but rather a
+    /// special button key code (the SWF column of GnashKey.h).
     template<class E>
-    void forEachAction(E& f) const {
-        for (size_t i = 0, e = _buttonActions.size(); i < e; ++i) {
-            const ButtonAction& ba = _buttonActions[i];
-            f(ba);
-        }
+    void visitKeyCodes(E& f) const {
+        std::for_each(_buttonActions.begin(), _buttonActions.end(),
+            boost::bind(f, boost::bind(
+                    boost::mem_fn(&ButtonAction::getKeyCode), _1)));
     }
     
 private:

http://git.savannah.gnu.org/cgit//commit/?id=366ba1369cf600128cf421f26bf1e309cf98c0fe


commit 366ba1369cf600128cf421f26bf1e309cf98c0fe
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 12:32:20 2011 +0200

    Remove unneeded member, minor renames.

diff --git a/libcore/swf/DefineButtonTag.cpp b/libcore/swf/DefineButtonTag.cpp
index 22ac365..8cf427b 100644
--- a/libcore/swf/DefineButtonTag.cpp
+++ b/libcore/swf/DefineButtonTag.cpp
@@ -386,10 +386,10 @@ ButtonRecord::read(SWFStream& in, TagType t,
         return false;
     }
     in.ensureBytes(2);
-    _id = in.read_u16();
+    const boost::uint16_t id = in.read_u16();
 
     // Get DisplayObject definition now (safer)
-    _definitionTag = m.getDefinitionTag(_id);
+    _definitionTag = m.getDefinitionTag(id);
 
     // If no DisplayObject with given ID is found in the movie
     // definition, we print an error, but keep parsing.
@@ -397,18 +397,18 @@ ButtonRecord::read(SWFStream& in, TagType t,
         IF_VERBOSE_MALFORMED_SWF(
         log_swferror(_("   button record for states [%s] refer to "
             "DisplayObject with id %d, which is not found "
-            "in the chars dictionary"), computeButtonStatesString(flags), _id);
+            "in the chars dictionary"), computeButtonStatesString(flags), id);
         );
     }
     else {
         IF_VERBOSE_PARSE(
         log_parse(_("   button record for states [%s] contain "
             "DisplayObject %d (%s)"), computeButtonStatesString(flags),
-            _id, typeName(*_definitionTag));
+            id, typeName(*_definitionTag));
         );
     }
 
-    if (in.tell()+2 > endPos) {
+    if (in.tell() + 2 > endPos) {
         IF_VERBOSE_MALFORMED_SWF(
         log_swferror(_("   premature end of button record input stream, "
                 "can't read button layer (depth?)"));
diff --git a/libcore/swf/DefineButtonTag.h b/libcore/swf/DefineButtonTag.h
index 3a8bb95..304ba3c 100644
--- a/libcore/swf/DefineButtonTag.h
+++ b/libcore/swf/DefineButtonTag.h
@@ -119,10 +119,9 @@ private:
     bool _down;
     bool _over;
     bool _up;
-    int    _id;
 
-    // This is a GC resource, so not owned by anyone.
-    const DefinitionTag* _definitionTag;
+    // This is a ref-counted resource, so not owned by anyone.
+    boost::intrusive_ptr<const DefinitionTag> _definitionTag;
 
     int _buttonLayer;
 
@@ -167,7 +166,7 @@ public:
 
 private:
 
-    enum condition
+    enum Condition
     {
         IDLE_TO_OVER_UP = 1 << 0,
         OVER_UP_TO_IDLE = 1 << 1,
@@ -180,7 +179,8 @@ private:
         OVER_DOWN_TO_IDLE = 1 << 8,
         KEYPRESS = 0xFE00  // highest 7 bits
     };
-    int _conditions;
+
+    boost::uint16_t _conditions;
 
 };
 

http://git.savannah.gnu.org/cgit//commit/?id=3db73486d8b99425a707e6ab04acf37942303eb8


commit 3db73486d8b99425a707e6ab04acf37942303eb8
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 09:41:02 2011 +0200

    Fix button key listeners.
    
    Only one listener can be registered for each key. Subsequent attempts
    are ignored. A frame count is needed for skip back, because new
    DisplayObjects are constructed before the old ones are destroyed when
    jumping back, and this means that their attempt to register a key
    listener is blocked by the not-yet-destroyed Button.

diff --git a/libcore/Button.cpp b/libcore/Button.cpp
index 92435bb..49cdf22 100644
--- a/libcore/Button.cpp
+++ b/libcore/Button.cpp
@@ -222,6 +222,24 @@ private:
     DisplayObject* _tp;
 };
 
+class ButtonKeyRegisterer {
+public:
+    ButtonKeyRegisterer(movie_root& mr, Button* this_ptr)
+        :
+        _mr(mr),
+        _tp(this_ptr)
+    {}
+
+    void operator()(const SWF::ButtonAction& b) const
+    {
+        _mr.registerButtonKey(b.getKeyCode(), _tp);
+    }
+
+private:
+    movie_root& _mr;
+    Button* _tp;
+};
+
 }
 
 namespace {
@@ -294,17 +312,10 @@ Button::Button(as_object* object, const 
SWF::DefineButtonTag* def,
     _def(def)
 {
     assert(object);
-
-    // check up presence Key events
-    if (_def->hasKeyPressHandler()) {
-        stage().add_key_listener(this);
-    }
-
 }
 
 Button::~Button()
 {
-    stage().remove_key_listener(this);
 }
 
 bool
@@ -343,23 +354,21 @@ void
 Button::notifyEvent(const event_id& id)
 {
     if (unloaded()) {
-        // We dont' respond to events while unloaded
+        // We don't respond to events while unloaded
         // See bug #22982
         return; 
     }
 
-    // We only respond keypress events
-    if ( id.id() != event_id::KEY_PRESS ) return;
-
-    // We only respond to valid key code (should we assert here?)
-    if ( id.keyCode() == key::INVALID ) return;
+    assert(id.id() == event_id::KEY_PRESS);
+    assert(id.keyCode() != key::INVALID);
 
     ButtonActionPusher xec(stage(), this); 
     _def->forEachTrigger(id, xec);
 }
 
 bool
-Button::handleFocus() {
+Button::handleFocus()
+{
     /// Nothing to do, but can receive focus.
     return false;
 }
@@ -454,8 +463,7 @@ Button::topmostMouseEntity(boost::int32_t x, boost::int32_t 
y)
 void
 Button::mouseEvent(const event_id& event)
 {
-    if ( unloaded() )
-    {
+    if (unloaded()) {
         // We don't respond to events while unloaded. See bug #22982.
         log_debug("Button %s received %s button event while unloaded: ignored",
             getTarget(), event);
@@ -843,6 +851,13 @@ Button::construct(as_object* initObj)
 
     // There is no INITIALIZE/CONSTRUCT/LOAD/ENTERFRAME/UNLOAD event 
     // for Buttons
+
+    // Register key events.
+    if (_def->hasKeyPressHandler()) {
+        ButtonKeyRegisterer r(stage(), this);
+        _def->forEachAction(r);
+    }
+
 }
 
 void
@@ -866,6 +881,7 @@ Button::markOwnResources() const
 bool
 Button::unloadChildren()
 {
+    GNASH_REPORT_FUNCTION;
 
     bool childsHaveUnload = false;
 
@@ -893,6 +909,9 @@ Button::unloadChildren()
 void
 Button::destroy()
 {
+    GNASH_REPORT_FUNCTION;
+
+    stage().removeButtonKey(this);
 
     for (DisplayObjects::iterator i = _stateCharacters.begin(),
             e=_stateCharacters.end(); i != e; ++i) {
diff --git a/libcore/Button.h b/libcore/Button.h
index 20b6ea7..898c3ba 100644
--- a/libcore/Button.h
+++ b/libcore/Button.h
@@ -120,8 +120,7 @@ public:
 
     /// Do ActionScript construction of the Button.
     //
-    /// (1) Register this button instance as a live DisplayObject
-    /// (2) Construct all button state DisplayObjects.
+    /// Construct all button state DisplayObjects.
     //
     /// @param init     An init object, which can be passed when constructing
     ///                 Buttons with attachMovie, but is never used.
diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 452d7e6..1453bfe 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -518,8 +518,8 @@ movie_root::reset()
     // remove all loadMovie requests
     _movieLoader.clear();
 
-    // remove key listeners
-    _keyListeners.clear();
+    // Remove button key events.
+    _buttonKeys.clear();
 
     // Cleanup the stack.
     _vm.getStack().clear();
@@ -600,10 +600,12 @@ movie_root::keyEvent(key::code k, bool down)
             // A stack limit like that is hardly of any use, but could be used
             // maliciously to crash Gnash.
             if (down) {
-                callMethod(key, getURI(_vm, NSV::PROP_BROADCAST_MESSAGE), 
"onKeyDown");
+                callMethod(key, getURI(_vm, NSV::PROP_BROADCAST_MESSAGE),
+                        "onKeyDown");
             }
             else {
-                callMethod(key, getURI(_vm,NSV::PROP_BROADCAST_MESSAGE), 
"onKeyUp");
+                callMethod(key, getURI(_vm,NSV::PROP_BROADCAST_MESSAGE),
+                        "onKeyUp");
             }
         }
         catch (const ActionLimitException &e) {
@@ -613,21 +615,17 @@ movie_root::keyEvent(key::code k, bool down)
         }
     }
     
-    // Then any button keys are notified.
-    Listeners lcopy = _keyListeners;
-    for (Listeners::iterator iter = lcopy.begin(), itEnd = lcopy.end();
-            iter != itEnd; ++iter) {
-
-        // sprite, button & input_edit_text DisplayObjects
-        Button* const ch = *iter;
-        if (ch->unloaded()) continue;
+    if (down) {
+        ButtonKeys::const_iterator it =
+            _buttonKeys.find(key::codeMap[k][key::SWF]);
 
-        if (down) {
-            ch->notifyEvent(event_id(event_id::KEY_PRESS, k));
+        if (it != _buttonKeys.end()) {
+            if (!it->second.first->unloaded()) {
+                it->second.first->notifyEvent(event_id(event_id::KEY_PRESS, 
k));
+            }
         }
     }
 
-
     // If we're focused on an editable text field, finally the text is updated
     if (down) {
         TextField* tf = dynamic_cast<TextField*>(_currentFocus);
@@ -1728,17 +1726,6 @@ movie_root::markReachableResources() const
     }
 #endif
     
-#if ( GNASH_PARANOIA_LEVEL > 1 ) || 
defined(ALLOW_GC_RUN_DURING_ACTIONS_EXECUTION)
-    for (Listeners::const_iterator i=_keyListeners.begin(),
-            e=_keyListeners.end(); i!=e; ++i) {
-#ifdef ALLOW_GC_RUN_DURING_ACTIONS_EXECUTION
-        (*i)->setReachable();
-#else
-        assert((*i)->isReachable());
-#endif
-    }
-#endif
-
 }
 
 InteractiveObject*
@@ -1886,20 +1873,34 @@ movie_root::callExternalCallback(const std::string 
&name,
 }
 
 void
-movie_root::remove_key_listener(Button* listener)
+movie_root::removeButtonKey(Button* listener)
 {
-    _keyListeners.remove_if(std::bind2nd(std::equal_to<Button*>(), listener));
+    GNASH_REPORT_FUNCTION;
+
+    // Remove the button and the key associated with it from the map.
+    for (ButtonKeys::iterator i = _buttonKeys.begin(), e = _buttonKeys.end();
+            i != e;) {
+        if (i->second.first == listener) {
+            _buttonKeys.erase(i++);
+        }
+        else ++i;
+    }
+
 }
 
 void
-movie_root::add_key_listener(Button* listener)
+movie_root::registerButtonKey(int code, Button* listener)
 {
-    assert(listener);
+    log_debug("Adding listener for code %s", +code);
 
-    if (std::find(_keyListeners.begin(), _keyListeners.end(), listener)
-            != _keyListeners.end()) return;
+    const size_t frame = _rootMovie->get_current_frame();
+    ButtonKeys::iterator it = _buttonKeys.find(code);
+
+    if (it != _buttonKeys.end() && it->second.second < frame) {
+        return;
+    }
 
-    _keyListeners.push_front(listener);
+    _buttonKeys[code] = std::make_pair(listener, frame);
 }
 
 void
diff --git a/libcore/movie_root.h b/libcore/movie_root.h
index afdf99a..4e10753 100644
--- a/libcore/movie_root.h
+++ b/libcore/movie_root.h
@@ -150,9 +150,6 @@ class DSOEXPORT movie_root : public GcRoot, 
boost::noncopyable
 {
 public:
     
-    /// Listeners container
-    typedef std::list<Button*> Listeners;
-
     class LoadCallback {
     public:
         LoadCallback(boost::shared_ptr<IOChannel> s, as_object* o)
@@ -394,10 +391,10 @@ public:
     }
 
     /// Push a new DisplayObject listener for key events
-    void add_key_listener(Button* listener);
+    void registerButtonKey(int c, Button* listener);
 
     /// Remove a DisplayObject listener for key events
-    void remove_key_listener(Button* listener);
+    void removeButtonKey(Button* listener);
 
     /// Get the DisplayObject having focus
     //
@@ -566,9 +563,7 @@ public:
     /// - Mouse entities (m_mouse_button_state)
     /// - Timer targets (_intervalTimers)
     /// - Resources reachable by ActionQueue code (_actionQueue)
-    /// - Key listeners (_keyListeners)
     /// - Any DisplayObject being dragged 
-    ///
     void markReachableResources() const;
 
     /// \brief
@@ -927,15 +922,13 @@ private:
 
     void handleActionLimitHit(const std::string& ref);
 
-    /// Buttons listening for key events
-    //
-    /// Note that Buttons (the only key listeners left) deregister themselves
-    /// on destruction. This isn't correct behaviour and also requires that
-    /// _keyListeners be alive longer than _gc so that deregistration doesn't
-    /// access a destroyed object.
+    /// A map of SWF key code to Buttons.
     //
-    /// TODO: fix it.
-    Listeners _keyListeners;
+    /// The Buttons are removed on destruction, so there is no need to
+    /// mark them reachable.
+    typedef std::pair<Button*, size_t> ButtonFrame;
+    typedef std::map<int, ButtonFrame> ButtonKeys;
+    ButtonKeys _buttonKeys;
 
     GC _gc;
 
diff --git a/libcore/swf/DefineButtonTag.cpp b/libcore/swf/DefineButtonTag.cpp
index 53a73a6..22ac365 100644
--- a/libcore/swf/DefineButtonTag.cpp
+++ b/libcore/swf/DefineButtonTag.cpp
@@ -297,8 +297,7 @@ ButtonAction::ButtonAction(SWFStream& in, TagType t, 
unsigned long endPos,
 bool
 ButtonAction::triggeredBy(const event_id& ev) const
 {
-    switch ( ev.id() )
-    {
+    switch (ev.id()) {
         case event_id::ROLL_OVER: return _conditions & IDLE_TO_OVER_UP;
         case event_id::ROLL_OUT: return _conditions & OVER_UP_TO_IDLE;
         case event_id::PRESS: return _conditions & OVER_UP_TO_OVER_DOWN;
@@ -309,7 +308,7 @@ ButtonAction::triggeredBy(const event_id& ev) const
         case event_id::KEY_PRESS:
         {
             int keycode = getKeyCode();
-            if (! keycode) return false; // not a keypress event
+            if (!keycode) return false; // not a keypress event
             return key::codeMap[ev.keyCode()][key::SWF] == keycode;
         }
         default: return false;
diff --git a/libcore/swf/DefineButtonTag.h b/libcore/swf/DefineButtonTag.h
index 26020f5..3a8bb95 100644
--- a/libcore/swf/DefineButtonTag.h
+++ b/libcore/swf/DefineButtonTag.h
@@ -158,8 +158,6 @@ public:
         return (_conditions & KEYPRESS);
     }
 
-private:
-
     /// Return the keycode triggering this action
     //
     /// Return 0 if no key is supposed to trigger us
@@ -167,6 +165,8 @@ private:
         return (_conditions & KEYPRESS) >> 9;
     }
 
+private:
+
     enum condition
     {
         IDLE_TO_OVER_UP = 1 << 0,
@@ -250,6 +250,14 @@ public:
             if (ba.triggeredBy(ev)) f(ba._actions);
         }
     }
+
+    template<class E>
+    void forEachAction(E& f) const {
+        for (size_t i = 0, e = _buttonActions.size(); i < e; ++i) {
+            const ButtonAction& ba = _buttonActions[i];
+            f(ba);
+        }
+    }
     
 private:
 

http://git.savannah.gnu.org/cgit//commit/?id=5d184071bdf2132d1a499e178423f9ce69b4a32c


commit 5d184071bdf2132d1a499e178423f9ce69b4a32c
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 08:55:32 2011 +0200

    Don't send unhandled key events to Buttons.
    
    Buttons do not handle key down or key up events, so don't send them.

diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index b730ad9..452d7e6 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -623,12 +623,8 @@ movie_root::keyEvent(key::code k, bool down)
         if (ch->unloaded()) continue;
 
         if (down) {
-            ch->notifyEvent(event_id(event_id::KEY_DOWN, key::INVALID)); 
             ch->notifyEvent(event_id(event_id::KEY_PRESS, k));
         }
-        else {
-            ch->notifyEvent(event_id(event_id::KEY_UP, key::INVALID));   
-        }
     }
 
 

http://git.savannah.gnu.org/cgit//commit/?id=7922b200024f5eb81de98a0816deb9168154c4a3


commit 7922b200024f5eb81de98a0816deb9168154c4a3
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 08:36:51 2011 +0200

    Remove silly copy-paste error.

diff --git a/libcore/asobj/Sound_as.cpp b/libcore/asobj/Sound_as.cpp
index a1864b2..760abce 100644
--- a/libcore/asobj/Sound_as.cpp
+++ b/libcore/asobj/Sound_as.cpp
@@ -287,9 +287,7 @@ sound_class_init(as_object& where, const ObjectURI& uri)
     proto->set_member_flags(NSV::PROP_CONSTRUCTOR, PropFlags::readOnly);
     proto->set_member_flags(NSV::PROP_uuPROTOuu, PropFlags::readOnly, 0);
 
-    // Register _global.String
     where.init_member(uri, cl, as_object::DefaultFlags);
-
 }
 
 void

http://git.savannah.gnu.org/cgit//commit/?id=1eb11eb0b70aa5001ea29fc4b185e21868e5ffa0


commit 1eb11eb0b70aa5001ea29fc4b185e21868e5ffa0
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 08:34:44 2011 +0200

    Header cleanups.

diff --git a/libcore/DisplayObject.cpp b/libcore/DisplayObject.cpp
index 3f0e604..7da37d4 100644
--- a/libcore/DisplayObject.cpp
+++ b/libcore/DisplayObject.cpp
@@ -25,8 +25,6 @@
 #include "DisplayObject.h"
 
 #include <utility>
-#include <boost/tuple/tuple.hpp>
-#include <boost/algorithm/string/case_conv.hpp>
 #include <boost/assign/list_of.hpp>
 #include <boost/bind.hpp>
 #include <boost/logic/tribool.hpp>

http://git.savannah.gnu.org/cgit//commit/?id=6f1126a57321cd96255ee017898e16e985f68c9e


commit 6f1126a57321cd96255ee017898e16e985f68c9e
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 08:31:09 2011 +0200

    Minor cleanups.

diff --git a/libcore/movie_root.cpp b/libcore/movie_root.cpp
index 8a2d887..b730ad9 100644
--- a/libcore/movie_root.cpp
+++ b/libcore/movie_root.cpp
@@ -27,9 +27,7 @@
 #include <bitset>
 #include <cassert>
 #include <functional>
-#include <boost/algorithm/string/erase.hpp>
 #include <boost/algorithm/string/replace.hpp>
-#include <boost/ptr_container/ptr_map.hpp>
 #include <boost/ptr_container/ptr_deque.hpp>
 #include <boost/algorithm/string/case_conv.hpp>
 #include <boost/bind.hpp>
@@ -1549,11 +1547,11 @@ movie_root::processInvoke(ExternalInterface::invoke_t 
*invoke)
         std::string var = invoke->args[0].to_string();
         as_value val;
         obj->get_member(getURI(vm, var), &val);
-    // GetVariable sends the value of the variable
-    ss << ExternalInterface::toXML(val);
+        // GetVariable sends the value of the variable
+        ss << ExternalInterface::toXML(val);
     } else if (invoke->name == "GotoFrame") {
         log_unimpl("ExternalInterface::GotoFrame()");
-    // GotoFrame doesn't send a response
+        // GotoFrame doesn't send a response
     } else if (invoke->name == "IsPlaying") {
         const bool result = 
             
callInterface<bool>(HostMessage(HostMessage::EXTERNALINTERFACE_ISPLAYING));

http://git.savannah.gnu.org/cgit//commit/?id=e86189d410e04bed0224ecaa77a7c394f656da07


commit e86189d410e04bed0224ecaa77a7c394f656da07
Author: Benjamin Wolsey <address@hidden>
Date:   Thu Jun 30 08:20:36 2011 +0200

    Add documentation for recent changes.

diff --git a/libcore/movie_root.h b/libcore/movie_root.h
index df367b8..afdf99a 100644
--- a/libcore/movie_root.h
+++ b/libcore/movie_root.h
@@ -669,8 +669,18 @@ public:
         return _unreleasedKeys;
     }
 
+    /// Register an actionscript class for construction of a MovieClip
+    //
+    /// @param sprite   The definition tag for the MovieClip to be placed on
+    ///                 stage
+    /// @param class    The ActionScript class to be used in construction.
     void registerClass(const SWF::DefinitionTag* sprite, as_function* cls);
 
+    /// Get the actionscript class for constructing a MovieClip
+    //
+    /// @param sprite   The definition tag for the MovieClip to be placed on
+    ///                 stage
+    /// @return         The class to be used, or 0 if no class is associated.
     as_function* getRegisteredClass(const SWF::DefinitionTag* sprite) const;
 
     /// Set a filedescriptor to use for host application requests

-----------------------------------------------------------------------

Summary of changes:
 libcore/Button.cpp                             |   71 +++++++++++++------
 libcore/Button.h                               |    5 +-
 libcore/DisplayObject.cpp                      |    2 -
 libcore/asobj/Sound_as.cpp                     |    2 -
 libcore/movie_root.cpp                         |   90 ++++++++++-------------
 libcore/movie_root.h                           |   39 ++++++----
 libcore/swf/DefineButtonTag.cpp                |   15 ++--
 libcore/swf/DefineButtonTag.h                  |   21 ++++--
 testsuite/actionscript.all/MovieClip.as        |    9 ++-
 testsuite/misc-ming.all/ButtonPropertiesTest.c |    4 +-
 testsuite/misc-ming.all/KeyEventOrder.c        |    2 +-
 11 files changed, 148 insertions(+), 112 deletions(-)


hooks/post-receive
-- 
Gnash



reply via email to

[Prev in Thread] Current Thread [Next in Thread]