gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r10967: Implement addChild() and add


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r10967: Implement addChild() and addChildAt() in the DisplayList. Currently they
Date: Tue, 02 Jun 2009 14:32:51 +0200
User-agent: Bazaar (1.13.1)

------------------------------------------------------------
revno: 10967
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Tue 2009-06-02 14:32:51 +0200
message:
  Implement addChild() and addChildAt() in the DisplayList. Currently they
  are implemented as global functions in ActionScript, but they should
  in fact be members of DisplayObjectContainer only.
modified:
  libcore/DisplayList.cpp
  libcore/DisplayList.h
  libcore/MovieClip.cpp
  libcore/MovieClip.h
  libcore/movie_root.cpp
    ------------------------------------------------------------
    revno: 10951.1.2
    committer: Benjamin Wolsey <address@hidden>
    branch nick: test
    timestamp: Tue 2009-06-02 09:58:24 +0200
    message:
      Implement addChild() and addChildAt() using the DisplayList through
      MovieClip (should be DisplayObjectContainer).
      
      Obsolete _childs member in movie_root, as this now delegates to the 
      DisplayList of the _root MovieClip.
    modified:
      libcore/DisplayList.cpp
      libcore/DisplayList.h
      libcore/MovieClip.cpp
      libcore/MovieClip.h
      libcore/movie_root.cpp
=== modified file 'libcore/DisplayList.cpp'
--- a/libcore/DisplayList.cpp   2009-04-22 11:55:09 +0000
+++ b/libcore/DisplayList.cpp   2009-06-02 07:58:24 +0000
@@ -206,7 +206,8 @@
 }
 
 void
-DisplayList::placeDisplayObject(DisplayObject* ch, int depth, as_object* 
initObj)
+DisplayList::placeDisplayObject(DisplayObject* ch, int depth,
+        as_object* initObj)
 {
     assert(!ch->unloaded());
     ch->set_invalidated();
@@ -265,8 +266,8 @@
 }
 
 void
-DisplayList::replaceDisplayObject(DisplayObject* ch, int depth, bool 
use_old_cxform,
-       bool use_old_matrix)
+DisplayList::replaceDisplayObject(DisplayObject* ch, int depth,
+        bool use_old_cxform, bool use_old_matrix)
 {
     testInvariant();
 
@@ -276,13 +277,6 @@
     ch->set_invalidated();
     ch->set_depth(depth);
 
-    // NOTE: currently, ::restart also cleans up all
-    // property, which include __proto__ !!
-    // For this reason I commented it out. Since no tests in
-    // the testsuite are failing
-    // I'm not sure what does this break. Udo: do you remember ? --strk;
-    // ch->restart();
-
     container_type::iterator it =
         std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
             DepthGreaterOrEqual(depth));
@@ -498,7 +492,89 @@
     testInvariant();
 
 }
-    
+
+/// Inserts a DisplayObject at the specified index (depth)
+//
+/// If a DisplayObject is already at that index, it is moved up.
+/// This implements AS3 DisplayObjectContainer.addChildAt().
+//
+/// @param obj      The DisplayObject to insert. This should already be
+///                 removed from any other DisplayLists. It should not be
+///                 the owner of this DisplayList or any parent of that
+///                 owner.
+/// @param index    The index at which to insert the DisplayObject.
+void
+DisplayList::insertDisplayObject(DisplayObject* obj, int index)
+{
+    testInvariant();
+
+    assert(!obj->unloaded());
+
+    obj->set_invalidated();
+    obj->set_depth(index);
+
+    // Find the first index greater than or equal to the required index
+    container_type::iterator it =
+        std::find_if(_charsByDepth.begin(), _charsByDepth.end(),
+            DepthGreaterOrEqual(index));
+        
+    // Insert the DisplayObject before that position
+    _charsByDepth.insert(it, obj);
+
+    // Shift depths upwards until no depths are duplicated. No DisplayObjects
+    // are removed!
+    while (it != _charsByDepth.end() && (*it)->get_depth() == index) {
+        (*it)->set_depth(index + 1);
+        ++index, ++it;
+    }
+
+    // Give life to this instance
+    obj->stagePlacementCallback();
+
+    testInvariant();
+
+}
+
+/// Adds a DisplayObject at the top of the DisplayList.
+//
+/// This implements AS3 DisplayObjectContainer.addChild().
+//
+/// @param obj      The DisplayObject to insert. This should already be
+///                 removed from any other DisplayLists. It should not be
+///                 the owner of this DisplayList or any parent of that
+///                 owner.
+void
+DisplayList::addDisplayObject(DisplayObject* obj)
+{
+    testInvariant();
+
+    assert(!obj->unloaded());
+
+    obj->set_invalidated();
+
+    int index;
+
+    if (_charsByDepth.empty()) {
+        index = 0;
+    }
+    else {
+        container_type::const_reverse_iterator it = _charsByDepth.rbegin();
+        index = (*it)->get_depth() + 1;
+    }
+
+    obj->set_depth(index);
+
+    // Insert the DisplayObject at the end
+    _charsByDepth.insert(_charsByDepth.end(), obj);
+
+    // Give life to this instance
+    obj->stagePlacementCallback();
+
+    testInvariant();
+
+}
+
+
 bool
 DisplayList::unload()
 {

=== modified file 'libcore/DisplayList.h'
--- a/libcore/DisplayList.h     2009-04-03 09:48:13 +0000
+++ b/libcore/DisplayList.h     2009-06-02 07:58:24 +0000
@@ -73,7 +73,6 @@
     /// Output operator
        friend std::ostream& operator<< (std::ostream&, const DisplayList&);
 
-
        /// \brief
        /// Place a new DisplayObject at the specified depth,
        /// replacing any existing DisplayObject at the same depth.
@@ -93,7 +92,8 @@
        ///
     /// @param initObj
     /// an object to initialize the new DisplayObject's properties with.
-       void placeDisplayObject(DisplayObject* ch, int depth, as_object* 
initObj = 0);
+       void placeDisplayObject(DisplayObject* ch, int depth,
+            as_object* initObj = 0);
 
        /// \brief
        /// Replace the old DisplayObject at the specified depth with
@@ -203,6 +203,28 @@
        ///     pre-existing DisplayObject at the same depth.
        void add(DisplayObject* ch, bool replace);
 
+    /// Inserts a DisplayObject at the specified index (depth)
+    //
+    /// If a DisplayObject is already at that index, it is moved up.
+    /// This implements AS3 DisplayObjectContainer.addChildAt().
+    //
+    /// @param obj      The DisplayObject to insert. This should already be
+    ///                 removed from any other DisplayLists. It should not be
+    ///                 the owner of this DisplayList or any parent of that
+    ///                 owner.
+    /// @param index    The index at which to insert the DisplayObject.
+    void insertDisplayObject(DisplayObject* obj, int index);
+
+    /// Adds a DisplayObject at the top of the DisplayList.
+    //
+    /// This implements AS3 DisplayObjectContainer.addChild().
+    //
+    /// @param obj      The DisplayObject to insert. This should already be
+    ///                 removed from any other DisplayLists. It should not be
+    ///                 the owner of this DisplayList or any parent of that
+    ///                 owner.
+    void addDisplayObject(DisplayObject* obj);
+
        /// \brief
        /// Display the referenced DisplayObjects.
        /// Lower depths are obscured by higher depths.

=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp     2009-05-25 12:34:53 +0000
+++ b/libcore/MovieClip.cpp     2009-06-02 07:58:24 +0000
@@ -2267,6 +2267,22 @@
     return shouldKeepAlive;
 }
 
+
+DisplayObject*
+MovieClip::addChild(DisplayObject* obj)
+{
+    _displayList.addDisplayObject(obj);
+    return obj;
+}
+
+
+DisplayObject*
+MovieClip::addChildAt(DisplayObject* obj, int index)
+{
+    _displayList.insertDisplayObject(obj, index);
+    return obj;
+}
+
 bool
 MovieClip::loadMovie(const URL& url, const std::string* postdata)
 {

=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h       2009-05-25 12:34:53 +0000
+++ b/libcore/MovieClip.h       2009-06-02 07:58:24 +0000
@@ -128,6 +128,29 @@
 
     virtual ~MovieClip();
 
+    /// Add a child DisplayObject at the next suitable index (AS2: depth).
+    //
+    /// TODO: should be a function of DisplayObjectContainer
+    /// This is the implementation of the AS3-only method
+    /// DisplayObjectContainer.addChild(), but can also be used for
+    /// AS2.
+    //
+    /// @param obj      The DisplayObject to add.
+    /// @return         The added DisplayObject (reflects the AS return)
+    virtual DisplayObject* addChild(DisplayObject* obj);
+
+    /// Add a child DisplayObject at the specified index (AS2: depth).
+    //
+    /// TODO: should be a function of DisplayObjectContainer
+    /// This is the implementation of the AS3-only method
+    /// DisplayObjectContainer.addChild(), but can also be used for
+    /// AS2.
+    //
+    /// @param obj      The DisplayObject to add.
+    /// @param index    The index (depth) at which to add the DisplayObject.
+    /// @return         The added DisplayObject (reflects the AS return)
+    virtual DisplayObject* addChildAt(DisplayObject* obj, int index);
+
     // Return the originating SWF
     virtual Movie* get_root() const;
 

=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp    2009-05-25 17:31:02 +0000
+++ b/libcore/movie_root.cpp    2009-06-02 07:58:24 +0000
@@ -115,7 +115,6 @@
        m_time_remainder(0.0f),
        m_drag_state(),
        _movies(),
-       _childs(),
        _rootMovie(),
        _invalidated(true),
        _disableScripts(false),
@@ -491,9 +490,6 @@
        // wipe out all levels
        _movies.clear();
 
-       // wipe out all childs
-       _childs.clear();
-
        // remove all intervals
        clearIntervalTimers();
 
@@ -1140,18 +1136,6 @@
 
        }
 
-       for (Childs::iterator i=_childs.begin(), e=_childs.end(); i!=e; ++i)
-       {
-               DisplayObject* ch = i->second;
-
-               ch->clear_invalidated();
-
-               if (ch->visible() == false) continue;
-
-               ch->display();
-
-       }
-
        render::end_display();
 }
 
@@ -1566,10 +1550,6 @@
                i->second->add_invalidated_bounds(ranges, force);
        }
 
-       for (Childs::reverse_iterator i=_childs.rbegin(), e=_childs.rend(); 
i!=e; ++i)
-       {
-               i->second->add_invalidated_bounds(ranges, force);
-       }
 }
 
 
@@ -1818,13 +1798,6 @@
         i->second->setReachable();
     }
 
-    // Mark childs as reachable
-    for (Childs::const_reverse_iterator i=_childs.rbegin(), e=_childs.rend();
-            i!=e; ++i)
-    {
-        i->second->setReachable();
-    }
-
     // Mark original top-level movie
     // This should always be in _movies, but better make sure
     if ( _rootMovie ) _rootMovie->setReachable();
@@ -1897,13 +1870,6 @@
 movie_root::getTopmostMouseEntity(boost::int32_t x, boost::int32_t y) const
 {
 
-       for (Childs::const_reverse_iterator i=_childs.rbegin(), 
e=_childs.rend();
-            i != e; ++i)
-       {
-               InteractiveObject* ret = i->second->topmostMouseEntity(x, y);
-               if (ret) return ret;
-       }
-
        for (Levels::const_reverse_iterator i=_movies.rbegin(), 
e=_movies.rend();
             i != e; ++i)
        {
@@ -1918,12 +1884,6 @@
 movie_root::findDropTarget(boost::int32_t x, boost::int32_t y,
         DisplayObject* dragging) const
 {
-       for (Childs::const_reverse_iterator i=_childs.rbegin(), 
e=_childs.rend();
-            i!=e; ++i) {
-
-               const DisplayObject* ret = i->second->findDropTarget(x, y, 
dragging);
-               if ( ret ) return ret;
-       }
 
     for (Levels::const_reverse_iterator i=_movies.rbegin(), e=_movies.rend();
             i!=e; ++i) {
@@ -1960,11 +1920,6 @@
     //       in local display lists must happen at the *end* of global action
     //       queue processing.
     //
-    for (Childs::reverse_iterator i=_childs.rbegin(), e=_childs.rend(); i!=e; 
++i)
-    {
-        MovieClip* mc = dynamic_cast<MovieClip*>(i->second);
-        if ( mc ) mc->cleanupDisplayList();
-    }
     for (Levels::reverse_iterator i=_movies.rbegin(), e=_movies.rend(); i!=e; 
++i)
     {
         i->second->cleanupDisplayList();
@@ -2469,65 +2424,15 @@
 void
 movie_root::addChild(DisplayObject* ch)
 {
-    int newDepth = _childs.empty() ? 0 : 
-        _childs.rbegin()->second->get_depth()+1;
-    
-    ch->set_depth(newDepth);
-
-    assert(!_childs[newDepth]);
-
-    _childs[newDepth] = ch;
-
-    ch->set_invalidated();
-
-       /// Notify placement 
-       ch->stagePlacementCallback();
+    setInvalidated();
+    _rootMovie->addChild(ch);
 }
 
 void
 movie_root::addChildAt(DisplayObject* ch, int depth)
 {
     setInvalidated();
-
-    // If this DisplayObject already exist
-    // as a child, drop it first.
-       Childs::iterator existing = _childs.begin();
-    for (Childs::iterator end=_childs.end(); existing!=end; ++existing)
-    {
-        if ( existing->second == ch )
-        {
-            log_debug("Character %s found as child %d",
-                ch->getTarget(), existing->first);
-            _childs.erase(existing);
-            break;
-        }
-    }
-
-    ch->set_depth(depth);
-
-       Childs::iterator it = _childs.find(depth);
-       if ( it == _childs.end() ) {
-        _childs[depth] = ch;
-    } else {
-        if ( it->second == ch )
-        {
-            log_debug("Character %s already the child at depth %d",
-                ch->getTarget(), depth);
-        }
-        // don't leak overloaded childs
-        it->second->destroy();
-        it->second = ch;
-    }
-
-    if ( existing == _childs.end() )
-    {
-        ch->set_invalidated();
-
-        /// Notify placement 
-        ch->stagePlacementCallback();
-    }
-
-       assert(testInvariant());
+    _rootMovie->addChildAt(ch, depth);
 }
 
 } // namespace gnash


reply via email to

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