gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] gnash ChangeLog doc/C/extensions.xml


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog doc/C/extensions.xml
Date: Tue, 18 Dec 2007 22:05:14 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  07/12/18 22:05:14

Modified files:
        .              : ChangeLog 
        doc/C          : extensions.xml 

Log message:
        gave a review of how to create extensions.  Should be a currently 
correct way of doing it.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5209&r2=1.5210
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/extensions.xml?cvsroot=gnash&r1=1.4&r2=1.5

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5209
retrieving revision 1.5210
diff -u -b -r1.5209 -r1.5210
--- ChangeLog   18 Dec 2007 21:28:58 -0000      1.5209
+++ ChangeLog   18 Dec 2007 22:05:13 -0000      1.5210
@@ -1,5 +1,7 @@
 2007-12-18 Sandro Santilli <address@hidden>
 
+       * doc/C/extensions.xml: gave a review of how to create extensions.
+         Should be a currently correct way of doing it.
        * server/character.cpp (destroy): make sure to set the _unloaded
          flag to avoid leaks (Fixes bug #21842).
 

Index: doc/C/extensions.xml
===================================================================
RCS file: /sources/gnash/gnash/doc/C/extensions.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- doc/C/extensions.xml        18 May 2007 17:25:42 -0000      1.4
+++ doc/C/extensions.xml        18 Dec 2007 22:05:14 -0000      1.5
@@ -115,25 +115,27 @@
        <emphasis>attachInterface</emphasis>, and this sets the other
        function callbacks for all the methods this class
        supports. The method callbacks are attached to the parent
-       class by using <emphasis>set_member()</emphasis> to set a C
+       class by using <emphasis>init_member()</emphasis> to set a C
        function pointer to the string value used in the Flash movie.
       </para>
 
       <programlisting>
-       // setup so DummyClass.func1() and DummyClass.func2() work from Flash.
+       // Attach DummyClass 'func1' and 'func2' methods to the given object
        static void
-       attachInterface(as_object *obj)
+       attachInterface(as_object&amp; obj)
        {
-            obj->set_member("func1", &amp;ext_func1);
-            obj->set_member("func2", &amp;ext_func2);
+            obj.init_member("func1", &amp;ext_func1);
+            obj.init_member("func2", &amp;ext_func2);
        }
       </programlisting>
 
       <para>
        The second function is commonly called
        <emphasis>getInterface()</emphasis>, and this returns a
-       smart pointer to the new object. Gnash uses smart pointers for
-       all ActionScript class definitions. (and many other things)
+       pointer to a static prototype of the class.
+        Gnash uses garbage collection for ActionScript objects
+        so you need to register the static with the VM to give it
+        a chance to be marked as reachable.
       </para>
       <programlisting>
        static as_object*
@@ -142,6 +144,8 @@
            static boost::intrusive_ptr&lt;as_object&gt; o;
            if (o == NULL) {
                o = new as_object();
+                VM::get().addStatic(o);
+                attachInterface(*o);
            }
            return o.get();
        }
@@ -155,25 +159,31 @@
        <emphasis>func2</emphasis>.
       </para>
       <programlisting>
-       static void
+       static as_value
        dummyext_ctor(const fn_call&amp; fn)
        {
-           DummyExt *obj = new DummyExt();
+           DummyExt *obj = new DummyExt(); // will setup prototypes
 
-           attachInterface(obj);
-           fn.result->set_as_object(obj); // will keep alive
+           return as_value(obj); 
        }
       </programlisting>
 
       <para>
-       Allocate the new object and return a smart pointer.
+       The trick for the above simple constructor to work is that
+        class appartenence is setup in the C++ DummyExt constructor
+        itself, which should derive from as_object and construct the
+        base passing it the interface (prototype) of it's class.
       </para>
       <programlisting>
-       std::auto_ptr&lt;as_object&gt;
-       init_dummyext_instance()
+       class DummyExt : public as_object
        {
-           return std::auto_ptr&lt;as_object&gt;(new DummyExt());
-       }
+        public:
+           DummyExt()
+                :
+                as_object(getInterface()) // returns the static prototype
+            {}
+
+       };
       </programlisting>
 
       <para>
@@ -190,18 +200,16 @@
            void
            dummyext_class_init(as_object &amp;obj)
            {
-               static boost::intrusive_ptr&lt;builtin_function&gt; cl;
-               if (cl == NULL) {
+               static builtin_function* cl=NULL;
+               if (!cl)
+                {
+                    // Create a builtin function using the given constructor
+                    // to instanciate objects and exporting the given interface
                    cl = new builtin_function(&amp;dummyext_ctor, 
getInterface());
-                   attachInterface(cl.get());
+                   VM::get().addStatic(cl); // will forbid to collect the class
                }
        
-               VM&amp; vm = VM::get();
-               std::string name = "DummyExt";
-               if ( vm.getSWFVersion() &lt; 7 ) {
-                   boost::to_lower(name, vm.getLocale());
-               }
-               obj.init_member(name, cl.get());
+               obj.init_member("DummyExt", cl);
            }
         } // end of extern C
       </programlisting>
@@ -216,15 +224,17 @@
       </para>
       <programlisting>
        // Creates a new button with the label as the text.
-       void func1(const fn_call&amp; fn)
+       as_value func1(const fn_call&amp; fn)
        {
-           DummyExt *ptr = dynamic_cast&lt;DummyExt *&gt;(fn.this_ptr);
-           assert(ptr);
+            // Following line will ensure 'func1' is called for a DummyExt 
instance,
+            // or would throw an exception which should behave as if we 
returned the
+            // undefined value.
+            boost::intrusive_ptr<DummyExt> ptr = 
ensureType<DummyExt>(fn.this_ptr);
        
            if (fn.nargs > 0) {
-               const char *label = fn.arg(0).to_string();
+               std::string label = fn.arg(0).to_string();
                bool ret = ptr->dummy_text_label(label);
-               fn.result->set_bool(ret);
+               return as_value(ret);
            }
        }
       </programlisting>




reply via email to

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