[Top][All Lists]
[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& obj)
+ {
+ obj.init_member("func1", &ext_func1);
+ obj.init_member("func2", &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<as_object> 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& 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 &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(&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& 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<DummyExt> ptr =
ensureType<DummyExt>(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& 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>
+
+ >kext;
+ &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>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash/doc/C/refmanual/extensions extensions.xml...,
Rob Savoye <=