gnash-commit
[Top][All Lists]
Advanced

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

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


From: Rob Savoye
Subject: [Gnash-commit] gnash/doc/C/refmanual/extensions extensions.xml...
Date: Sat, 01 Mar 2008 15:24:44 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Rob Savoye <rsavoye>    08/03/01 15:24:44

Added files:
        doc/C/refmanual/extensions: extensions.xml fileext.xml 
                                    gtkext.xml mysqlext.xml 

Log message:
        New directory for docs on Gnash extensions.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/refmanual/extensions/extensions.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/refmanual/extensions/fileext.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/refmanual/extensions/gtkext.xml?cvsroot=gnash&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/gnash/doc/C/refmanual/extensions/mysqlext.xml?cvsroot=gnash&rev=1.1

Patches:
Index: extensions.xml
===================================================================
RCS file: extensions.xml
diff -N extensions.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ extensions.xml      1 Mar 2008 15:24:43 -0000       1.1
@@ -0,0 +1,315 @@
+<chapter id="extensions">
+  <title>Gnash Extensions</title>
+  
+  <para>
+    Gnash supports extending the Flash specification by creating
+    custom ActionScript classes that are compiled code, as opposed to
+    the existing method of defining custom classes as
+    ActionScript. Executing compiled code has many performance
+    benefits over having to interpret the byte stream of the
+    ActionScript opcodes.
+  </para>
+  
+  <para>
+    I can already hear people complaining now about the concept of
+    extending Flash, so this in no way affects Gnash's ability to play
+    Flash movies when functioning as a browser plugin.
+    Gnash's goal is still to function in a way that is compatible
+    with the current proprietary Flash player.
+  </para>
+
+  <para>
+    But at the same time, we see Flash as the ideal scripting language
+    for a digital multi-media streaming environment. There are many
+    resources for Flash movie creators for widgets, higher level APIs,
+    all sorts of desirable things. But for those of use committed to
+    using free software tools for Flash, our options are very
+    limited. 
+  </para>
+
+  <para>
+    Rather than launching a multi-year project to duplicate all
+    classes in the commercial Flash IDE, it's much more efficient to
+    use existing development libraries much like Python or Perl
+    do. The extension mechanism in Gnash allows wrappers to be created
+    for any C or C++ development library. Unlike the proprietary Flash
+    IDE, which compiles all the extension libraries into byte codes
+    from ActionScript, the support is moved to the player side. Movies
+    with all of the goodies of the proprietary IDE in them play in
+    Gnash just fine, as it's all just byte codes by then.
+  </para>
+
+  <para>
+    This trick works because until Flash player version 9, all the
+    ActionScript class names and methods are passed as ASCII strings
+    into the Flash movie. So the Gnash Virtual Machine just loads the
+    extension file if that class name is invoked in the movie. All
+    extension files specify the class name and methods it implements
+    in an identical style as adding any new ActionScript class. The
+    advantage is the class itself is compiled code, and runs much
+    faster than the equivalent byte codes which all have to be
+    interpreted..
+  </para>
+
+  <sect1 id="newext">
+    <title>Creating A New Extension</title>
+
+    <para>
+      Each new extension should live in it's own directory. The
+      extensions included in Gnash are all in the
+      <code>gnash/extensions</code> directory. Creating an extension
+      requires a Makefile.am,
+    </para>
+
+    <para>
+      If you are adding this extension to the Gnash source tree
+      itself, then you need to make two changes to add the new
+      extension.
+    </para>
+
+    <para>
+      The first change is to add the directory to the list in
+      extensions/Makefile.am. This can be done either by adding the
+      new directory to the SUBDIRS setting, or by wrapping it in a
+      conditional test.
+    </para>
+
+    <para>
+      The other change is to add it to the AC_OUTPUT list in
+      <emphasis>configure.ac</emphasis> so the new directory will be
+      configured along with the rest of Gnash.
+    </para>
+
+    <para>
+      Each extension should have an ActionScript source file included
+      that tests the new class, and this file should be referenced in
+      the new Makefile.am in the <emphasis>check_PROGRAMS</emphasis>
+      variable so that "make check" works.
+    </para>
+
+    <para>
+      When creating an extension that is a wrapper for an existing
+      development library API, it's often better to make this a thin
+      layer, than to get carried away with creating beautiful
+      abstractions. Higher-level classes that offer a lot of new
+      functionality are fine, but is different than wrapping a library
+      so it can be used from within Gnash.
+    </para>
+
+    <sect2 id="craftext">
+      <title>Crafting an Extension</title>
+
+      <para>
+       All extensions have the same requirements, namely setting up a
+       few defined function callbacks, which the Gnash VM then uses
+       to do the right thing. The initial two function callbacks are
+       for handling the interface of the newly created object so that
+       Gnash can find and use it.
+      </para>
+
+      <para>
+       The first function is commonly called
+       <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>init_member()</emphasis> to set a C
+       function pointer to the string value used in the Flash movie.
+      </para>
+
+      <programlisting>
+       // Attach DummyClass 'func1' and 'func2' methods to the given object
+       static void
+       attachInterface(as_object&amp; obj)
+       {
+            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
+       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*
+       getInterface()
+       {
+           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();
+       }
+      </programlisting>
+
+      <para>
+       This is the callback that gets executed when constructing a
+       new object for the VM. In this example we'll assume the new
+       ActionScript class is called <emphasis>DummyExt</emphasis>,
+       and has two methods, <emphasis>func1</emphasis> and
+       <emphasis>func2</emphasis>.
+      </para>
+      <programlisting>
+       static as_value
+       dummyext_ctor(const fn_call&amp; fn)
+       {
+           DummyExt *obj = new DummyExt(); // will setup prototypes
+
+           return as_value(obj); 
+       }
+      </programlisting>
+
+      <para>
+       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>
+       class DummyExt : public as_object
+        {
+        public:
+           DummyExt()
+                :
+                as_object(getInterface()) // returns the static prototype
+            {}
+
+       };
+      </programlisting>
+
+      <para>
+       Initialize the extension. This is looked for by the extension
+       handling code in each extension, and is executed when the
+       extension is loaded. This is the main entry point into the
+       extension. This function can be found because the prefix of
+       <emphasis>dummyext</emphasis>, which also matches the file
+       name of the extension. Gnash uses the name of the extension
+       file itself when looking for the init function.
+      </para>
+      <programlisting>
+        extern "C" {
+           void
+           dummyext_class_init(as_object &amp;obj)
+           {
+               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());
+                   VM::get().addStatic(cl); // will forbid to collect the class
+               }
+       
+               obj.init_member("DummyExt", cl);
+           }
+        } // end of extern C
+      </programlisting>
+
+      <para>
+       The callbacks are all C functions. Like all the other code
+       that implements ActionScript, parameters to the function are
+       passed in using the <emphasis>fn_call</emphasis> data
+       structure. The return code, if any, is also returned using
+       this data structure. <emphasis>this_ptr</emphasis> is the
+       object that the method is a member of.
+      </para>
+      <programlisting>
+       // Creates a new button with the label as the text.
+       as_value func1(const fn_call&amp; fn)
+       {
+            // 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&lt;DummyExt&gt; ptr = 
ensureType&lt;DummyExt&gt;(fn.this_ptr);
+       
+           if (fn.nargs > 0) {
+               std::string label = fn.arg(0).to_string();
+               bool ret = ptr->dummy_text_label(label);
+               return as_value(ret);
+           }
+       }
+      </programlisting>
+
+    </sect2>
+
+  </sect1>
+
+  <sect1 id="debuext">
+    <title>Debugging An Extension</title>
+    
+    <para>
+      As extensions are loaded dynamically at runtime, debugging one
+      can be difficult. You can use GDB, but you have the problem of
+      not being able to set a breakpoint in Gnash until
+      <emphasis>after</emphasis> the extension has been loaded into
+      Gnash's VM. The easy solution is to use the Gnash debugger.
+    </para>
+
+    <para>
+      You can insert these few lines in any file that you wish to
+      manually start the debugger. Once at the console, you can attach
+      GDB to the process. Then you can set breakpoints, etc... and you
+      are at the point of execution where the console was started. To
+      then continue playing the movie, type the <emphasis>c</emphasis>
+      (for continue) command to the Gnash console.
+    </para>
+    <programlisting>
+      // Get the debugger instance
+      static Debugger&amp; debugger = Debugger::getDefaultInstance();
+
+      // Enable the debugger
+      debugger.enabled(true);
+      // Stop and drop into a console
+      debugger.console();
+    </programlisting>
+
+    <para>
+      You can also resort to the time honored technique of creating a
+      loop before the point you want to set a breakpoint for. Gnash
+      will stop playing the movie at this point, and then you can
+      externally attach GDB to the running process, or type
+      <emphasis>^C</emphasis> to drop into the GDB command console.
+    </para>
+    <programlisting>
+      bool stall = true;
+      while (stall) {
+          sleep 1;
+      }
+    </programlisting>
+
+    <para>
+      Once you have set the breakpoints you want, reset the value of
+      the <emphasis>stall</emphasis> variable to break out of the
+      loop, and the Flash movie will then continue playing.
+    </para>
+    <programlisting>
+      (gdb) set variable stall = false;
+      continue
+    </programlisting>
+
+  </sect1>
+  
+  <sect1 id="inclext">
+    <title>Included Extensions</title>
+
+    <para>
+      Gnash has some extensions included in the distribution. This is
+      mostly because they were written by the Gnash team. Extensions
+      can be external to gnash, Gnash needs no compiled in knowledge
+      to load an extension file.
+    </para>
+    
+    &gtkext;
+    &fileext;
+    &mysqlext;
+
+  </sect1>
+
+</chapter>

Index: fileext.xml
===================================================================
RCS file: fileext.xml
diff -N fileext.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ fileext.xml 1 Mar 2008 15:24:44 -0000       1.1
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sect3 id="fileioext">
+  <title>File I/O Extension</title>
+
+  <para>
+    Flash movies are traditionally forbidden from accessing the
+    filesystem, but this may be necessary for some embedded
+    applications. Especially in the case of a user console, currently
+    there is no way to get input into a Flash movie but through a
+    TextField.
+  </para>
+
+  <variablelist>
+    <varlistentry>
+      <term>fopen</term>
+      <listitem>
+       <para>
+         Open the file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fread</term>
+      <listitem>
+       <para>
+         Read a series of bytes from the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fgetc</term>
+      <listitem>
+       <para>
+         Read a single byte from the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fgets</term>
+      <listitem>
+       <para>
+         Read a single line until a Carriage Return from the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>gets</term>
+      <listitem>
+       <para>
+         Read a single line from the standard in.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>getchar</term>
+      <listitem>
+       <para>
+         Read a single character from the standard in.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fwrite</term>
+      <listitem>
+       <para>
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fputc</term>
+      <listitem>
+       <para>
+         Write a single character to the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fputs</term>
+      <listitem>
+       <para>
+         Write a single line to the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>puts</term>
+      <listitem>
+       <para>
+         Write a single line to standard out..
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>putchar</term>
+      <listitem>
+       <para>
+         Write a single character to standard out..
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fflush</term>
+      <listitem>
+       <para>
+         Flush the current opened file to disk.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fseek</term>
+      <listitem>
+       <para>
+         Seek to a location within the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>ftell</term>
+      <listitem>
+       <para>
+         Report the current position within the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fclose</term>
+      <listitem>
+       <para>
+         Close the opened file.
+       </para>
+      </listitem>
+    </varlistentry>
+
+  </variablelist>
+
+</sect3>

Index: gtkext.xml
===================================================================
RCS file: gtkext.xml
diff -N gtkext.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ gtkext.xml  1 Mar 2008 15:24:44 -0000       1.1
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sect3 id="gtkext">
+  <title>Gtk Extension</title>
+
+  <para>
+    The GTK ActionScript class follows the same API as Gtk2, even down
+    to the same arguments to the same function names. This means
+    you're actually programming GTK,you're just using ActionScript
+    instead of python, perl, or C. This extension makes it possible to
+    write Flash movies that use the Gtk2 widgets for user interface
+    components.
+  </para>
+
+  <variablelist>
+    <varlistentry>
+      <term>window_new</term>
+      <listitem>
+       <para>
+         Create a new window.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>signal_connect</term>
+      <listitem>
+       <para>
+         Add an event handler to a widget.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>container_set_border_width</term>
+      <listitem>
+       <para>
+         Set the width of the window border.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>button_new_with_label</term>
+      <listitem>
+       <para>
+         Create a new button and give it the specified label.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>signal_connect_swapped</term>
+      <listitem>
+       <para>
+         Swap signals. Commonly used for <emphasis>delete</emphasis> event 
handling.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>container_add</term>
+      <listitem>
+           <para>
+             Add one widget to another as a child.
+           </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>widget_show</term>
+      <listitem>
+       <para>
+         Display the widget on the screen.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+    <varlistentry>
+      <term>main</term>
+      <listitem>
+       <para>
+         Start the main GTK event loop. This function does not return.
+       </para>
+      </listitem>
+    </varlistentry>
+    
+  </variablelist>
+</sect3>
\ No newline at end of file

Index: mysqlext.xml
===================================================================
RCS file: mysqlext.xml
diff -N mysqlext.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ mysqlext.xml        1 Mar 2008 15:24:44 -0000       1.1
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<sect3 id="mysqlext">
+  <title>MySQL Extension</title>
+
+  <para>
+    The MySQL ActionScript class follows the same API as MySQL, even down
+    to the same arguments to the same function names. This enables a
+    Flash movie to have direct access to a MySQL
+    database. Traditionally Flash movies have had no database
+    support, they either had to use arrays, or use XML to communicate
+    to an application specific external database daemon.
+  </para>
+
+  <variablelist>
+    <varlistentry>
+      <term>connect</term>
+      <listitem>
+       <para>
+         Connect to a MySQL database.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>qetData</term>
+      <listitem>
+       <para>
+         Get data from the database.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>disconnect</term>
+      <listitem>
+       <para>
+         Disconnect from a MySQL database.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>query</term>
+      <listitem>
+       <para>
+         Execute an SQL query to the database.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>fetch_row</term>
+      <listitem>
+       <para>
+         Fetch a row from the query results.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>num_fields</term>
+      <listitem>
+       <para>
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>free_result</term>
+      <listitem>
+       <para>
+         Free the results of a query.
+       </para>
+      </listitem>
+    </varlistentry>
+
+    <varlistentry>
+      <term>store_results</term>
+      <listitem>
+       <para>
+         Store the results of a query.
+       </para>
+      </listitem>
+    </varlistentry>
+
+  </variablelist>
+  
+</sect3>




reply via email to

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