[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r12225: Move DisplayObject construct
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r12225: Move DisplayObject construction out of DisplayList to avoid passing |
Date: |
Sun, 06 Jun 2010 09:33:08 +0200 |
User-agent: |
Bazaar (2.0.3) |
------------------------------------------------------------
revno: 12225 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Sun 2010-06-06 09:33:08 +0200
message:
Move DisplayObject construction out of DisplayList to avoid passing
the init object around. This commit has various intermediate changes to
construction by separating stage placement and construction, but in the
end united them again under the DisplayObject::construct() function.
Test and correct construction of exported Buttons (test requires ming 0.4.4).
Change font file and misc-ming.all/TextSnapshotTest.c to work with ming CVS
after changes to the handling of kerning values as well as older versions
of ming.
modified:
libcore/Bitmap.cpp
libcore/Bitmap.h
libcore/Button.cpp
libcore/Button.h
libcore/DisplayList.cpp
libcore/DisplayList.h
libcore/DisplayObject.h
libcore/MovieClip.cpp
libcore/MovieClip.h
libcore/MovieLoader.cpp
libcore/SWFMovie.cpp
libcore/SWFMovie.h
libcore/Video.cpp
libcore/Video.h
libcore/movie_root.cpp
libcore/parser/BitmapMovieDefinition.h
testsuite/media/Bitstream-Vera-Sans.fdb
testsuite/misc-ming.all/TextSnapshotTest.c
testsuite/misc-ming.all/attachMovieTest.c
testsuite/misc-ming.all/attachMovieTestRunner.cpp
testsuite/misc-ming.all/duplicate_movie_clip_test.c
=== modified file 'libcore/Bitmap.cpp'
--- a/libcore/Bitmap.cpp 2010-03-11 01:47:08 +0000
+++ b/libcore/Bitmap.cpp 2010-06-03 17:32:50 +0000
@@ -66,9 +66,8 @@
}
void
-Bitmap::stagePlacementCallback(as_object* initObj)
+Bitmap::construct(as_object* /*init*/)
{
- assert(!initObj);
if (_bitmapData) _bitmapData->registerBitmap(this);
update();
}
=== modified file 'libcore/Bitmap.h'
--- a/libcore/Bitmap.h 2010-03-12 15:42:07 +0000
+++ b/libcore/Bitmap.h 2010-06-03 17:32:50 +0000
@@ -71,7 +71,7 @@
virtual bool pointInShape(boost::int32_t x, boost::int32_t y) const;
- virtual void stagePlacementCallback(as_object* initObj = 0);
+ virtual void construct(as_object* init);
protected:
=== modified file 'libcore/Button.cpp'
--- a/libcore/Button.cpp 2010-05-07 08:01:02 +0000
+++ b/libcore/Button.cpp 2010-06-04 07:52:37 +0000
@@ -710,7 +710,7 @@
set_invalidated();
_stateCharacters[i] = ch;
addInstanceProperty(*this, ch);
- ch->stagePlacementCallback();
+ ch->construct();
}
}
}
@@ -779,14 +779,16 @@
}
void
-Button::stagePlacementCallback(as_object* initObj)
+Button::construct(as_object* initObj)
{
-
- // Not sure how this can happen, but blip.tv does it.
+ // This can happen if attachMovie is called with an exported Button and
+ // an init object. The attachment happens, but the init object is not used
+ // (see misc-ming.all/attachMovieTest.swf).
if (initObj) {
- log_unimpl("Button placed with an initObj. How did this happen? "
- "We'll copy the properties anyway");
- getObject(this)->copyProperties(*initObj);
+ IF_VERBOSE_ASCODING_ERRORS(
+ log_aserror("Button placed with an init object. This will "
+ "be ignored.");
+ );
}
saveOriginalTarget(); // for soft refs
@@ -826,7 +828,7 @@
_stateCharacters[rno] = ch;
addInstanceProperty(*this, ch);
- ch->stagePlacementCallback(); // give this DisplayObject a life
+ ch->construct();
}
// There is no INITIALIZE/CONSTRUCT/LOAD/ENTERFRAME/UNLOAD event
=== modified file 'libcore/Button.h'
--- a/libcore/Button.h 2010-03-11 01:47:08 +0000
+++ b/libcore/Button.h 2010-06-03 17:32:50 +0000
@@ -115,21 +115,14 @@
bool isEnabled();
- /// Receive a stage placement notification
- //
- /// This callback will:
- ///
- /// (1) Register this button instance as a live DisplayObject
- /// (2) Setup the state DisplayObjects calling stagePlacementCallback
- /// on all [WRONG]
- virtual void stagePlacementCallback(as_object* initObj = 0);
-
/// Properly unload contained DisplayObjects
bool unload();
/// Properly destroy contained DisplayObjects
void destroy();
+ virtual void construct(as_object* initObj);
+
#ifdef USE_SWFTREE
// Override to append button DisplayObjects info, see dox in
DisplayObject.h
virtual InfoTree::iterator getMovieInfo(InfoTree& tr,
=== modified file 'libcore/DisplayList.cpp'
--- a/libcore/DisplayList.cpp 2010-05-27 11:01:11 +0000
+++ b/libcore/DisplayList.cpp 2010-06-03 17:32:50 +0000
@@ -208,8 +208,7 @@
}
void
-DisplayList::placeDisplayObject(DisplayObject* ch, int depth,
- as_object* initObj)
+DisplayList::placeDisplayObject(DisplayObject* ch, int depth)
{
assert(!ch->unloaded());
ch->set_invalidated();
@@ -244,9 +243,6 @@
ch->extend_invalidated_bounds(old_ranges);
}
- // Give life to this instance
- ch->stagePlacementCallback(initObj);
-
testInvariant();
}
@@ -327,9 +323,6 @@
}
- // Give life to this instance
- ch->stagePlacementCallback();
-
testInvariant();
}
@@ -545,9 +538,6 @@
++index, ++it;
}
- // Give life to this instance
- obj->stagePlacementCallback();
-
testInvariant();
}
@@ -576,9 +566,6 @@
// Insert the DisplayObject at the end
_charsByDepth.insert(_charsByDepth.end(), obj);
- // Give life to this instance
- obj->stagePlacementCallback();
-
testInvariant();
}
@@ -684,7 +671,7 @@
// Don't display dynamic masks
if (ch->isDynamicMask()) continue;
- assert(! ch->unloaded() ); // we don't advance unloaded chars
+ assert(!ch->unloaded()); // we don't advance unloaded chars
// Check if this charater or any of its parents is a mask.
// Characters acting as masks should always be rendered to the
=== modified file 'libcore/DisplayList.h'
--- a/libcore/DisplayList.h 2010-03-12 23:35:54 +0000
+++ b/libcore/DisplayList.h 2010-06-03 17:32:50 +0000
@@ -90,11 +90,7 @@
///
/// @param depth
/// depth at which the new DisplayObject is placed.
- ///
- /// @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);
/// \brief
/// Replace the old DisplayObject at the specified depth with
=== modified file 'libcore/DisplayObject.h'
--- a/libcore/DisplayObject.h 2010-03-14 04:51:25 +0000
+++ b/libcore/DisplayObject.h 2010-06-03 17:32:50 +0000
@@ -789,7 +789,8 @@
/// If you override the method remember to call saveOriginalTarget()
/// as the first thing.
///
- virtual void stagePlacementCallback(as_object* = 0)
+ /// This handles all ActionScript construction and initialization events.
+ virtual void construct(as_object* /*init*/ = 0)
{
saveOriginalTarget();
}
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2010-05-27 11:01:27 +0000
+++ b/libcore/MovieClip.cpp 2010-06-03 17:32:50 +0000
@@ -552,7 +552,8 @@
// TODO: only call set_invalidated if this DisplayObject actually overrides
// an existing one !
set_invalidated();
- _displayList.placeDisplayObject(obj, depth);
+ _displayList.placeDisplayObject(obj, depth);
+ obj->construct();
return obj;
}
@@ -594,8 +595,8 @@
newmovieclip->set_ratio(get_ratio());
newmovieclip->set_clip_depth(get_clip_depth());
- parent->_displayList.placeDisplayObject(newmovieclip, depth,
- initObject);
+ parent->_displayList.placeDisplayObject(newmovieclip, depth);
+ newmovieclip->construct(initObject);
return newmovieclip;
}
@@ -1131,10 +1132,10 @@
}
bool
-MovieClip::attachCharacter(DisplayObject& newch, int depth,
- as_object* initObject)
+MovieClip::attachCharacter(DisplayObject& newch, int depth, as_object* initObj)
{
- _displayList.placeDisplayObject(&newch, depth, initObject);
+ _displayList.placeDisplayObject(&newch, depth);
+ newch.construct(initObj);
// FIXME: check return from placeDisplayObject above ?
return true;
@@ -1202,6 +1203,7 @@
ch->set_clip_depth(tag->getClipDepth());
dlist.placeDisplayObject(ch, tag->getDepth());
+ ch->construct();
return ch;
}
@@ -1276,6 +1278,7 @@
// use SWFMatrix from the old DisplayObject if tag doesn't provide one.
dlist.replaceDisplayObject(ch, tag->getDepth(),
!tag->hasCxform(), !tag->hasMatrix());
+ ch->construct();
}
void
@@ -1287,15 +1290,6 @@
}
void
-MovieClip::replace_display_object(DisplayObject* ch, int depth,
- bool use_old_cxform, bool use_old_matrix)
-{
- assert(ch);
- _displayList.replaceDisplayObject(ch, depth,
- use_old_cxform, use_old_matrix);
-}
-
-void
MovieClip::increment_frame_and_check_for_loop()
{
const size_t frame_count = get_loaded_frames();
@@ -1730,14 +1724,53 @@
stage().add_mouse_listener(this);
}
-
-// WARNING: THIS SNIPPET NEEDS THE CHARACTER TO BE "INSTANTIATED", that is,
-// its target path needs to exist, or any as_value for it will be
-// a dangling reference to an unexistent movieclip !
-// NOTE: this is just due to the wrong steps, see comment in header
-void
-MovieClip::stagePlacementCallback(as_object* initObj)
-{
+void
+MovieClip::constructAsScriptObject()
+{
+ as_object* mc = getObject(this);
+
+ // A MovieClip should always have an associated object.
+ assert(mc);
+
+ if (!isAS3(getVM(*mc)) && !get_parent()) {
+ mc->init_member("$version", getVM(*mc).getPlayerVersion(), 0);
+ }
+
+ const sprite_definition* def =
+ dynamic_cast<const sprite_definition*>(_def.get());
+
+ // We won't "construct" top-level movies
+ as_function* ctor = def ? def->getRegisteredClass() : 0;
+
+#ifdef GNASH_DEBUG
+ log_debug(_("Attached movieclips %s registered class is %p"),
+ getTarget(), (void*)ctor);
+#endif
+
+ // Set this MovieClip object to be an instance of the class.
+ if (ctor) {
+ Property* proto = ctor->getOwnProperty(NSV::PROP_PROTOTYPE);
+ if (proto) mc->set_prototype(proto->getValue(*ctor));
+ }
+
+ // Send the construct event. This must be done after the __proto__
+ // member is set. It is always done.
+ notifyEvent(event_id::CONSTRUCT);
+
+ if (ctor) {
+ const int swfversion = getSWFVersion(*mc);
+ if (swfversion > 5) {
+ fn_call::Args args;
+ ctor->construct(*mc, get_environment(), args);
+ }
+ }
+
+}
+
+void
+MovieClip::construct(as_object* initObj)
+{
+
assert(!unloaded());
saveOriginalTarget();
@@ -1748,7 +1781,6 @@
// Register this movieclip as a live one
stage().addLiveChar(this);
-
// Register this movieclip as a core broadcasters listener
registerAsListener();
@@ -1795,6 +1827,11 @@
SWF::ControlTag::TAG_ACTION);
}
+ as_object* mc = getObject(this);
+
+ // A MovieClip should always have an associated object.
+ assert(mc);
+
// We execute events immediately when the stage-placed DisplayObject
// is dynamic, This is becase we assume that this means that
// the DisplayObject is placed during processing of actions (opposed
@@ -1805,14 +1842,12 @@
// Another possibility to inspect could be letting movie_root decide
// when to really queue and when rather to execute immediately the
// events with priority INITIALIZE or CONSTRUCT ...
- if (!isDynamic())
- {
- assert(!initObj);
+ if (!isDynamic()) {
+
#ifdef GNASH_DEBUG
log_debug(_("Queuing INITIALIZE and CONSTRUCT events for movieclip
%s"),
getTarget());
#endif
- queueEvent(event_id::INITIALIZE, movie_root::PRIORITY_INIT);
std::auto_ptr<ExecutableCode> code(new ConstructEvent(this));
stage().pushAction(code, movie_root::PRIORITY_CONSTRUCT);
@@ -1824,61 +1859,18 @@
// after the display list has been populated, so that _height and
// _width (which depend on bounds) are correct.
if (initObj) {
- getObject(this)->copyProperties(*initObj);
- }
-
- constructAsScriptObject();
-
- // Tested in testsuite/swfdec/duplicateMovieclip-events.c and
- // testsuite/swfdec/clone-sprite-events.c not to call notifyEvent
- // immediately.
- queueEvent(event_id::INITIALIZE, movie_root::PRIORITY_INIT);
- }
-
-
-}
-
-
-void
-MovieClip::constructAsScriptObject()
-{
- as_object* mc = getObject(this);
-
- // A MovieClip should always have an associated object.
- assert(mc);
-
- if (!isAS3(getVM(*mc)) && !get_parent()) {
- mc->init_member("$version", getVM(*mc).getPlayerVersion(), 0);
- }
-
- const sprite_definition* def =
- dynamic_cast<const sprite_definition*>(_def.get());
-
- // We won't "construct" top-level movies
- as_function* ctor = def ? def->getRegisteredClass() : 0;
-
-#ifdef GNASH_DEBUG
- log_debug(_("Attached movieclips %s registered class is %p"),
- getTarget(), (void*)ctor);
-#endif
-
- // Set this MovieClip object to be an instance of the class.
- if (ctor) {
- Property* proto = ctor->getOwnProperty(NSV::PROP_PROTOTYPE);
- if (proto) mc->set_prototype(proto->getValue(*ctor));
- }
-
- // Send the construct event. This must be done after the __proto__
- // member is set. It is always done.
- notifyEvent(event_id::CONSTRUCT);
-
- if (ctor) {
- const int swfversion = getSWFVersion(*mc);
- if (swfversion > 5) {
- fn_call::Args args;
- ctor->construct(*mc, get_environment(), args);
- }
- }
+ mc->copyProperties(*initObj);
+ }
+
+ constructAsScriptObject();
+
+ }
+
+ // Tested in testsuite/swfdec/duplicateMovieclip-events.c and
+ // testsuite/swfdec/clone-sprite-events.c not to call notifyEvent
+ // immediately.
+ queueEvent(event_id::INITIALIZE, movie_root::PRIORITY_INIT);
+
}
bool
@@ -1938,9 +1930,9 @@
// DisplayObjectContainer and log an error if it's not.
MovieClip* parent_sp = parent->to_movie();
assert(parent_sp);
- parent_sp->replace_display_object(extern_movie, get_depth(),
- true, true);
-
+ parent_sp->_displayList.replaceDisplayObject(extern_movie, get_depth(),
+ true, true);
+ extern_movie->construct();
}
else
{
=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h 2010-05-06 12:11:30 +0000
+++ b/libcore/MovieClip.h 2010-06-03 17:32:50 +0000
@@ -342,27 +342,6 @@
void remove_display_object(const SWF::PlaceObject2Tag* tag,
DisplayList& dlist);
- /// Proxy of DisplayList::removeDisplayObject()
- ///
- /// @
- /// new DisplayObject to be used for replacing.
- ///
- /// @param depth
- /// depth at which the old DisplayObject is to be replaced.
- ///
- /// @param use_old_cxform
- /// if true, the cxform of the new DisplayObject will be set to the old
one.
- /// if false, the cxform of the new DisplayObject will be untouched.
- ///
- /// @param use_old_matrix
- /// if true, the transformation SWFMatrix of the new DisplayObject
- /// will be set to the old one.
- /// if false, the transformation SWFMatrix of the new DisplayObject will
- /// be untouched.
- void replace_display_object(DisplayObject* ch, int depth,
- bool use_old_cxform, bool use_old_matrix);
-
-
/// \brief
/// Remove the object at the specified depth.
//
@@ -404,8 +383,9 @@
/// The callback will also (known to be bogus):
//
/// (1) Construct this instance as an ActionScript object.
- /// See constructAsScriptObject() method.
- virtual void stagePlacementCallback(as_object* initObj = 0);
+ /// See constructAsScriptObject() method, including constructing
+ /// registered class and adding properties.
+ virtual void construct(as_object* initObj = 0);
/// Unload all contents in the displaylist and this instance
/// See DisplayObject::unload for more info
=== modified file 'libcore/MovieLoader.cpp'
--- a/libcore/MovieLoader.cpp 2010-05-07 08:17:21 +0000
+++ b/libcore/MovieLoader.cpp 2010-06-03 17:32:50 +0000
@@ -319,7 +319,7 @@
// in first frame of loaded clip have been executed.
//
// Since getLoadedMovie or setLevel above will invoke
- // stagePlacementCallback and thus queue all actions in first
+ // construct() and thus queue all actions in first
// frame, we'll queue the
// onLoadInit call next, so it happens after the former.
//
=== modified file 'libcore/SWFMovie.cpp'
--- a/libcore/SWFMovie.cpp 2010-01-11 06:41:38 +0000
+++ b/libcore/SWFMovie.cpp 2010-06-03 17:32:50 +0000
@@ -40,25 +40,23 @@
}
void
-SWFMovie::stagePlacementCallback(as_object* initObj)
+SWFMovie::construct(as_object* /*init*/)
{
- assert (!initObj);
-
- saveOriginalTarget();
-
- // Load first frame (1-based index)
- size_t nextframe = 1;
- if ( !_def->ensure_frame_loaded(nextframe) )
- {
- IF_VERBOSE_MALFORMED_SWF(
- log_swferror("Frame %d never loaded. Total frames: %d",
- nextframe, get_frame_count());
- );
- }
-
- // Invoke parent placement event handler
- MovieClip::stagePlacementCallback();
+ saveOriginalTarget();
+
+ // Load first frame (1-based index)
+ size_t nextframe = 1;
+ if ( !_def->ensure_frame_loaded(nextframe) )
+ {
+ IF_VERBOSE_MALFORMED_SWF(
+ log_swferror("Frame %d never loaded. Total frames: %d",
+ nextframe, get_frame_count());
+ );
+ }
+
+ // Invoke parent placement event handler
+ MovieClip::construct();
}
// Advance of an SWF-defined movie instance
=== modified file 'libcore/SWFMovie.h'
--- a/libcore/SWFMovie.h 2010-03-12 15:42:07 +0000
+++ b/libcore/SWFMovie.h 2010-06-03 17:32:50 +0000
@@ -69,11 +69,10 @@
/// Handle a top-level movie on stage placement.
//
/// This method will just ensure first frame is loaded
- /// and then call MovieClip::stagePlacementCallback.
+ /// and then call MovieClip::construct
///
/// It's intended to be called by movie_root::setLevel().
- ///
- void stagePlacementCallback(as_object* initObj = 0);
+ void construct(as_object* init = 0);
const std::string& url() const {
return _def->get_url();
=== modified file 'libcore/Video.cpp'
--- a/libcore/Video.cpp 2010-03-11 01:47:08 +0000
+++ b/libcore/Video.cpp 2010-06-03 17:32:50 +0000
@@ -239,13 +239,10 @@
}
void
-Video::stagePlacementCallback(as_object* initObj)
+Video::construct(as_object* /*init*/)
{
-
- // A Video cannot be created with an initObj
- assert(!initObj);
-
- saveOriginalTarget(); // for softref
+ // For soft references.
+ saveOriginalTarget();
// Register this video instance as a live DisplayObject
stage().addLiveChar(this);
=== modified file 'libcore/Video.h'
--- a/libcore/Video.h 2010-06-05 09:29:30 +0000
+++ b/libcore/Video.h 2010-06-06 07:33:08 +0000
@@ -67,7 +67,7 @@
virtual void advance();
/// Register this video instance as a live DisplayObject
- virtual void stagePlacementCallback(as_object* initObj = 0);
+ virtual void construct(as_object* init = 0);
void display(Renderer& renderer);
=== modified file 'libcore/movie_root.cpp'
--- a/libcore/movie_root.cpp 2010-06-04 06:55:42 +0000
+++ b/libcore/movie_root.cpp 2010-06-06 07:33:08 +0000
@@ -347,7 +347,7 @@
movie->set_invalidated();
/// Notify placement
- movie->stagePlacementCallback();
+ movie->construct();
assert(testInvariant());
}
=== modified file 'libcore/parser/BitmapMovieDefinition.h'
--- a/libcore/parser/BitmapMovieDefinition.h 2010-03-11 03:47:39 +0000
+++ b/libcore/parser/BitmapMovieDefinition.h 2010-06-03 17:32:50 +0000
@@ -110,7 +110,7 @@
}
// Inheritance from movie_definition requires this.
- // we always return 1 so MovieClip::stagePlacementCallback
+ // we always return 1 so MovieClip::construct()
// doesn't skip our handling (TODO: check if it's correct to
// skip handling of 0-frames movies..).
size_t get_loading_frame() const
=== modified file 'testsuite/media/Bitstream-Vera-Sans.fdb'
Binary files a/testsuite/media/Bitstream-Vera-Sans.fdb 2008-05-16 19:42:07
+0000 and b/testsuite/media/Bitstream-Vera-Sans.fdb 2010-06-05 06:35:58 +0000
differ
=== modified file 'testsuite/misc-ming.all/TextSnapshotTest.c'
--- a/testsuite/misc-ming.all/TextSnapshotTest.c 2010-01-01 17:48:26
+0000
+++ b/testsuite/misc-ming.all/TextSnapshotTest.c 2010-06-05 06:43:53
+0000
@@ -277,12 +277,12 @@
check_equals(mo, "ri2[18].selected", "false");
xcheck_equals(mo, "ri2[50].corner2y", "388.85");
- xcheck_equals(mo, "ri2[50].corner2x", "154.55");
+ xcheck_equals(mo, "ri2[50].corner2x", "156.6");
xcheck_equals(mo, "ri2[51].corner2y", "388.85");
- xcheck_equals(mo, "ri2[51].corner2x", "161.9");
+ xcheck_equals(mo, "ri2[51].corner2x", "163.95");
- check_equals(mo, "ri2[50].matrix_tx", "149.6");
- check_equals(mo, "ri2[51].matrix_tx", "154.5");
+ check_equals(mo, "ri2[50].matrix_tx", "151.65");
+ check_equals(mo, "ri2[51].matrix_tx", "156.55");
add_actions(mo, "ts = this.getTextSnapshot();");
check_equals(mo, "typeof(ts)", "'object'");
=== modified file 'testsuite/misc-ming.all/attachMovieTest.c'
--- a/testsuite/misc-ming.all/attachMovieTest.c 2010-01-01 17:48:26 +0000
+++ b/testsuite/misc-ming.all/attachMovieTest.c 2010-06-06 06:22:40 +0000
@@ -63,6 +63,10 @@
const char *srcdir=".";
SWFMovieClip dejagnuclip;
+ SWFShape sh;
+ SWFButton but;
+ SWFButtonRecord br;
+
/*********************************************
*
@@ -98,6 +102,22 @@
SWFMovie_add(mo, (SWFBlock)dejagnuclip);
addRedSquareExport(mo);
+
+#if MING_VERSION_CODE >= 00040400
+ but = newSWFButton();
+
+ sh = make_fill_square (100, 300, 60, 60, 255, 0, 0, 0, 255, 0);
+ br = SWFButton_addCharacter(but, (SWFCharacter)sh, SWFBUTTON_UP);
+ SWFButtonRecord_setDepth(br, 12);
+
+ sh = make_fill_square (100, 300, 60, 60, 255, 0, 0, 255, 0, 0);
+ br = SWFButton_addCharacter(but, (SWFCharacter)sh, SWFBUTTON_HIT);
+ br = SWFButton_addCharacter(but, (SWFCharacter)sh, SWFBUTTON_OVER);
+ SWFButtonRecord_setDepth(br, 10);
+
+ SWFMovie_addExport(mo, (SWFBlock)but, "butexp");
+ SWFMovie_writeExports(mo);
+#endif
/* it seems we need a SHOWFRAME for this to be effective */
/* (maybe it's related to loop-back handling ?) */
SWFMovie_nextFrame(mo);
@@ -177,6 +197,27 @@
check_equals(mo, "square3._x", "210");
+
+ SWFMovie_nextFrame(mo); /* showFrame */
+
+#if MING_VERSION_CODE >= 00040400
+
+ add_actions(mo,
+ "o = new Object();"
+ "o.f = 56;"
+ "ar = attachMovie('butexp', 'butatt', 5000, o);"
+ "trace(ar);"
+ "trace(butatt);"
+ "ar = attachMovie('redsquare', 'rs', 5001, o);"
+ "ar.t = 34;"
+ "butatt.s = 37;"
+ );
+
+ /* init object is not used for Buttons */
+ check_equals(mo, "butatt.f", "undefined");
+ check_equals(mo, "butatt.t", "undefined");
+ check_equals(mo, "butatt.s", "37");
+#endif
add_actions(mo, "totals(); stop();");
SWFMovie_nextFrame(mo); /* showFrame */
=== modified file 'testsuite/misc-ming.all/attachMovieTestRunner.cpp'
--- a/testsuite/misc-ming.all/attachMovieTestRunner.cpp 2010-01-01 17:48:26
+0000
+++ b/testsuite/misc-ming.all/attachMovieTestRunner.cpp 2010-06-04 08:27:45
+0000
@@ -48,7 +48,7 @@
as_value tmp;
- check_equals(root->get_frame_count(), 5);
+ check_equals(root->get_frame_count(), 6);
check_equals(root->getPlayState(), MovieClip::PLAYSTATE_PLAY);
check_equals(root->get_current_frame(), 0);
=== modified file 'testsuite/misc-ming.all/duplicate_movie_clip_test.c'
--- a/testsuite/misc-ming.all/duplicate_movie_clip_test.c 2010-01-01
17:48:26 +0000
+++ b/testsuite/misc-ming.all/duplicate_movie_clip_test.c 2010-06-04
06:16:08 +0000
@@ -35,6 +35,10 @@
SWFDisplayItem it1, it2;
SWFShape sh_red;
+ /* For the button duplication test */
+ SWFButton but;
+ SWFButtonRecord br;
+
const char *srcdir=".";
if ( argc>1 )
srcdir=argv[1];
@@ -116,7 +120,47 @@
SWFDisplayItem_remove(it1);
SWFDisplayItem_remove(it2);
add_actions(mo, " dup2.removeMovieClip(); ");
+
SWFMovie_nextFrame(mo); /* 4th frame */
+
+ /* Create a button, add it to mc1 */
+ but = newSWFButton();
+ br = SWFButton_addCharacter(but, (SWFCharacter)sh_red, SWFBUTTON_UP);
+ SWFButtonRecord_setDepth(br, 10);
+ it1 = SWFMovie_add(mo, (SWFBlock)but);
+ SWFDisplayItem_setName(it1, "button");
+
+ /* Sanity check */
+ check_equals(mo, "typeof(button)", "'object'");
+
+ add_actions(mo,
+ "trace(button);"
+ "dupl = MovieClip.prototype.duplicateMovieClip;"
+ "button.dupl = dupl;"
+ "o = { x: 4 };"
+ "d = button.dupl('buttdup', 201, o);"
+ );
+
+ xcheck_equals(mo, "typeof(d)", "'object'");
+ xcheck_equals(mo, "'' + _root.buttdup", "'_level0.buttdup'");
+ check_equals(mo, "_root.buttdup", "d");
+
+ /* initobj not used */
+ check_equals(mo, "_root.buttdup.x", "undefined");
+
+ add_actions(mo,
+ "t = new Object();"
+ "t.dupl = dupl;"
+ "o2 = { x: 44 };"
+ "d2 = t.dupl('objdup', 202, o2);"
+ "trace(_root.objdup);"
+ );
+
+ /* Does not work on plain objects */
+ check_equals(mo, "typeof(d2)", "'undefined'");
+ check_equals(mo, "typeof(_root.objdup)", "'undefined'");
+
+ SWFMovie_nextFrame(mo); /* 5th frame */
check_equals(mo, "_root.x1", "2");
check_equals(mo, "_root.x2", "3");
- [Gnash-commit] /srv/bzr/gnash/trunk r12225: Move DisplayObject construction out of DisplayList to avoid passing,
Benjamin Wolsey <=