[Top][All Lists]
[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
{