[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnash-commit] gnash ChangeLog doc/C/internals.xml
From: |
strk |
Subject: |
Re: [Gnash-commit] gnash ChangeLog doc/C/internals.xml |
Date: |
Mon, 5 Mar 2007 23:39:31 +0100 |
On Mon, Mar 05, 2007 at 09:35:27PM +0000, Ann Barcomb wrote:
> virtual bool get_member(const tu_stringi& name, as_value*
> val) {
> if ((name == "firstChild") || (name == "childNodes")) {
> - val->set_as_object_interface(this);
> + val->set_as_object(this);
> return true;
> }
We now have the concept of getter/setter members, which allows us to *not*
override get_member and set_member. Not overriding them has the advantage of
automatically getting case conversion and inheritance crawling for free.
Ideally, I'd make get_member/set_member non-virtual functions of as_object
to completely disable overriding them.
Example of use for the gettersetter can be found in Sound.cpp, LoadVars.cpp,
xmlnode.cpp and other files.
Our gen-files.sh script does NOT output any getter/setter because it's input
file (docs/C/NOTES) doesn't distinguish between methods and properties.
One thing which is still uncertail is wheter properties should be set
in the class exported interface (get<classname>Iterface) or attached
to *instances* of that class. Currently both work fine, and an example
of split is found in sprite_instance.cpp.
> + // Register _global.String
> + global.init_member("XML", cl.get());
A typo: "// Register _global.XML"
> + main one of interest is <emphasis>is_function</emphasis>,
> + <emphasis>is_as_function</emphasis>,
> <emphasis>is_string</emphasis>,
> + and so on. A list of these methods, which indicate if a argument
> + is of a specified type, can be found in
> + <emphasis>as_value.h</emphasis>.
> <programlisting>
> - if (fn.env->top(0).get_type() == as_value::STRING) {
> + if (fn.env->top(0).is_string()) {
> ...
> }
> </programlisting>
> + Another option is to use <emphasis>typeOf</emphasis>, which will
> + return a string describing the argument type.
I'd discourage anyone from using as_value::typeOf(). That function
is specifically there to implement a TYPOF ActionScript expression.
Also, sometime an ActionScript class method only want a specific type, in
that case it can call the as_value::to<type> method directly, and check
that the return is valid. This is because there are automatic type conversions.
Like, if a function wants a number, but it has given the string "10",
is_number()
will return false, but to_number() will return 10.
> <para>
> The supported data types for an object are
> + <emphasis>NULLTYPE</emphasis>
> <emphasis>BOOLEAN</emphasis>, <emphasis>STRING</emphasis>,
> <emphasis>NUMBER</emphasis>, <emphasis>OBJECT</emphasis>,
> - <emphasis>C_FUNCTION</emphasis>, <emphasis>AS_FUNCTION</emphasis>.
> Because
> + <emphasis>C_FUNCTION</emphasis>, <emphasis>AS_FUNCTION</emphasis>,
I'd add that C_FUNCTION is being deprecated for as_value.
> <para>
> To add methods to the class, a new class needs to be
> + instantiated as an object. Each ActionScript object can
> + have child methods, which are attached to the object in a
> + manner similar to how the object itself is initialized using
> + <emphasis>init_member</emphasis>.
What ? :)
> <programlisting>
> xml_obj = new xml_as_object;
> - xml_obj->set_member("load", &xml_load);
> + xml_obj->init_member("load", new builtin_function(xml_load));
> </programlisting>
> </para>
The only reason ti add members to *instances* rather then to the class itself
is for attaching getter/setter properties, if we find out that's the way to go.
In this case, yes, the <class>_ctor will need to attach a set of properties,
which is better done with a separate function, see attachMovieClipProperties
in sprite_instance.cpp. (I've just seen it's not even used, btw).
> <programlisting>
> void
> - xml_new(const fn_call& fn) {
> + xml_new(const fn_call& fn)
> + {
> as_value inum;
> - xml_as_object *xml_obj;
> + XML *xml_obj;
>
> if (fn.nargs > 0) {
> - if (fn.env->top(0).get_type() == as_value::STRING) {
> - xml_obj = new xml_as_object;
> + as_object* obj = fn.env->top(0).to_object();
Use fn.arg(0), not fn.env->top(0) !
> + if (! obj ) {
> + xml_obj = new XML;
> tu_string datain = fn.env->top(0).to_tu_string();
> - xml_obj->obj.parseXML(datain);
> - xml_obj->obj.setupFrame(xml_obj,
> xml_obj->obj.firstChild(), true);
> + xml_obj->parseXML(datain);
> + xml_obj->setupFrame(xml_obj, xml_obj->firstChild(),
> true);
> } else {
> - xml_as_object *xml_obj =
> (xml_as_object*)fn.env->top(0).to_object();
> - fn.result->set_as_object_interface(xml_obj);
> + assert(dynamic_cast<XML*>(obj));
Don't assert, or new XML(new Date) will abort Gnash.
Rather, check as you did after .to_object() above.
> + XML* xml_obj = (XML*)obj;
> + fn.result->set_as_object(xml_obj);
> return;
> }
> } else {
> - xml_obj = new xml_as_object;
> - xml_obj->set_member("load", &xml_load);
> - xml_obj->set_member("loaded", &xml_loaded);
> + xml_obj = new XML;
> }
> - fn.result->set_as_object_interface(xml_obj);
> +
> + fn.result->set_as_object(xml_obj);
> }
> +
> </programlisting>
> </para>
Maybe XML was not the better example to put in the manual :)
> <programlisting>
> - xml_as_object *xml_obj = (xml_as_object*)fn.this_ptr;
> + xml_as_object *xml_obj = static_cast < xml_as_object* >
> (fn.this_ptr);
These are both bad. And both doing the same thing, btw.
What we want here is a run-time check.
In the latest versions I took the habit of using an 'type*
ensureType(as_object* obj)'
function to take care of checking and eventually raise an exception.
Calling *any* function with an unexpected 'this' pointer is *always* an invalid
call and ActionException is cought at appropriate places to simply make the
function return 'undefined.
See for example array.cpp, or string.cpp.
> if (fn.nargs) {
> - filespec = fn.env->bottom(fn.first_arg_bottom_index).to_string;
> + filespec =
> fn.env->bottom(fn.first_arg_bottom_index).to_string();
Hard to read (still XML ?) but I belive it means fn.arg(0).to_string();
...
I'm happy you started, as it's still a lot of work to do ;)
--strk;
Message not available