[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] gnash ChangeLog server/asobj/Sound.cpp server/a...
From: |
Sandro Santilli |
Subject: |
[Gnash-commit] gnash ChangeLog server/asobj/Sound.cpp server/a... |
Date: |
Tue, 17 Jun 2008 12:42:22 +0000 |
CVSROOT: /sources/gnash
Module name: gnash
Changes by: Sandro Santilli <strk> 08/06/17 12:42:22
Modified files:
. : ChangeLog
server/asobj : Sound.cpp Sound.h
testsuite/actionscript.all: Makefile.am
utilities : processor.cpp
Added files:
testsuite/actionscript.all: Sound.as
Log message:
* server/asobj/Sound.{cpp,h}: fix constructor taking
arg; fix getVolume/setVolume to query either global
volume or associated-character-local one; fix visibility
of a few method found to be only available in SWF6+
by the new Sound.as testcase.
* testsuite/actionscript.all: Makefile.am, Sound.as: initial
test for Sound class.
* utilities/processor.cpp: register a NullSoundHandler so we
can query global volume from actionscript.all
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.6957&r2=1.6958
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Sound.cpp?cvsroot=gnash&r1=1.32&r2=1.33
http://cvs.savannah.gnu.org/viewcvs/gnash/server/asobj/Sound.h?cvsroot=gnash&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Makefile.am?cvsroot=gnash&r1=1.96&r2=1.97
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/actionscript.all/Sound.as?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/utilities/processor.cpp?cvsroot=gnash&r1=1.102&r2=1.103
Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.6957
retrieving revision 1.6958
diff -u -b -r1.6957 -r1.6958
--- ChangeLog 17 Jun 2008 12:34:19 -0000 1.6957
+++ ChangeLog 17 Jun 2008 12:42:15 -0000 1.6958
@@ -1,5 +1,17 @@
2008-06-17 Sandro Santilli <address@hidden>
+ * server/asobj/Sound.{cpp,h}: fix constructor taking
+ arg; fix getVolume/setVolume to query either global
+ volume or associated-character-local one; fix visibility
+ of a few method found to be only available in SWF6+
+ by the new Sound.as testcase.
+ * testsuite/actionscript.all: Makefile.am, Sound.as: initial
+ test for Sound class.
+ * utilities/processor.cpp: register a NullSoundHandler so we
+ can query global volume from actionscript.all
+
+2008-06-17 Sandro Santilli <address@hidden>
+
* server/character.{cpp,h}: add interface to get/set volume
of sounds associated to the character, both local and
concatenated one.
Index: server/asobj/Sound.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.cpp,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- server/asobj/Sound.cpp 29 May 2008 12:44:29 -0000 1.32
+++ server/asobj/Sound.cpp 17 Jun 2008 12:42:21 -0000 1.33
@@ -64,14 +64,23 @@
static as_value checkPolicyFile_getset(const fn_call& fn);
static as_object* getSoundInterface();
-Sound::Sound() :
+Sound::Sound()
+ :
as_object(getSoundInterface()),
+ attachedCharacter(0),
soundId(-1),
externalSound(false),
- isStreaming(false)
+ isStreaming(false),
+ _soundHandler(get_sound_handler())
{
}
+void
+Sound::attachCharacter(character* attachTo)
+{
+ attachedCharacter.reset(new CharacterProxy(attachTo));
+}
+
Sound::~Sound()
{
}
@@ -128,16 +137,50 @@
}
}
-int
-Sound::getVolume()
+bool
+Sound::getVolume(int& volume)
{
- int volume = 0;
- media::sound_handler* s = get_sound_handler();
- if (s != NULL)
+ // TODO: check what takes precedence in case we
+ // have both an attached character *and*
+ // some other sound...
+ //
+ if ( attachedCharacter )
+ {
+ log_debug("Sound has an attached character");
+ character* ch = attachedCharacter->get();
+ if ( ! ch )
+ {
+ log_debug("Character attached to Sound was unloaded and couldn't
rebind");
+ return false;
+ }
+ volume = ch->getVolume();
+ return true;
+ }
+ else log_debug("Sound has NO attached character, _soundHandler is %p,
soundId is %d", _soundHandler, soundId);
+
+ // If we're not attached to a character we'll need to query
+ // sound_handler for volume. If we have no sound handler, we
+ // can't do much, so we'll return false
+ if (!_soundHandler)
+ {
+ log_debug("We have no sound handler here...");
+ return false;
+ }
+
+ // Now, we may be controlling a specific sound or
+ // the final output as a whole.
+ // If soundId is -1 we're controlling as a whole
+ //
+ if ( soundId == -1 )
+ {
+ volume = _soundHandler->getFinalVolume();
+ }
+ else
{
- volume = s->get_volume(soundId);
+ volume = _soundHandler->get_volume(soundId);
}
- return volume;
+
+ return true;
}
void
@@ -180,36 +223,76 @@
void
Sound::setVolume(int volume)
{
- // sanity check
- if (volume >= 0 && volume <=100)
+ // TODO: check what takes precedence in case we
+ // have both an attached character *and*
+ // some other sound...
+ //
+ if ( attachedCharacter )
+ {
+ character* ch = attachedCharacter->get();
+ if ( ! ch )
+ {
+ log_debug("Character attached to Sound was unloaded and couldn't
rebind");
+ return;
+ }
+ ch->setVolume(volume);
+ return;
+ }
+
+ // If we're not attached to a character we'll need to use
+ // sound_handler for volume. If we have no sound handler, we
+ // can't do much, so we'll just return
+ if (!_soundHandler)
{
- media::sound_handler* s = get_sound_handler();
- if (s != NULL)
+ return;
+ }
+
+ // Now, we may be controlling a specific sound or
+ // the final output as a whole.
+ // If soundId is -1 we're controlling as a whole
+ //
+ if ( soundId == -1 )
{
- s->set_volume(soundId, volume);
+ _soundHandler->setFinalVolume(volume);
}
+ else
+ {
+ _soundHandler->set_volume(soundId, volume);
}
}
void
Sound::start(int offset, int loops)
{
- media::sound_handler* s = get_sound_handler();
- if (s) s->play_sound(soundId, loops, offset, 0, NULL);
+ if ( soundId == -1 )
+ {
+ // FIXME: find out what to do here
+ log_error("Sound.start() called against a Sound that has no sound
handle attached");
+ return;
+ }
+ if (_soundHandler)
+ {
+ _soundHandler->play_sound(soundId, loops, offset, 0, NULL);
+ }
}
void
Sound::stop(int si)
{
+ if ( soundId == -1 )
+ {
+ // FIXME: find out what to do here
+ log_error("Sound.stop() called against a Sound that has no sound
handle attached");
+ return;
+ }
- media::sound_handler* s = get_sound_handler();
- if (s != NULL)
+ if (_soundHandler)
{
if (si > -1) {
- s->stop_sound(soundId);
+ _soundHandler->stop_sound(soundId);
} else {
- s->stop_sound(si);
+ _soundHandler->stop_sound(si);
}
}
}
@@ -240,7 +323,7 @@
as_value
-sound_new(const fn_call& /* fn */)
+sound_new(const fn_call& fn)
{
Sound* sound_obj;
@@ -253,6 +336,36 @@
#else
sound_obj = new Sound();
#endif
+
+ if ( fn.nargs )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ if ( fn.nargs > 1 )
+ {
+ std::stringstream ss; fn.dump_args(ss);
+ log_aserror("new Sound(%d) : args after first one ignored",
ss.str());
+ }
+ );
+
+ as_value& arg0 = fn.arg(0);
+ if ( ! arg0.is_null() && ! arg0.is_undefined() )
+ {
+ as_object* obj = arg0.to_object().get();
+ character* ch = obj ? obj->to_character() : 0;
+ IF_VERBOSE_ASCODING_ERRORS(
+ if ( ! ch )
+ {
+ std::stringstream ss; fn.dump_args(ss);
+ log_aserror("new Sound(%s) : first argument isn't null "
+ "nor undefined, and doesn't cast to a character. "
+ "We'll take as an invalid character ref.",
+ ss.str());
+ }
+ );
+ sound_obj->attachCharacter(ch);
+ }
+ }
+
return as_value(sound_obj);
}
@@ -396,7 +509,7 @@
as_value
sound_getpan(const fn_call& /*fn*/)
{
- LOG_ONCE( log_unimpl ("Sound.getDuration()") );
+ LOG_ONCE( log_unimpl ("Sound.getPan()") );
return as_value();
}
@@ -441,10 +554,17 @@
boost::intrusive_ptr<Sound> so = ensureType<Sound>(fn.this_ptr);
- int volume = so->getVolume();
-
- return as_value(volume);
+ if ( fn.nargs )
+ {
+ IF_VERBOSE_ASCODING_ERRORS(
+ std::stringstream ss; fn.dump_args(ss);
+ log_aserror("Sound.getVolume(%s) : arguments ignored");
+ );
+ }
+ int volume;
+ if ( so->getVolume(volume) ) return as_value(volume);
+ return as_value();
}
as_value
@@ -537,15 +657,10 @@
int fl_hpc =
as_prop_flags::dontEnum|as_prop_flags::dontDelete|as_prop_flags::readOnly;
o.init_member("attachSound", new builtin_function(sound_attachsound),
fl_hpc);
- o.init_member("getDuration", new builtin_function(sound_getDuration),
fl_hpc);
- o.init_member("setDuration", new builtin_function(sound_setDuration),
fl_hpc);
o.init_member("getPan", new builtin_function(sound_getpan), fl_hpc);
o.init_member("setPan", new builtin_function(sound_setpan), fl_hpc);
- o.init_member("loadSound", new builtin_function(sound_loadsound),
fl_hpc);
o.init_member("start", new builtin_function(sound_start), fl_hpc);
o.init_member("stop", new builtin_function(sound_stop), fl_hpc);
- o.init_member("getPosition", new builtin_function(sound_getPosition),
fl_hpc);
- o.init_member("setPosition", new builtin_function(sound_setPosition),
fl_hpc);
o.init_member("getTransform", new builtin_function(sound_gettransform),
fl_hpc);
o.init_member("setTransform", new builtin_function(sound_settransform),
fl_hpc);
o.init_member("getVolume", new builtin_function(sound_getvolume),
fl_hpc);
@@ -553,6 +668,11 @@
int fl_hpcn6 = fl_hpc|as_prop_flags::onlySWF6Up;
+ o.init_member("getDuration", new builtin_function(sound_getDuration),
fl_hpcn6);
+ o.init_member("setDuration", new builtin_function(sound_setDuration),
fl_hpcn6);
+ o.init_member("loadSound", new builtin_function(sound_loadsound),
fl_hpcn6);
+ o.init_member("getPosition", new builtin_function(sound_getPosition),
fl_hpcn6);
+ o.init_member("setPosition", new builtin_function(sound_setPosition),
fl_hpcn6);
o.init_member("getBytesLoaded", new
builtin_function(sound_getbytesloaded), fl_hpcn6);
o.init_member("getBytesTotal", new
builtin_function(sound_getbytestotal), fl_hpcn6);
@@ -608,7 +728,6 @@
as_object* iface = getSoundInterface();
cl=new builtin_function(&sound_new, iface);
iface->set_member_flags(NSV::PROP_CONSTRUCTOR,
as_prop_flags::readOnly);
-
}
// Register _global.String
@@ -616,4 +735,13 @@
}
+#ifdef GNASH_USE_GC
+void
+Sound::markReachableResources() const
+{
+ if ( connection ) connection->setReachable();
+ if ( attachedCharacter ) attachedCharacter->setReachable();
+}
+#endif // GNASH_USE_GC
+
} // end of gnash namespace
Index: server/asobj/Sound.h
===================================================================
RCS file: /sources/gnash/gnash/server/asobj/Sound.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- server/asobj/Sound.h 21 Apr 2008 11:27:44 -0000 1.10
+++ server/asobj/Sound.h 17 Jun 2008 12:42:21 -0000 1.11
@@ -32,6 +32,16 @@
#include "as_object.h" // for inheritance
#include "NetConnection.h"
+#include <boost/scoped_ptr.hpp>
+
+/// Forward declarations
+namespace gnash {
+ class CharacterProxy;
+ namespace media {
+ class sound_handler;
+ }
+}
+
namespace gnash {
// Forward declarations
@@ -40,17 +50,33 @@
class Sound : public as_object {
public:
Sound();
+
+ /// Make this sound control the given character
+ //
+ /// NOTE: 0 is accepted, to implement an "invalid"
+ /// controller type.
+ ///
+ void attachCharacter(character* attachedChar);
+
~Sound();
virtual void attachSound(int si, const std::string& name);
virtual void getBytesLoaded();
virtual void getBytesTotal();
virtual void getPan();
virtual void getTransform();
- virtual int getVolume();
+
+ /// Get volume from associated resource
+ //
+ /// @return true of volume was obtained, false
+ /// otherwise (for example if the associated
+ /// character was unloaded).
+ ///
+ bool getVolume(int& volume);
+ void setVolume(int volume);
+
virtual void loadSound(const std::string& file, bool streaming);
virtual void setPan();
virtual void setTransform();
- virtual void setVolume(int volume);
virtual void start(int offset, int loops);
virtual void stop(int si);
virtual unsigned int getDuration();
@@ -66,10 +92,7 @@
/// Reachable resources are:
/// - associated NetConnection object (connection)
///
- void markReachableResources() const
- {
- if ( connection ) connection->setReachable();
- }
+ void markReachableResources() const;
#endif // GNASH_USE_GC
bool _duration;
@@ -78,12 +101,17 @@
bool _onLoad;
bool _onComplete;
bool _position;
+
boost::intrusive_ptr<NetConnection> connection;
+ boost::scoped_ptr<CharacterProxy> attachedCharacter;
int soundId;
bool externalSound;
std::string externalURL;
bool isStreaming;
+
+ media::sound_handler* _soundHandler;
+
};
void sound_class_init(as_object& global);
Index: testsuite/actionscript.all/Makefile.am
===================================================================
RCS file: /sources/gnash/gnash/testsuite/actionscript.all/Makefile.am,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- testsuite/actionscript.all/Makefile.am 11 Jun 2008 12:09:33 -0000
1.96
+++ testsuite/actionscript.all/Makefile.am 17 Jun 2008 12:42:21 -0000
1.97
@@ -101,6 +101,7 @@
Random.as \
Selection.as \
SharedObject.as \
+ Sound.as \
Stage.as \
String.as \
System.as \
Index: utilities/processor.cpp
===================================================================
RCS file: /sources/gnash/gnash/utilities/processor.cpp,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -b -r1.102 -r1.103
--- utilities/processor.cpp 9 Jun 2008 14:31:56 -0000 1.102
+++ utilities/processor.cpp 17 Jun 2008 12:42:22 -0000 1.103
@@ -21,6 +21,8 @@
#include "gnashconfig.h"
#endif
+#include "NullSoundHandler.h"
+
#include <iostream>
#include <cstdio>
#include <sys/time.h>
@@ -312,6 +314,9 @@
exit(1);
}
+ std::auto_ptr<media::sound_handler> soundHandler(new
media::NullSoundHandler());
+ gnash::set_sound_handler(soundHandler.get());
+
std::vector<movie_data> data;
if (infiles.size() > 1)
Index: testsuite/actionscript.all/Sound.as
===================================================================
RCS file: testsuite/actionscript.all/Sound.as
diff -N testsuite/actionscript.all/Sound.as
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/actionscript.all/Sound.as 17 Jun 2008 12:42:22 -0000 1.1
@@ -0,0 +1,231 @@
+//
+// Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+// Test case for Sound ActionScript class
+// compile this test case with Ming makeswf, and then
+// execute it like this gnash -1 -r 0 -v out.swf
+
+
+rcsid="$Id: Sound.as,v 1.1 2008/06/17 12:42:22 strk Exp $";
+#include "check.as"
+
+// test Sound class and interface availability
+
+check_equals(typeof(Sound), 'function');
+check_equals(typeof(Sound.prototype), 'object');
+check_equals(typeof(Sound.prototype.__proto__), 'object');
+check_equals(Sound.prototype.__proto__, Object.prototype);
+
+check_equals(typeof(Sound.prototype.attachSound), 'function');
+check_equals(typeof(Sound.prototype.getPan), 'function');
+check_equals(typeof(Sound.prototype.setPan), 'function');
+check_equals(typeof(Sound.prototype.start), 'function');
+check_equals(typeof(Sound.prototype.stop), 'function');
+check_equals(typeof(Sound.prototype.getTransform), 'function');
+check_equals(typeof(Sound.prototype.setTransform), 'function');
+check_equals(typeof(Sound.prototype.getVolume), 'function');
+check_equals(typeof(Sound.prototype.setVolume), 'function');
+
+#if OUTPUT_VERSION > 5
+ var functionSinceSWF6 = 'function';
+#else
+ var functionSinceSWF6 = 'undefined';
+#endif
+check_equals(typeof(Sound.prototype.getDuration), functionSinceSWF6);
+check_equals(typeof(Sound.prototype.setDuration), functionSinceSWF6);
+check_equals(typeof(Sound.prototype.loadSound), functionSinceSWF6);
+check_equals(typeof(Sound.prototype.getPosition), functionSinceSWF6);
+check_equals(typeof(Sound.prototype.setPosition), functionSinceSWF6);
+check_equals(typeof(Sound.prototype.getBytesLoaded), functionSinceSWF6);
+check_equals(typeof(Sound.prototype.getBytesTotal), functionSinceSWF6);
+
+// The ones below are undefined in SWF5..SWF8, chances are an ASSetPropFlags
+// to drop the onlyForSWF9 flag would expose them (TODO: test that)
+check_equals(typeof(Sound.prototype.areSoundInaccessible), 'undefined');
+check_equals(typeof(Sound.prototype.duration), 'undefined');
+check_equals(typeof(Sound.prototype.ID3), 'undefined');
+check_equals(typeof(Sound.prototype.checkPolicyFile), 'undefined');
+check_equals(typeof(Sound.prototype.position), 'undefined');
+check_equals(typeof(Sound.prototype.onID3), 'undefined');
+check_equals(typeof(Sound.prototype.onLoad), 'undefined');
+check_equals(typeof(Sound.prototype.onSoundComplete), 'undefined');
+
+
+//-----------------------------------------
+// Test Sound constructor
+//-----------------------------------------
+
+//
+// Use default constructor and check return of all inspectors
+//
+
+// It seems like if Sound ctor is passed nothing, undefined or null
+// it gets associated to some kind of global volume which is DIFFERENT
+// from the one associated with _root...
+//
+s1 = new Sound();
+s2 = new Sound();
+check(s1 instanceof Sound);
+check_equals(typeof(s1.getDuration()), 'undefined');
+xcheck_equals(typeof(s1.getPan()), 'number');
+xcheck_equals(s1.getPan(), 0);
+check_equals(typeof(s1.getPosition()), 'undefined');
+xcheck_equals(typeof(s1.getTransform()), 'object'); // TODO: check composition
+
+// Now, it seems s1 and s2 are both attached to something, and share
+// the volume !
+check_equals(typeof(s1.getVolume()), 'number');
+check_equals(s1.getVolume(), 100); // why, since we didn't specify an attached
char ??
+s1.setVolume(95);
+check_equals(s1.getVolume(), 95);
+check_equals(s2.getVolume(), 95);
+
+check_equals(typeof(s1.getBytesLoaded()), 'undefined');
+check_equals(typeof(s1.getBytesTotal()), 'undefined');
+xcheck_equals(typeof(s1.checkPolicyFile), 'boolean');
+
+// The following are undefined in SWF5..SWF8, chances are
+// some ASSetPropFlag to drop SWF9-only flag would expose
+xcheck_equals(typeof(s1.duration), 'undefined');
+check_equals(typeof(s1.ID3), 'undefined');
+xcheck_equals(typeof(s1.position), 'undefined');
+
+
+//
+// Use constructor taking a movieclip and check return of all inspectors
+//
+
+s2 = new Sound(_root);
+check(s2 instanceof Sound);
+check_equals(typeof(s2.getDuration()), 'undefined');
+xcheck_equals(typeof(s2.getPan()), 'number');
+xcheck_equals(s2.getPan(), 0);
+check_equals(typeof(s2.getPosition()), 'undefined');
+xcheck_equals(typeof(s2.getTransform()), 'object'); // TODO: check composition
+check_equals(typeof(s2.getVolume()), 'number');
+check_equals(s2.getVolume(), 100);
+check_equals(typeof(s2.getBytesLoaded()), 'undefined');
+check_equals(typeof(s2.getBytesTotal()), 'undefined');
+xcheck_equals(typeof(s2.checkPolicyFile), 'boolean');
+
+// The following are undefined in SWF5..SWF8, chances are
+// some ASSetPropFlag to drop SWF9-only flag would expose
+xcheck_equals(typeof(s2.duration), 'undefined');
+check_equals(typeof(s2.ID3), 'undefined');
+xcheck_equals(typeof(s2.position), 'undefined');
+
+// this is still valid, altought getVolume would return undefined
+s3 = new Sound(33);
+check(s3 instanceof Sound);
+check_equals(typeof(s3.getVolume()), 'undefined');
+
+//-----------------------------------------
+// Test association of Sound to characters
+//-----------------------------------------
+
+
+s1a = new Sound();
+s1b = new Sound();
+check_equals(s1a.getVolume(), 95);
+check_equals(s1b.getVolume(), 95);
+s1b.setVolume(76);
+check_equals(s1a.getVolume(), 76);
+check_equals(s1b.getVolume(), 76);
+
+// Numbers are invalid controllable-characters
+s1c = new Sound(54);
+s1d = new Sound(54);
+check_equals(typeof(s1c.getVolume()), 'undefined');
+check_equals(typeof(s1d.getVolume()), 'undefined');
+s1c.setVolume(54);
+check_equals(typeof(s1c.getVolume()), 'undefined');
+check_equals(typeof(s1d.getVolume()), 'undefined');
+
+s1e = new Sound(null);
+s1f = new Sound(undefined);
+check_equals(s1e.getVolume(), 76);
+check_equals(s1f.getVolume(), 76);
+
+// Objects are invalid controllable characters
+o = new Object;
+s1g = new Sound(o);
+s1h = new Sound(o);
+check_equals(typeof(s1g.getVolume()), 'undefined');
+check_equals(typeof(s1h.getVolume()), 'undefined');
+s1g.setVolume(54);
+check_equals(typeof(s1g.getVolume()), 'undefined');
+check_equals(typeof(s1h.getVolume()), 'undefined');
+
+s2 = new Sound(_root);
+s3 = new Sound(_root);
+
+check_equals(s2.getVolume(), 100);
+check_equals(s3.getVolume(), 100);
+s2.setVolume(80);
+check_equals(s2.getVolume(), 80);
+check_equals(s3.getVolume(), 80);
+
+
+// Check association to unloaded characters, and rebinding
+MovieClip.prototype.createEmptyMovieClip = ASnative(901, 0);
+createEmptyMovieClip('c1', 1);
+s2 = new Sound(c1);
+s3 = new Sound(c1);
+check_equals(s2.getVolume(), 100);
+check_equals(s3.getVolume(), 100);
+c1.removeMovieClip(); // unload, no unload handler
+check_equals(typeof(s2.getVolume()), 'undefined');
+check_equals(typeof(s3.getVolume()), 'undefined');
+createEmptyMovieClip('c1', 2); // rebind ref to _level0.c1
+check_equals(s2.getVolume(), 100);
+check_equals(s3.getVolume(), 100);
+s2.setVolume(80);
+check_equals(s2.getVolume(), 80);
+check_equals(s3.getVolume(), 80);
+c1.removeMovieClip(); // unload, no unload handler
+check_equals(typeof(s2.getVolume()), 'undefined');
+check_equals(typeof(s3.getVolume()), 'undefined');
+createEmptyMovieClip('c1', 3); // rebind ref to _level0.c1
+check_equals(s2.getVolume(), 100); // old volume isn't remembered
+check_equals(s3.getVolume(), 100);
+s2.setVolume(80);
+check_equals(s2.getVolume(), 80);
+check_equals(s3.getVolume(), 80);
+c1.onUnload = function() {}; // give c1 an unload handler
+c1.removeMovieClip(); // there's an unload handler now
+#if OUTPUT_VERSION < 6
+ // No matter onUnload, SWF5 looses association
+ xcheck_equals(typeof(s2.getVolume()), 'undefined');
+ xcheck_equals(typeof(s3.getVolume()), 'undefined');
+#else
+ // in SWF6 up, presence of an onUnload handler
+ // prevents loosing the association
+ check_equals(s2.getVolume(), 80);
+ check_equals(s3.getVolume(), 80);
+#endif
+
+// TODO: test association with other kind of characters:
+// - TextField
+// - Video
+// - ...
+
+//-----------------------------------------
+// END OF TEST
+//-----------------------------------------
+
+check_totals(94);
- [Gnash-commit] gnash ChangeLog server/asobj/Sound.cpp server/a...,
Sandro Santilli <=