gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog server/character.h server/dlist...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/character.h server/dlist...
Date: Sat, 03 Feb 2007 23:02:07 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/02/03 23:02:07

Modified files:
        .              : ChangeLog 
        server         : character.h dlist.cpp sprite_instance.cpp 
                         sprite_instance.h 

Log message:
                * server/dlist.cpp: call character::construct() everytime an 
object
                  is placed on stage, making the code much more readable and 
clean
                  (IMHO).
                * server/sprite_instance.{h,cpp}: implement 'construct' method
                  to take care of properly handling user-defined registered
                  classes for sprites and to execute tags in frame0; attach
                  properties to *instances* rather then to the MovieClip
                  exported interface.
                * server/character.h: add a 'construct' method.
        
        This commit fixes the registerClassTest case.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.2243&r2=1.2244
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.44&r2=1.45
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.44&r2=1.45
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.147&r2=1.148
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.h?cvsroot=gnash&r1=1.60&r2=1.61

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.2243
retrieving revision 1.2244
diff -u -b -r1.2243 -r1.2244
--- ChangeLog   3 Feb 2007 22:27:36 -0000       1.2243
+++ ChangeLog   3 Feb 2007 23:02:07 -0000       1.2244
@@ -1,5 +1,14 @@
 2007-02-03 Sandro Santilli <address@hidden>
 
+       * server/dlist.cpp: call character::construct() everytime an object
+         is placed on stage, making the code much more readable and clean
+         (IMHO).
+       * server/sprite_instance.{h,cpp}: implement 'construct' method
+         to take care of properly handling user-defined registered
+         classes for sprites and to execute tags in frame0; attach
+         properties to *instances* rather then to the MovieClip
+         exported interface.
+       * server/character.h: add a 'construct' method.
        * testsuite/misc-ming.all/: registerClassTest.c,
          registerClassTestRunner.cpp: add new tests, a fix
          for gnash will follow shortly.

Index: server/character.h
===================================================================
RCS file: /sources/gnash/gnash/server/character.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- server/character.h  2 Feb 2007 10:07:50 -0000       1.44
+++ server/character.h  3 Feb 2007 23:02:07 -0000       1.45
@@ -18,7 +18,7 @@
 //
 //
 
-/* $Id: character.h,v 1.44 2007/02/02 10:07:50 strk Exp $ */
+/* $Id: character.h,v 1.45 2007/02/03 23:02:07 strk Exp $ */
 
 #ifndef GNASH_CHARACTER_H
 #define GNASH_CHARACTER_H
@@ -549,6 +549,21 @@
        ///
        virtual void get_invalidated_bounds(rect* bounds, bool force) = 0;
 
+       /// Construct this instance as an ActionScript object.
+       //
+       /// This function must be called when the character is placed on
+       /// stage for the first time. It will take care of invoking
+       /// the constructor of its associated class and calling the
+       /// 'onConstruct' event handler.
+       ///
+       /// Make sure this instance got an instance name before calling
+       /// this method (it's needed for properly setting the "this" pointer
+       /// when calling user-defined constructors).
+       ///
+       virtual void construct()
+       {
+               on_event(event_id::CONSTRUCT);
+       }
 
        
 };

Index: server/dlist.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.cpp,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -b -r1.44 -r1.45
--- server/dlist.cpp    24 Jan 2007 23:33:00 -0000      1.44
+++ server/dlist.cpp    3 Feb 2007 23:02:07 -0000       1.45
@@ -210,10 +210,8 @@
                *it = DisplayItem(ch);
        }
 
-       ch->on_event(event_id::CONSTRUCT);
-
-       sprite_instance* sprite_ch = ch->to_movie();
-       if ( sprite_ch ) sprite_ch->execute_frame_tags(0, false);       
+       // Give life to this instance
+       ch->construct();
 }
 
 void
@@ -284,9 +282,8 @@
                // add the new char
                _characters.insert(it, di);
 
-               ch->on_event(event_id::CONSTRUCT);
-               sprite_instance* sprite_ch = ch->to_movie();
-               if ( sprite_ch ) sprite_ch->execute_frame_tags(0, false);       
+               // Give life to this instance
+               ch->construct();
        }
        else
        {
@@ -304,6 +301,9 @@
 
                // replace existing char
                *it = di;
+
+               // Shouldn't we construct the new object here too ?
+               //ch->construct();
        }
 
 }

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -b -r1.147 -r1.148
--- server/sprite_instance.cpp  1 Feb 2007 10:42:29 -0000       1.147
+++ server/sprite_instance.cpp  3 Feb 2007 23:02:07 -0000       1.148
@@ -75,6 +75,8 @@
 
 // Forward declarations
 static as_object* getMovieClipInterface();
+static void attachMovieClipInterface(as_object& o);
+static void attachMovieClipProperties(as_object& o);
 
 // Initialize unnamed instance count
 unsigned int sprite_instance::_lastUnnamedInstanceNum=0;
@@ -115,19 +117,6 @@
        return ret;
 }
 
-// Wrapper around dynamic_cast to implement user warning.
-// To be used by builtin properties and methods.
-static character*
-ensure_character(as_object* obj)
-{
-       character* ret = dynamic_cast<character*>(obj);
-       if ( ! ret )
-       {
-               throw ActionException("builtin method or gettersetter for 
character objects called against non-character instance");
-       }
-       return ret;
-}
-
 static void sprite_play(const fn_call& fn)
 {
        sprite_instance* sprite = ensure_sprite(fn.this_ptr);
@@ -183,6 +172,7 @@
 
        // Get exported resource 
        std::string id_name = fn.arg(0).to_std_string();
+
        boost::intrusive_ptr<resource> exported = 
sprite->get_movie_definition()->get_exported_resource(id_name.c_str());
        if ( exported == NULL )
        {
@@ -213,12 +203,23 @@
 
        boost::intrusive_ptr<character> newch = 
exported_movie->create_character_instance(sprite, depth_val);
        assert( dynamic_cast<sprite_instance*>(newch.get()) );
+       assert( newch.get() > (void*)0xFFFF );
+       assert(newch->get_ref_count() > 0);
 
-       if (! sprite->attachCharacter(*newch, depth_val, newname) )
+       newch->set_name(newname.c_str());
+
+       // place_character() will set depth on newch
+       if ( ! sprite->attachCharacter(*newch, depth_val) )
        {
+               log_error("Could not attach character at depth %d", depth_val);
                return;
        }
 
+       // MOVE THIS CODE TO dlist.cpp, and have sprite_instance::construct
+       // call execute_frame_tags(0, false)
+       //sprite_instance* newsprite = 
dynamic_cast<sprite_instance*>(newch.get());
+       //if ( newsprite ) newsprite->construct();
+
        newch->setDynamic();
 
        /// Properties must be copied *after* the call to attachCharacter
@@ -868,6 +869,7 @@
 movieclip_ctor(const fn_call& fn)
 {
        boost::intrusive_ptr<as_object> clip = new 
as_object(getMovieClipInterface());
+       attachMovieClipProperties(*clip);
        fn.result->set_as_object(clip.get());
 }
 
@@ -1092,6 +1094,7 @@
 
 #endif // ndef OLD_GET_MEMBER
 
+/// Properties (and/or methods) *inherited* by MovieClip instances
 static void
 attachMovieClipInterface(as_object& o)
 {
@@ -1099,7 +1102,57 @@
 
        boost::intrusive_ptr<builtin_function> gettersetter;
 
-#ifndef OLD_GET_MEMBER
+       // SWF5 or higher
+       o.init_member("attachMovie", &sprite_attach_movie);
+       o.init_member("play", &sprite_play);
+       o.init_member("stop", &sprite_stop);
+       o.init_member("gotoAndStop", &sprite_goto_and_stop);
+       o.init_member("gotoAndPlay", &sprite_goto_and_play);
+       o.init_member("nextFrame", &sprite_next_frame);
+       o.init_member("prevFrame", &sprite_prev_frame);
+       o.init_member("getBytesLoaded", &sprite_get_bytes_loaded);
+       o.init_member("getBytesTotal", &sprite_get_bytes_total);
+       o.init_member("loadMovie", &sprite_load_movie);
+       o.init_member("hitTest", &sprite_hit_test);
+       o.init_member("duplicateMovieClip", &sprite_duplicate_movieclip);
+       o.init_member("swapDepths", &sprite_swap_depths);
+       o.init_member("removeMovieClip", &sprite_remove_movieclip);
+       o.init_member("startDrag", &sprite_startDrag);
+       o.init_member("stopDrag", &sprite_stopDrag);
+       o.init_member("getURL", &sprite_getURL);
+       o.init_member("getBounds", &sprite_getBounds);
+       o.init_member("globalToLocal", &sprite_globalToLocal);
+       if ( target_version  < 6 ) return;
+
+       // SWF6 or higher
+       o.init_member("beginFill", &sprite_beginFill);
+       o.init_member("beginGradientFill", &sprite_beginGradientFill);
+       o.init_member("clear", &sprite_clear);
+       o.init_member("curveTo", &sprite_curveTo);
+       o.init_member("lineStyle", &sprite_lineStyle);
+       o.init_member("lineTo", &sprite_lineTo);
+       o.init_member("endFill", &sprite_endFill);
+       o.init_member("attachAudio", &sprite_attach_audio);
+       o.init_member("createTextField", &sprite_create_text_field);
+       o.init_member("getDepth", &sprite_get_depth);
+       o.init_member("createEmptyMovieClip", &sprite_create_empty_movieclip);
+       if ( target_version  < 7 ) return;
+
+       // SWF7 or higher
+       o.init_member("getNextHighestDepth", &sprite_getNextHighestDepth);
+       if ( target_version  < 8 ) return;
+
+       // TODO: many more methods, see MovieClip class ...
+
+}
+
+/// Properties (and/or methods) attached to every *instance* of a MovieClip 
+static void
+attachMovieClipProperties(as_object& o)
+{
+       //int target_version = o.getVM().getSWFVersion();
+
+       boost::intrusive_ptr<builtin_function> gettersetter;
 
        //
        // Properties (TODO: move to appropriate SWF version section)
@@ -1180,50 +1233,6 @@
        gettersetter = new builtin_function(&character::onload_getset, NULL);
        o.init_property("onLoad", *gettersetter, *gettersetter);
 
-#endif // ndef OLD_GET_MEMBER
-
-       // SWF5 or higher
-       o.init_member("attachMovie", &sprite_attach_movie);
-       o.init_member("play", &sprite_play);
-       o.init_member("stop", &sprite_stop);
-       o.init_member("gotoAndStop", &sprite_goto_and_stop);
-       o.init_member("gotoAndPlay", &sprite_goto_and_play);
-       o.init_member("nextFrame", &sprite_next_frame);
-       o.init_member("prevFrame", &sprite_prev_frame);
-       o.init_member("getBytesLoaded", &sprite_get_bytes_loaded);
-       o.init_member("getBytesTotal", &sprite_get_bytes_total);
-       o.init_member("loadMovie", &sprite_load_movie);
-       o.init_member("hitTest", &sprite_hit_test);
-       o.init_member("duplicateMovieClip", &sprite_duplicate_movieclip);
-       o.init_member("swapDepths", &sprite_swap_depths);
-       o.init_member("removeMovieClip", &sprite_remove_movieclip);
-       o.init_member("startDrag", &sprite_startDrag);
-       o.init_member("stopDrag", &sprite_stopDrag);
-       o.init_member("getURL", &sprite_getURL);
-       o.init_member("getBounds", &sprite_getBounds);
-       o.init_member("globalToLocal", &sprite_globalToLocal);
-       if ( target_version  < 6 ) return;
-
-       // SWF6 or higher
-       o.init_member("beginFill", &sprite_beginFill);
-       o.init_member("beginGradientFill", &sprite_beginGradientFill);
-       o.init_member("clear", &sprite_clear);
-       o.init_member("curveTo", &sprite_curveTo);
-       o.init_member("lineStyle", &sprite_lineStyle);
-       o.init_member("lineTo", &sprite_lineTo);
-       o.init_member("endFill", &sprite_endFill);
-       o.init_member("attachAudio", &sprite_attach_audio);
-       o.init_member("createTextField", &sprite_create_text_field);
-       o.init_member("getDepth", &sprite_get_depth);
-       o.init_member("createEmptyMovieClip", &sprite_create_empty_movieclip);
-       if ( target_version  < 7 ) return;
-
-       // SWF7 or higher
-       o.init_member("getNextHighestDepth", &sprite_getNextHighestDepth);
-       if ( target_version  < 8 ) return;
-
-       // TODO: many more methods, see MovieClip class ...
-
 }
 
 static as_object*
@@ -1409,19 +1418,7 @@
        assert(m_def != NULL);
        assert(m_root != NULL);
 
-       if ( registerClass )
-       {
-               attachMovieClipInterface(*this);
-               // TODO: call the constructor ?
-               as_object* proto = registerClass->getPrototype();
-               log_msg("registerClass prototype : %p", proto);
-               copyProperties(*proto);
-               set_prototype(proto);
-       }
-       else
-       {
                set_prototype(getMovieClipInterface());
-       }
                        
        //m_root->add_ref();    // @@ circular!
        m_as_environment.set_target(this);
@@ -1429,6 +1426,9 @@
        // Initialize the flags for init action executed.
        m_init_actions_executed.assign(m_def->get_frame_count(), false);
 
+       // TODO: have the 'MovieClip' constructor take care of this !
+       attachMovieClipProperties(*this);
+
 }
 
 sprite_instance::~sprite_instance()
@@ -1902,7 +1902,6 @@
        }
 }
 
-#if 1
 void sprite_instance::remove_display_object(const tu_string& name_tu)
 {
 //         GNASH_REPORT_FUNCTION;
@@ -1917,7 +1916,6 @@
            remove_display_object(ch->get_depth(), ch->get_id());
        }
 }
-#endif
 
 bool sprite_instance::on_event(const event_id& id)
 {
@@ -2792,9 +2790,8 @@
 }
 
 bool
-sprite_instance::attachCharacter(character& newch, uint16_t depth, 
std::string& name)
+sprite_instance::attachCharacter(character& newch, uint16_t depth)
 {
-       newch.set_name(name.c_str());
 
        // place_character() will set depth on newch
        m_display_list.place_character(
@@ -3412,6 +3409,43 @@
        return _target_dot.c_str();
 }
 
+// WARNING: THIS SNIPPET NEEDS THE CHARACTER TO BE "INSTANTIATED", which is
+//          it's target path needs to exist, or any as_value for it will be
+//          a dangling reference to an unexistent sprite !
+void
+sprite_instance::construct()
+{
+       on_event(event_id::CONSTRUCT);
+       execute_frame_tags(0, false);   
+
+       sprite_definition* def = dynamic_cast<sprite_definition*>(m_def.get());
+
+       // We won't "construct" top-level movies
+       if ( ! def ) return;
+
+       // instance name will be needed for properly setting up
+       // a reference to 'this' object.
+       assert(!_name.empty());
+
+       as_function* ctor = def->getRegisteredClass();
+       log_msg("Attached sprite's registered class is %p", (void*)ctor); 
+
+       // TODO: builtin constructors are different from user-defined ones
+       // we should likely change that. See also vm/ASHandlers.cpp 
(construct_object)
+       if ( ctor && ! ctor->isBuiltin() )
+       {
+               // Set the new prototype *after* the constructor was called
+               as_object* proto = ctor->getPrototype();
+               set_prototype(proto);
+
+               log_msg("Calling the user-defined constructor against this 
sprite_instance");
+               as_value ret; // we don't use the constructor return (should 
we?)
+               fn_call call(&ret, this, &(get_environment()), 0, 0);
+               (*ctor)(call);
+
+       }
+}
+
 void
 sprite_instance::set_name(const char* name)
 {

Index: server/sprite_instance.h
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.h,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -b -r1.60 -r1.61
--- server/sprite_instance.h    2 Feb 2007 10:07:50 -0000       1.60
+++ server/sprite_instance.h    3 Feb 2007 23:02:07 -0000       1.61
@@ -17,7 +17,7 @@
 // 
 //
 
-/* $Id: sprite_instance.h,v 1.60 2007/02/02 10:07:50 strk Exp $ */
+/* $Id: sprite_instance.h,v 1.61 2007/02/03 23:02:07 strk Exp $ */
 
 // Stateful live Sprite instance
 
@@ -355,15 +355,27 @@
        /// @param depth
        ///     The depth to assign to the instance.
        ///
-       /// @param name
-       ///     The name to assign to the instance.
-       ///
        /// @return true on success, false on failure
        ///     FIXME: currently never returns false !
        ///
-       bool attachCharacter(character& newch, uint16_t depth,
-                       std::string& name);
+       bool attachCharacter(character& newch, uint16_t depth);
 
+       /// Construct this instance as an ActionScript object.
+       //
+       /// This function must be called when the sprite is placed on
+       /// stage for the first time. It will take care of invoking
+       /// the constructor of its associated class, either MovieClip
+       /// or any user-specified one (see sprite_definition::registerClass).
+       ///
+       /// Make sure this sprite got an instance name before calling
+       /// this method (it's needed for properly setting the "this" pointer
+       /// when calling user-defined constructors).
+       ///
+       /// TODO: check if we only need to construct "named" instances
+       /// TODO: consider moving this function up to the 'character' class.
+       /// TODO: possibly have this function call the onConstruct() event 
handler
+       ///
+       void construct();
 
        /// Updates the transform properties of the object at
        /// the specified depth.




reply via email to

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