Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion Firing an event with a reference to a FB::JSObject

Received: by 10.68.190.104 with SMTP id gp8mr10985143pbc.4.1341243962259;
        Mon, 02 Jul 2012 08:46:02 -0700 (PDT)
X-BeenThere: firebreath-dev@googlegroups.com
Received: by 10.68.211.194 with SMTP id ne2ls19963481pbc.9.gmail; Mon, 02 Jul
 2012 08:46:01 -0700 (PDT)
Received: by 10.68.223.73 with SMTP id qs9mr4889660pbc.7.1341243961481;
        Mon, 02 Jul 2012 08:46:01 -0700 (PDT)
Received: by 10.68.223.73 with SMTP id qs9mr4889658pbc.7.1341243961455;
        Mon, 02 Jul 2012 08:46:01 -0700 (PDT)
Return-Path: <rich...@batemansr.us>
Received: from mail-pb0-f49.google.com (mail-pb0-f49.google.com [209.85.160.49])
        by gmr-mx.google.com with ESMTPS id oh7si666136pbb.2.2012.07.02.08.46.01
        (version=TLSv1/SSLv3 cipher=OTHER);
        Mon, 02 Jul 2012 08:46:01 -0700 (PDT)
Received-SPF: temperror (google.com: error in processing during lookup of rich...@batemansr.us: DNS timeout) client-ip=209.85.160.49;
Authentication-Results: gmr-mx.google.com; spf=temperror (google.com: error in processing during lookup of rich...@batemansr.us: DNS timeout) smtp.mail=rich...@batemansr.us
Received: by pbbrq13 with SMTP id rq13so8264755pbb.8
        for <firebreath-dev@googlegroups.com>; Mon, 02 Jul 2012 08:46:01 -0700 (PDT)
        d=google.com; s=20120113;
        h=content-type:mime-version:subject:from:in-reply-to:date
         :content-transfer-encoding:message-id:references:to:x-mailer
         :x-gm-message-state;
        bh=JeMkRRTSZcH0d1W0gr0JCJid3nSwmJdql0L0bP9QLq4=;
        b=fzst53s+3ay57MdMXl2TmPvNxxL0bGIcn5vUHjJgchYecUFdGrnqlXrsaK9r6PsBwc
         dKSP/2U54evtg9dRUFzEb7QJYn6ZoOUYfFyYig4ClE9XyF7IpKsdjXWwueXkILmrOf1U
         zkcf5gZ+8xMWgLMkq01wO47bJXn2TKudBd0ASWgXgXfayU10ajOUUlriHIijBesSBKvh
         cKB3h9LVxCbf5xS3I9JVCEqwx3cr5dz7li8AitbjnlS6y0ezv0WTuwN1SeKLzSxO4YiA
         J4RIyMLjJZabqyYE5ezyp3Wrdkoon9/73QgEUaya62IaFuM8oItGgQWylqO3+DyRpj1l
         Ndjg==
Received: by 10.68.223.198 with SMTP id qw6mr31335744pbc.94.1341243960884;
        Mon, 02 Jul 2012 08:46:00 -0700 (PDT)
Return-Path: <rich...@batemansr.us>
Received: from [172.19.32.107] (70-90-213-98-utah-ut.hfc.comcastbusiness.net. [70.90.213.98])
        by mx.google.com with ESMTPS id pg3sm13264384pbc.2.2012.07.02.08.45.57
        (version=TLSv1/SSLv3 cipher=OTHER);
        Mon, 02 Jul 2012 08:45:59 -0700 (PDT)
Content-Type: text/plain; charset=us-ascii
Mime-Version: 1.0 (Apple Message framework v1278)
Subject: Re: [firebreath-dev] Firing an event with a reference to a FB::JSObject
From: Richard Bateman <rich...@batemansr.us>
In-Reply-To: <b56f8730-378e-4ed7-8cea-fe75be1e887f@googlegroups.com>
Date: Mon, 2 Jul 2012 09:45:56 -0600
Content-Transfer-Encoding: quoted-printable
Message-Id: <93A01EA9-1F0C-40AA-AEEF-1BB1D1773...@batemansr.us>
References: <b56f8730-378e-4ed7-8cea-fe75be1e887f@googlegroups.com>
To: firebreath-dev@googlegroups.com
X-Mailer: Apple Mail (2.1278)
X-Gm-Message-State: ALoCoQmDRSjf91jVKnqzmP9LbZRS/1VrF4TsbCqYRvSLgNoJcnIdFp2qs7fcaG4RW3aUZm/9OuoX


Comments in-line

On Jul 1, 2012, at 17:12 , Adrian C wrote:

> I have created a collection of scriptable objects by exposing in =
MyPluginAPI a property that returns an array, initialized like this:
> =20
> m_collection =3D m_host->getDOMWindow()->createArray();
> =20
> Then thanks to Richard, I learned how to push my custom objects into =
that array. I just defined my new class derived from JSAPIAuto and do =
this:
> =20
>     MyObjectPtr newMyObject =3D boost::make_shared<MyObject>(m_host, =
[...other constructor parameters...]));
>     m_collection->Invoke("push", FB::variant_list_of(newMyObject));
> =20
> All this works very well. I can browser the collection from =
JavaScript, use properties and invoke methods in the objects in the =
collection.
> =20
> Now I have a working thread that monitors changes and when they happen =
I want to fire an event that includes a reference to one of the items in =
the above collection. The working thread has access to a native C array =
provided by the OS API and the array defines an LPVOID member for each =
element of the array. So I wanted to use that pointer to reference each =
of the objects and when the event happens, try to use it in the call.
> =20
> First, to pass the objects from the main thread to the working thread, =
I created a shared_ptr to the original MyObjectPtr to cast it to LPVOID. =
I am not sure whether this is necessary or valid.
> =20
>     MyObjectPtr *ppMyObject =3D new MyObjectPtr(newMyObject);
>     m_rgNative[i].pvUserData =3D (void*)ppMyObject;

This is unneccesary and potentially dangerous.  The reference counting =
on boost::shared_ptr is threadsafe, though destruction is not.  That =
means that you're fine to access the ptr from another thread as long as =
you're careful with it (all normal rules for accessing the same object =
on multiple threads apply) but make sure that the last release happens =
on the main thread.

> Then in the workin thread, I try to get the pointer back to retrieve =
the reference to the object. I know that in COM you can't pass COM =
objects across threads without complex marshaling. Does one of the many =
fantastic features of Firebreath includes taking care of this?
> =20
>     MyObjectPtr *ppMyObject =3D =
(MyObjectPtr*)(m_rgNative[i].pvUserData);
>     MyObjectPtr theMyObject =3D *ppMyObject;
>     delete ppMyObject;
>     theMyObject->set_someproperty(value); <- this seems to work.

You're really over thinking this; it's just an object. This isn't COM, =
so you don't have to worry about that. However, make sure that anything =
that may be accessed from javascript or from your alternate thread are =
threadsafe.

> The last statement above seems to work, I can actually set properties =
in my custom object across threads. But I am not sure again if it's =
valid. Besides, I think it fails if the object is busy, so it might not =
be the correct solution to the interthread communication.

You can probably solve a lot of the potential issues simply by throwing =
a mutex into your getters, setters, and methods.=20

> And then, last, I have no clue how to reference the original object in =
the fire event method. For the time being, it's working fine if the =
event is defined as:
> =20
>     FB_JSAPI_EVENT(statuschange, 2, (const FB::variant&, const int));
> and fired from the working thread calling

This should work fine; FB::variant is actually what it will end up =
being.  If you do this then you can pass whatever (supported) type you =
want for the first parameter.

>     fire_statuschange(std::wstring(m_rgNative[i].szName), =
m_rgNative[i].dwCurrentState);
>=20
> But since I don't want a string, but a reference to the scriptable =
object, I tried to change the event definition to:
> =20
>      FB_JSAPI_EVENT(statuschange, 2, (const FB::JSObjectPtr&, const =
int));
> and fired from the working thread calling
>      fire_statuschange(theMyObject, m_rgNative[i].dwCurrentState);

This should work as well; if it doesn't, truy passing just a =
FB::JSObjectPtr without the const &; I don't know of a reason that the =
const & wouldn't work, but that's the only explanation I can think of.

One of your biggest issues is that you are seriously over-thinking the =
cross thread stuff.  Basically when you're dealing with multiple threads =
in normal C++ the only real concern is that you could have two things =
accessing it at the same time; if one changes something while another is =
running then you could run into some problems, and you could definitely =
have an issue if the last two shared_ptr instances go away at the same =
time on different threads because they could both try to destruct your =
object, but otherwise it's just a variable in memory shared between both =
threads. Note that fire_* will always fire that event on the main thread =
asynchronously.

An FB::JSObjectPtr object will also automatically cause all calls that =
modify data to happen on the main thread; this is usually good, but be =
aware that if you are doing a lot of operations one after another from a =
different thread you may want to wrap them all in a function and use =
m_host->CallOnMainThread to call it; each call that happens on the main =
thread adds a reasonably significant amount of delay to the call, so you =
can run into performance problems that way if you aren't careful.

Hope that helps,

Richard=