gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/as_value.cpp server/as_v...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/as_value.cpp server/as_v...
Date: Thu, 04 Oct 2007 15:32:11 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/10/04 15:32:11

Modified files:
        .              : ChangeLog 
        server         : as_value.cpp as_value.h 

Log message:
                * server/as_value.{cpp,h}: use a new SpriteProxy class for
                  doing all the soft-reference things. This will now be a flavor
                  of the boost::variant. Advantage of this is we won't keep 
alive
                  destroyed sprites only because we need their original path for
                  rebinding.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.4525&r2=1.4526
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.cpp?cvsroot=gnash&r1=1.83&r2=1.84
http://cvs.savannah.gnu.org/viewcvs/gnash/server/as_value.h?cvsroot=gnash&r1=1.68&r2=1.69

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.4525
retrieving revision 1.4526
diff -u -b -r1.4525 -r1.4526
--- ChangeLog   4 Oct 2007 12:32:34 -0000       1.4525
+++ ChangeLog   4 Oct 2007 15:32:10 -0000       1.4526
@@ -1,5 +1,13 @@
 2007-10-04 Sandro Santilli <address@hidden>
 
+       * server/as_value.{cpp,h}: use a new SpriteProxy class for 
+         doing all the soft-reference things. This will now be a flavor
+         of the boost::variant. Advantage of this is we won't keep alive
+         destroyed sprites only because we need their original path for
+         rebinding.
+
+2007-10-04 Sandro Santilli <address@hidden>
+
        * autogen.sh: reccommend installing libltdl3-dev when libtoolize
          fails.
 

Index: server/as_value.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.cpp,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -b -r1.83 -r1.84
--- server/as_value.cpp 4 Oct 2007 12:16:49 -0000       1.83
+++ server/as_value.cpp 4 Oct 2007 15:32:11 -0000       1.84
@@ -79,9 +79,7 @@
 
                case MOVIECLIP:
                {
-                        sprite_instance* sp = getSprite();
-                        assert(sp); // or return as in to_sprite() ?
-                        return sp->getTarget();
+                       return getSpriteProxy().getTarget();
                }
 
                case NUMBER:
@@ -486,56 +484,20 @@
        }
 }
 
-/* static private */
-sprite_instance*
-as_value::find_sprite_by_target(const std::string& tgtstr)
-{
-       // Evaluate target everytime an attempt is made 
-       // to fetch a movieclip value.
-       sprite_instance* root = VM::get().getRoot().get_root_movie();
-       as_environment& env = root->get_environment();
-       character* target = env.find_target(tgtstr);
-       if ( ! target ) return NULL;
-       return target->to_movie();
-}
-
 sprite_instance*
 as_value::to_sprite() const
 {
        if ( m_type != MOVIECLIP ) return NULL;
 
-       sprite_instance* sp = getSprite();
-       if ( ! sp ) return NULL; // shoudl we assert(sp) instead ?
-
-       if ( sp->isDestroyed() )
-       // TODO: we should also check if the unload event handlers have been 
invoked or not, or references to 'this' in unload handlers will be bogus !
-       {
-               log_debug(_("MovieClip value is a dangling reference: "
-                               "target %s was unloaded (looking for a 
substitute on the same target))"),
-                               sp->getTarget().c_str());
-               sp = find_sprite_by_target(sp->getOrigTarget());
-               return sp;
-               //return NULL;
-       }
-       return sp;
+       return getSprite();
 }
 
 void
-as_value::set_sprite(const sprite_instance& sprite)
+as_value::set_sprite(sprite_instance& sprite)
 {
        drop_refs();
        m_type = MOVIECLIP;
-       _value = 
boost::intrusive_ptr<as_object>(const_cast<sprite_instance*>(&sprite));
-}
-
-void
-as_value::set_sprite(const std::string& path)
-{
-       drop_refs();
-       m_type = MOVIECLIP;
-       sprite_instance* sp = find_sprite_by_target(path);
-       if ( ! sp ) set_null();
-       else set_sprite(*sp);
+       _value = SpriteProxy(&sprite);
 }
 
 // Return value as an ActionScript function.  Returns NULL if value is
@@ -917,10 +879,15 @@
                }
                case MOVIECLIP:
                {
-                       sprite_instance* sp = getSprite();
-                       assert(sp); // will change in case we'll have better 
management :)
-                       //snprintf(buf, 511, "[%smovieclip(%s):%p]", 
sp->isUnloaded() ? "dangling " : "", sp->getOrigTarget().c_str(), (void *)sp);
-                       snprintf(buf, 511, "[%smovieclip(%s):%p]", 
sp->isDestroyed() ? "dangling " : "", sp->getOrigTarget().c_str(), (void *)sp);
+                       const SpriteProxy& sp = getSpriteProxy();
+                       if ( sp.isDangling() )
+                       {
+                               snprintf(buf, 511, "[dangling movieclip:%s]", 
sp.getTarget().c_str());
+                       }
+                       else
+                       {
+                               snprintf(buf, 511, "[movieclip(%s):%p]", 
sp.getTarget().c_str(), (void *)sp.get());
+                       }
                        buf[511] = '\0';
                        return buf;
                }
@@ -1133,7 +1100,7 @@
                        break;
 
                case MOVIECLIP:
-                       getSprite()->setReachable();
+                       getSpriteProxy().setReachable();
                        break;
 
                default: break;
@@ -1155,12 +1122,18 @@
        return boost::get<AsObjPtr>(_value);
 }
 
+as_value::SpriteProxy
+as_value::getSpriteProxy() const
+{
+       assert(m_type == MOVIECLIP);
+       return boost::get<SpriteProxy>(_value);
+}
+
 as_value::SpritePtr
 as_value::getSprite() const
 {
        assert(m_type == MOVIECLIP);
-       //return boost::get<SpritePtr>(_value);
-       return boost::get<AsObjPtr>(_value)->to_movie();
+       return boost::get<SpriteProxy>(_value).get();
 }
 
 void
@@ -1274,6 +1247,48 @@
        set_as_object(obj);
 }
 
+//-------------------------------------
+// as_value::SpriteProxy
+//-------------------------------------
+
+/* static private */
+sprite_instance*
+as_value::SpriteProxy::find_sprite_by_target(const std::string& tgtstr)
+{
+       if ( tgtstr.empty() ) return NULL;
+
+       sprite_instance* root = VM::get().getRoot().get_root_movie();
+       as_environment& env = root->get_environment();
+       character* target = env.find_target(tgtstr);
+       if ( ! target ) return NULL;
+       return target->to_movie();
+}
+
+void
+as_value::SpriteProxy::checkDangling() const
+{
+       if ( _ptr && _ptr->isDestroyed() ) 
+       {
+               _tgt = _ptr->getOrigTarget();
+               _ptr = 0;
+       }
+}
+
+std::string
+as_value::SpriteProxy::getTarget() const
+{
+       checkDangling(); // set _ptr to NULL and _tgt to original target if 
destroyed
+       if ( _ptr ) return _ptr->getTarget();
+       else return _tgt;
+}
+
+void
+as_value::SpriteProxy::setReachable() const
+{
+       checkDangling();
+       if ( _ptr ) _ptr->setReachable();
+}
+
 } // namespace gnash
 
 

Index: server/as_value.h
===================================================================
RCS file: /sources/gnash/gnash/server/as_value.h,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -b -r1.68 -r1.69
--- server/as_value.h   3 Oct 2007 21:20:07 -0000       1.68
+++ server/as_value.h   4 Oct 2007 15:32:11 -0000       1.69
@@ -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: as_value.h,v 1.68 2007/10/03 21:20:07 strk Exp $ */
+/* $Id: as_value.h,v 1.69 2007/10/04 15:32:11 strk Exp $ */
 
 #ifndef GNASH_AS_VALUE_H
 #define GNASH_AS_VALUE_H
@@ -411,7 +411,7 @@
 
        void    set_bool(bool val);
 
-       void    set_sprite(const sprite_instance& sp);
+       void    set_sprite(sprite_instance& sp);
 
        void    set_int(int val) { set_double(val); }
 
@@ -509,10 +509,112 @@
 
 private:
 
+       /// A proxy for sprite pointers.
+       //
+       /// The proxy will store a pointer to a sprite_instance until the 
+       /// sprite is destroyed, in which case it will only store the original
+       /// target path of it and always use that for rebinding when needed.
+       ///
+       class SpriteProxy {
+
+               mutable sprite_instance* _ptr;
+
+               mutable std::string _tgt;
+
        static sprite_instance* find_sprite_by_target(const std::string& 
target);
 
-       void    set_sprite(const std::string& path);
+               /// If we still have a sprite pointer check if it was destroyed
+               /// in which case we drop the pointer and only keep the target.
+               void checkDangling() const;
+
+       public:
+
+               /// Construct a SpriteProxy pointing to the given sprite
+               SpriteProxy(sprite_instance* sp)
+                       :
+                       _ptr(sp)
+               {
+                       checkDangling();
+               }
+
+               /// Construct a copy of the given SpriteProxy 
+               //
+               /// @param sp
+               ///     The SpriteProxy to make a copy of.
+               ///     NOTE: if the given proxy is dangling, this proxy
+               ///           will also be dangling. If you want to 
+               ///           create a non-dangling proxy you can
+               ///           use the constructor taking a sprite_instance
+               ///           as in SpriteProxy newProxy(oldProxy.get())
+               ///
+               SpriteProxy(const SpriteProxy& sp)
+               {
+                       sp.checkDangling();
+                       _ptr=sp._ptr;
+                       if ( ! _ptr ) _tgt=sp._tgt;
+               }
 
+               /// Make this proxy a copy of the given one
+               //
+               /// @param sp
+               ///     The SpriteProxy to make a copy of.
+               ///     NOTE: if the given proxy is dangling, this proxy
+               ///           will also be dangling. If you want to 
+               ///           create a non-dangling proxy you can
+               ///           use the constructor taking a sprite_instance
+               ///           as in SpriteProxy newProxy(oldProxy.get())
+               ///
+               SpriteProxy& operator=(const SpriteProxy& sp)
+               {
+                       sp.checkDangling();
+                       _ptr=sp._ptr;
+                       if ( ! _ptr ) _tgt=sp._tgt;
+                       return *this;
+               }
+
+               /// Get the pointed sprite, either original or rebound
+               //
+               /// @return the currently bound sprite, NULL if none
+               ///
+               sprite_instance* get() const
+               {
+                       checkDangling(); // set _ptr to NULL and _tgt to 
original target if destroyed
+                       if ( _ptr ) return _ptr;
+                       else return find_sprite_by_target(_tgt);
+               }
+
+               /// Get the sprite target, either current (if not dangling) or 
bounded-to one.
+               std::string getTarget() const;
+
+               /// Return true if this sprite is dangling
+               //
+               /// Dangling means that it doesn't have a pointer to the 
original
+               /// sprite anymore, not that it doesn't point to anything.
+               /// To know if it points to something or not use get(), which 
will
+               /// return NULL if it doesn't point to anyhing.
+               ///
+               bool isDangling() const
+               {
+                       checkDangling();
+                       return !_ptr;
+               }
+
+               /// \brief
+               /// Two sprite_proxies are equal if they point to the
+               /// same sprite
+               ///
+               bool operator==(const SpriteProxy& sp) const
+               {
+                       return get() == sp.get();
+               }
+
+               /// Set the original sprite (if any) as reachable
+               //
+               /// NOTE: if this value is dangling, we won't keep anything
+               ///       alive.
+               ///
+               void setReachable() const;
+       };
 
        /// Compare values of the same type
        //
@@ -539,7 +641,7 @@
                          bool,         // BOOLEAN
                          AsObjPtr,     // OBJECT,
 //                        AsFuncPtr,   // AS_FUNCTION
-//                        SpritePtr,   // MOVIECLIP
+                         SpriteProxy,  // MOVIECLIP
                         std::string    // STRING 
                       > _value;
 
@@ -551,8 +653,15 @@
        AsObjPtr getObj() const;
 
        /// Get the sprite pointer variant member (we assume m_type == 
MOVIECLIP)
+       //
+       /// NOTE: this is possibly NULL !
+       ///
        SpritePtr getSprite() const;
 
+       /// Get the sprite proxy variant member (we assume m_type == MOVIECLIP)
+       //
+       SpriteProxy getSpriteProxy() const;
+
        /// Get the number variant member (we assume m_type == NUMBER)
        double getNum() const
        {




reply via email to

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