Re: [firebreath-dev] Support JS Object Construction in FireBreath

120 views
Skip to first unread message

Richard Bateman

unread,
May 24, 2013, 11:00:33 AM5/24/13
to firebre...@googlegroups.com

It would be awesome if you could put this on firebreath.org somewhere.  (in case you didn't know, firebreath.org is a wiki that anyone can edit)

Richard

On May 24, 2013, at 8:58 , Chang Shu <csh...@gmail.com> wrote:

Hi, all,

I have done some experiments in FireBreath to support JS binding for object construction, e.g. "new TestObj()" and made it work. I would like to share my experience with everyone in case you need to do the same thing in the future.

You must have known how to bind a function or an attribute to an existing class through "registerMethod" and "registerProperty", accordingly. The example can be found in FireBreath's auto-generated TestPlugin. To support creating a new object type, say "TestObj", you must first "registerProperty" with the name of the new class, "TestObj", and a function that returns an instance of another class "TestObjConstructor". This "TestObjConstructor" is also a JSAPIAuto-derived class and it should override the virtual function "Construct". In its "Construct" function, which is triggered each time the Javascript code calls "new TestObj()", it should return a new instance of "TestObj". This completes the support of JS object construction.

I have some experimental code based on MyTestPlugin generated by FireBreath, as shown below.

diff --git a/MyTestPluginAPI.cpp b/MyTestPluginAPI.cpp
index 8d17632..6b7a72e 100644
--- a/MyTestPluginAPI.cpp
+++ b/MyTestPluginAPI.cpp
@@ -60,6 +60,32 @@ std::string MyTestPluginAPI::get_version()
     return FBSTRING_PLUGIN_VERSION;
 }
 
+FB::variant MyTestPluginAPI::TestObjConstructor()
+{
+    return TestObjConstructor::getConstructor();
+}
+
+FB::JSAPIPtr TestObjConstructor::getConstructor()
+{
+    static FB::JSAPIPtr s_instance;
+    if (!s_instance.get()) {
+        s_instance = boost::make_shared<TestObjConstructor>();
+    }
+    return s_instance;
+}
+
+FB::variant TestObjConstructor::Construct(const std::vector<FB::variant> &args)
+{
+    boost::recursive_mutex::scoped_lock lock(m_zoneMutex);
+    if(!m_valid)
+        throw FB::object_invalidated();
+
+    if (args.size() < 1)
+        return boost::make_shared<TestObj>();
+
+    return boost::make_shared<TestObj>(args[0].convert_cast<int>());
+}
+
 void MyTestPluginAPI::testEvent()
 {
     fire_test();
diff --git a/MyTestPluginAPI.h b/MyTestPluginAPI.h
index ee4a41b..a7dc694 100644
--- a/MyTestPluginAPI.h
+++ b/MyTestPluginAPI.h
@@ -14,6 +14,27 @@
 #ifndef H_MyTestPluginAPI
 #define H_MyTestPluginAPI
 
+class TestObj : public FB::JSAPIAuto
+{
+public:
+    TestObj(int x = 0) : m_x(x) {
+        registerMethod("add",      make_method(this, &TestObj::add));
+        registerProperty("x", make_property(this, &TestObj::x, &TestObj::setX));
+    };
+    void add(int x) { m_x += x; };
+    int x() { return m_x; };
+    void setX(int x) { m_x = x; };
+private:
+    int m_x;
+};
+
+class TestObjConstructor : public FB::JSAPIAuto
+{
+public:
+    static FB::JSAPIPtr getConstructor();
+    virtual FB::variant Construct(const std::vector<FB::variant>& args);
+};
+
 class MyTestPluginAPI : public FB::JSAPIAuto
 {
 public:
@@ -44,6 +65,11 @@ public:
         registerProperty("version",
                          make_property(this,
                                        &MyTestPluginAPI::get_version));
+
+        // cshu's test
+        registerProperty("TestObj",
+                         make_property(this,
+                                       &MyTestPluginAPI::TestObjConstructor));
     }
 
     ///////////////////////////////////////////////////////////////////////////////
@@ -64,6 +90,9 @@ public:
     // Read-only property ${PROPERTY.ident}
     std::string get_version();
 
+    // cshu's test
+    FB::variant TestObjConstructor();
+
     // Method echo
     FB::variant echo(const FB::variant& msg);
     
-- 
The JS code could be:
        function testEvent()
        {
//            plugin().testEvent();
            var TestObj = plugin().TestObj;
            var t = new TestObj();
            t.x = 3;
            t.add(4);
            var t2 = new TestObj(2);
            t2.add(3);
            alert('should be 7, 5: ' + t.x + ', ' + t2.x);
        }

I hope the above is helpful and also would like to thank taxilian's help over IRC.

Thanks
cshu


--
 
---
You received this message because you are subscribed to the Google Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebreath-de...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

goutami kumbhar

unread,
May 30, 2013, 3:09:27 AM5/30/13
to firebre...@googlegroups.com
Hi,
    Thanks for sharing your implementation.

    Could you please tell me If your post could be helpful for exporting method from JavaScript in Firebreath which contains argument as object of another class.

Thanks & Regards,
GoutamiKumbhar

Richard Bateman

unread,
May 30, 2013, 11:07:28 AM5/30/13
to firebre...@googlegroups.com

Could you please explain what you mean by "contains argument as object of another class"? I don't understand what you're asking.

Richard

goutami kumbhar

unread,
May 31, 2013, 5:18:56 AM5/31/13
to firebre...@googlegroups.com
Hi,
    Thanks for the Reply !!!

    Suppose my ClassLibrary in C#
    

      namespace MyImage
     {
       public class DrawImage
      { 
        public void ShowImage(TestImage testImage)
        {
         }
     }
    public class TestImage 
   {
    }
  }

  Here I need to call the ShowImage(TestImage testImage) method from  JavaScript in firebreath through wrapper. Means here ShowImage() contains arguments as object of another class.

Please let me know if you have the solution related to the same.

Thanks & Regards,
GoutamiKumbhar




--
 
---
You received this message because you are subscribed to a topic in the Google Groups "firebreath-dev" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/firebreath-dev/Yhz97IF-_5g/unsubscribe?hl=en-US.
To unsubscribe from this group and all its topics, send an email to firebreath-de...@googlegroups.com.

John Tan

unread,
May 31, 2013, 5:26:40 AM5/31/13
to firebre...@googlegroups.com
I am amazed at your persistency on pursuing this matter.... ;-)

goutami kumbhar

unread,
May 31, 2013, 6:03:09 AM5/31/13
to firebre...@googlegroups.com
Because these are the things that I want to implement ..

John Dexter

unread,
May 31, 2013, 10:06:33 AM5/31/13
to firebre...@googlegroups.com
Your question doesn't seem to have anything to do with this discussion?


--

Neil Griffiths

unread,
May 31, 2013, 7:54:44 PM5/31/13
to firebre...@googlegroups.com
Create a DLL with your C# code in it and a C/C++ interface. Load that DLL from your FireBreath plugin and use the C/C++ interface that you defined.

goutami kumbhar

unread,
Jun 1, 2013, 2:37:54 AM6/1/13
to firebre...@googlegroups.com
Hi,
    Thanks for the reply.

     I have to create the complex class hirearchy in Firebreath which has the flow like C#-->C++CLI-->Firebreath-->Javascript.
      I have followed the same thing that you mentioned in the reply.
     Now the problem is I dont want to use the interface IWrapper from C++CLI .Code should be implemented only through Wrapper.cpp and Wrapper.h.
     It works well for simple hierarchy.But when I want to call some complex methods which includes the  class object as method argument in it then it doesnot work well.
    I dont know how to call that complex method in my Wrapper.h file. because When i pass the object as argument to the method then that .h file includes managed code and that raises the problem in the                       firebreath  as managed targeted code requires /clr option.

     Please let me know if you have the solution related to this.


      Thanks & Regards,
      GoutamiKumbhar
   
    

John Tan

unread,
Jun 1, 2013, 3:13:17 AM6/1/13
to firebre...@googlegroups.com
For some strange reason, this is the 3rd SAME postings you posted and you have not been listening to ANY of the advice given by a fellow FBers here.
 
An object from a C# is NOT the same as a C++. Which is why, people have been telling you that you need to do a translation to get it to work.

goutami kumbhar

unread,
Jun 1, 2013, 4:56:26 AM6/1/13
to firebre...@googlegroups.com
 I am Sorry but these are the things that I want to implement ..Sorry


--
 
---

Gaurav Raj

unread,
Jun 1, 2013, 6:03:17 AM6/1/13
to firebre...@googlegroups.com
Try converting your objects into transferrable data type and then pass it through the functions. Then reconstruct the object.


--
 
---
You received this message because you are subscribed to the Google Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebreath-de...@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Gaurav Raj

Gaurav Raj

unread,
Jun 1, 2013, 6:14:29 AM6/1/13
to firebre...@googlegroups.com
Can you elaborate what exactly are you doing in C#? If its possible you can do the same thing in C++ making things easier.
--
Gaurav Raj

Message has been deleted

John Tan

unread,
Jun 1, 2013, 8:45:27 AM6/1/13
to firebre...@googlegroups.com
Yes, wanting is one thing. Can or not is another. Asking a million times will not change whether or not it can be done.
You must understand, a plugin is not an independent application. It is an extension of a browser. As such, you must comply to what is exposed by the browser and how they are allowed to communicate with the browser. As of now, there are only 3 methods, ActiveX, NPAPI and PPAPI. ActiveX and NPAPI is mainly done in Native C/C++ (I somewhat remember it could be done in other language) but as far as Firebreath is concern, it's ONLY done in Native C++. As for PPAPI, it's specific to Chrome only and they are written in Java syntax with special compiler.
 

John Tan

unread,
Jun 1, 2013, 9:13:50 AM6/1/13
to firebre...@googlegroups.com
There are few things that I badly want too but not possible:
- Windowed Mac plugin
- Plugin loadable in Window8 Metro UI
- Window mode with HTML elements able to overlay the plugin.
- Windowless mode performing as fast as Windowed mode.
 
While there are some workaround with compromised result, some are downright not possible.

goutami kumbhar

unread,
Jun 1, 2013, 9:29:23 AM6/1/13
to firebre...@googlegroups.com
Hi,
     Thanks for the reply.
     please see below link :
     
    Here are the things which includes the method that contains the argument as object of another class.  Please let me know if you have any solution related to this.

   Thanks & Regards,
    GoutamiKumbhar

     

goutami kumbhar

unread,
Jun 1, 2013, 9:32:52 AM6/1/13
to firebre...@googlegroups.com
Hi,

I appreciate your knowledge  but still I am unsuccessful what I want to implement. So I am presistently pursuing in this matter.
Sorry.

Thanks & Regards,
 GoutamiKumbhar


On Sat, Jun 1, 2013 at 6:13 PM, John Tan <tjk...@gmail.com> wrote:
Yes, wanting is one thing. Can or not is another. Asking a million times will not change whether or not it can be done.
 
You must understand, a plugin is not an independent application. It is an extension of a browser. As such, you must comply to what is exposed by the browser and how they are allowed to communicate with the browser. As of now, there are only 3 methods, ActiveX, NPAPI and PPAPI. ActiveX and NPAPI is mainly done in Native C/C++ (I somewhat remember it could be done in other language) but as far as Firebreath is concern, it's ONLY done in Native C++. As for PPAPI, it's specific to Chrome only and they are written in Java syntax with special compiler.

Richard Bateman

unread,
Jun 1, 2013, 11:50:19 PM6/1/13
to firebre...@googlegroups.com

Let me see if I can help you understand why several of us are starting to get a little bit frustrated by your persistence.

1) This is not a FireBreath issue.  It isn't.  Let me repeat that: This issue has nothing directly to do with FireBreath.  The fact that you want to do it in a firebreath plugin is beside the point.

2) You ask a question, we answer it, and then you ask the same question again with no indication that you have done any work  following up on the answer.  We expect questions for clarification, or requests for help on some specific aspect of the solution we suggested.  Your questions reveal none of this.  You simply seem to be asking the same questions over and over again in every medium that you can, with no indication that any of the answers we give have helped in the slightest.

3) Your question is very broad.  We are a community of people who generally are fairly happy to help our peers, but "help" does not extend to "do it for you".  Your questions have generally been phrased like "I want to do x. Please show me how".  This sounds to most of us like "Hey guys, can someone do a bunch of free work for me?"


--

Let me now explain something.  FireBreath *does not* support the CLR. It never will. We *are not ever* going to give you an answer to your main question, because none of us know the answer and none of us feel up to spending the hours of work required to solve your problem for you.  In addition, that's your job, not ours.

IF YOU DON'T SHOW ANY SIGN OF USING THE ANSWERS WE HAVE GIVEN YOU, WE WILL NOT HELP YOU FURTHER.,

Said another way,

If you don't show any sign of using the answers we have given you, we will not help you further.

What you need to do is build a DLL that can be called from a normal C++ application (not firebreath, nothing special, no /clr) that calls the C# assembly that you want to use.

A quick google search reveals this: http://bit.ly/12nZ8K7

Everything that I would use to learn how to do this is returned in that query.  It's not a simple thing, so don't expect to figure it out after just a few lines of code.  Break the problem down, and then ask specific questions (in a forum that is actually relevant to what you're asking, so not here) about how to do that small piece.

DO NOT EVER REPEAT THE FULL QUESTION AFTER RECEIVING A GOOD ANSWER.  A good answer is one that gives you more information about what steps you'll need to take to solve the problem.


Once you have a C++ application that compiles *without* /CLR that can call your function, then take that function and copy it into a firebreath example and you'll probably be done.

I hope this is helpful in clearing up your confusion,

Richard Bateman
FireBreath principle author and project manager

Jun 1, 2013, в 07:32, goutami kumbhar <goutmi...@gmail.com> написал(а):

You received this message because you are subscribed to the Google Groups "firebreath-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to firebreath-de...@googlegroups.com.

John Tan

unread,
Jun 2, 2013, 12:38:49 AM6/2/13
to firebre...@googlegroups.com
Another thing to add.... Objects of native c++ and managed c++ are not transferable. Primitive variable is ok but not objects. They are only similar in syntax.

goutami kumbhar

unread,
Jun 3, 2013, 1:50:42 AM6/3/13
to firebre...@googlegroups.com
Hi,
    Sorry for my behaviour. As per your suggestion I will break down the problem and try to work out for specific things in parts.If I have the query related to the firebreath then I will post the specific question for it.
  
Thanks & Regards,
GoutamiKumbhar


On Sun, Jun 2, 2013 at 10:08 AM, John Tan <tjk...@gmail.com> wrote:
Another thing to add.... Objects of native c++ and managed c++ are not transferable. Primitive variable is ok but not objects. They are only similar in syntax.
Reply all
Reply to author
Forward
0 new messages