I spent the last week working on the WtRuby bindings and have made good
progress:

* The Wt:: and Wt::Chart:: classes are all wrapped in a 'Smoke' library
'libsmokewt' (140 classes)
* The Wt::Ext:: classes are wrapped in another Smoke library 'libsmokewtext'
(30 classes)
* Each of these libraries has a corresponding Ruby extension, 'wt' and
'wtext'
* I've removed all Qt dependencies, and the WtRuby runtime now only requires
boost and Wt
* I've implemented marshallers to and from Ruby, for std::strings, WStrings
and the various std::vector types used in Wt
* EventSignals can be connected to a Ruby instance/method with connect(),
and emit() called on them too.
* boost::any in C++ is Boost::Any in Ruby
* The hello world application runs! Please find the source attached.

Some notes on the hello.rb source:

You pass a block to Wt::WRun with code to create your application each time
a new uses connects to the web app:

Wt::WRun(ARGV) do |env|
  HelloApplication.new(env)
end

Connecting an event signal to a slot looks like this:

    @nameEdit.enterPressed.connect(SLOT(self, :greet))

You can pass a block to constructors in WtRuby, like this one to create a
button:

    button = Wt::WPushButton.new("Greet me.", root) do |b|
      b.setMargin(Wt::WLength.new(5), Wt::WWidget::Left)
    end

Then in the block you can set up various intialization options like the
margin. Note that Ruby doesn't have implicit constructors like C++ and a
WLength must be constructed here as an argument to setMargin(), whereas in
C++ you can just pass a literal 5.

I need to make some changes to the Wt sources to get the bindings code
generation working (see attached 'wt_ruby.patch'):

* In Wt/Ext/TextEdit the resize() virtual method has a different signature
to the one it is overriding and I got 'hidden virtual method' warnings and
code gen problems.

I changed:
void TextEdit::resize(const WLength& width, const WLength& height)

To:
void TextEdit::resize(WLength width, WLength height)

* There was a similar problem with the layout() virtual method changing its
signature from const to non-const. I could only get the code gen to work by
making it always non-const.
* Wt/Ext/Widget has a private pure virtual method createJS(). which caused
code gen problems, and I could only get it to work by making it protected
* Forward class declarations and extra includes needed to be added to some
headers, to make them compile in the generated code.

When I tried the standard multi-threaded wthttp library with Ruby, it didn't
work and Ruby threw stack overflow exceptions, and I needed to build a
single threaded version. I couldn't get the cmake option
'-DMULTI_THREADED=off' to work, and so I had to hack the cmake link.txt
files to remove the compile option '-DTHREADED'. I also needed to  make some
small changes to the WServer.C file to get it to work (please see
wt_http_threaded.patch).

TODO:
* Translate as many of the examples as possible to Ruby and fix any problems
that arise.
* Implement Javascript slots/signals
* Implement non-EventSignal C++ slots/signals
* Allow the the various sorts of signals to be defined in Ruby.
* Package the two libraries and two Ruby extensions, and perl code generator
code and put in a WtRuby project on Rubyforge.

So that's it so far - I'm quite excited about how well it seems to work, and
have just downloaded the Ext 2.0 java script widgets to try out which will
be very interesting. Although the project isn't quite ready to release, I
can tar up the sources and mail them to anyone who is interested in trying
it out.

-- Richard

Attachment: hello.rb
Description: application/ruby

diff -Naur Wt/Ext/TextEdit Wt.patched/Ext/TextEdit
--- Wt/Ext/TextEdit	2008-07-25 12:22:06.000000000 +0100
+++ Wt.patched/Ext/TextEdit	2008-08-27 18:15:38.000000000 +0100
@@ -78,7 +78,7 @@
    */
   void setEnableSourceEdit(bool enable);
 
-  virtual void resize(const WLength& width, const WLength& height);
+  virtual void resize(WLength width, WLength height);
   
   virtual WValidator::State validate();
 
diff -Naur Wt/Ext/TextEdit.C Wt.patched/Ext/TextEdit.C
--- Wt/Ext/TextEdit.C	2008-07-15 07:25:55.000000000 +0100
+++ Wt.patched/Ext/TextEdit.C	2008-08-27 18:15:55.000000000 +0100
@@ -121,7 +121,7 @@
     return WValidator::Valid;
 }
 
-void TextEdit::resize(const WLength& width, const WLength& height)
+void TextEdit::resize(WLength width, WLength height)
 {
   textArea_->resize(width, height);
 }
diff -Naur Wt/Ext/Widget Wt.patched/Ext/Widget
--- Wt/Ext/Widget	2008-07-15 07:25:56.000000000 +0100
+++ Wt.patched/Ext/Widget	2008-08-27 17:56:48.000000000 +0100
@@ -57,7 +57,7 @@
 
   bool isRendered() const { return rendered_; }
 
-private:
+protected:
   virtual std::string createJS(DomElement *inContainer) = 0;
 
 protected:
diff -Naur Wt/WCompositeWidget Wt.patched/WCompositeWidget
--- Wt/WCompositeWidget	2008-07-15 07:25:47.000000000 +0100
+++ Wt.patched/WCompositeWidget	2008-08-27 18:20:15.000000000 +0100
@@ -96,7 +96,7 @@
   WWidget *impl_;
 
   virtual void setLayout(WLayout *layout);
-  virtual WLayout *layout() const;
+  virtual WLayout *layout();
   virtual WLayoutItemImpl *createLayoutItemImpl(WLayoutItem *layoutItem);
 };
 
diff -Naur Wt/WCompositeWidget.C Wt.patched/WCompositeWidget.C
--- Wt/WCompositeWidget.C	2008-07-15 07:25:47.000000000 +0100
+++ Wt.patched/WCompositeWidget.C	2008-08-27 18:20:25.000000000 +0100
@@ -304,7 +304,7 @@
   impl_->setLayout(layout);
 }
 
-WLayout *WCompositeWidget::layout() const
+WLayout *WCompositeWidget::layout()
 {
   return impl_->layout();
 }
diff -Naur Wt/WMenuItem Wt.patched/WMenuItem
--- Wt/WMenuItem	2008-07-15 07:25:49.000000000 +0100
+++ Wt.patched/WMenuItem	2008-08-27 17:57:55.000000000 +0100
@@ -8,12 +8,14 @@
 #define WMENU_ITEM_H_
 
 #include <Wt/WObject>
+#include <Wt/WString>
 
 namespace Wt {
 
 class WContainerWidget;
 class WMenu;
 class WWidget;
+class SignalBase;
 
 /*! \brief A single item in a menu.
  *
diff -Naur Wt/WTableColumn Wt.patched/WTableColumn
--- Wt/WTableColumn	2008-07-15 07:25:51.000000000 +0100
+++ Wt.patched/WTableColumn	2008-08-27 17:58:23.000000000 +0100
@@ -13,6 +13,7 @@
 
 class DomElement;
 class WTable;
+class WLength;
 
 /*! \class WTableColumn Wt/WTableColumn Wt/WTableColumn
  *  \brief A column in a WTable
diff -Naur Wt/WTextEdit Wt.patched/WTextEdit
--- Wt/WTextEdit	2008-07-25 12:22:06.000000000 +0100
+++ Wt.patched/WTextEdit	2008-08-27 18:17:20.000000000 +0100
@@ -133,7 +133,7 @@
    */
   const std::string& toolBar(int i) { return buttons_[i]; }
 
-  void resize(const WLength& width, const WLength& height);
+  void resize(WLength width, WLength height);
 
 private:
   bool        rendered_, contentChanged_;
diff -Naur Wt/WTextEdit.C Wt.patched/WTextEdit.C
--- Wt/WTextEdit.C	2008-07-25 15:43:55.000000000 +0100
+++ Wt.patched/WTextEdit.C	2008-08-27 18:17:37.000000000 +0100
@@ -109,7 +109,7 @@
   }
 }
 
-void WTextEdit::resize(const WLength& width, const WLength& height)
+void WTextEdit::resize(WLength width, WLength height)
 {
   WTextArea::resize(width, height);
 }
diff -Naur Wt/WVirtualImage Wt.patched/WVirtualImage
--- Wt/WVirtualImage	2008-07-15 07:25:53.000000000 +0100
+++ Wt.patched/WVirtualImage	2008-08-27 17:59:55.000000000 +0100
@@ -14,6 +14,7 @@
 namespace Wt {
 
 class WImage;
+class WMouseEvent;
 
 /*! \class WVirtualImage Wt/WVirtualImage Wt/WVirtualImage
  *  \brief An abstract widget that shows a viewport to a virtually large image.
diff -Naur Wt/WWidget Wt.patched/WWidget
--- Wt/WWidget	2008-07-22 07:03:07.000000000 +0100
+++ Wt.patched/WWidget	2008-08-27 18:03:49.000000000 +0100
@@ -826,7 +826,7 @@
   void undoHideShow();
 
   virtual WLayoutItemImpl  *createLayoutItemImpl(WLayoutItem *layout);
-  virtual WLayout          *layout() const;
+  virtual WLayout          *layout();
 
   friend class WebRenderer;
 
diff -Naur Wt/WWidget.C Wt.patched/WWidget.C
--- Wt/WWidget.C	2008-07-15 07:25:53.000000000 +0100
+++ Wt.patched/WWidget.C	2008-08-27 18:03:58.000000000 +0100
@@ -199,7 +199,7 @@
   layout->setParent(this);
 }
 
-WLayout *WWidget::layout() const
+WLayout *WWidget::layout()
 {
   return 0;
 }
diff -Naur http/WServer.C http.patched/WServer.C
--- http/WServer.C	2008-07-15 09:55:04.000000000 +0100
+++ http.patched/WServer.C	2008-08-29 13:11:20.000000000 +0100
@@ -46,11 +46,13 @@
 #include "WebController.h"
 #include "HTTPStream.h"
 
+#ifdef THREADED
 #ifdef BOOST_ASIO
     typedef boost::thread thread_t;
 #else
     typedef asio::thread thread_t;
 #endif
+#endif
 
 namespace Wt {
 
@@ -72,7 +74,9 @@
   http::server::Configuration  serverConfiguration_;
   http::server::Server        *server_;
 
+#ifdef THREADED
   thread_t **threads_;
+#endif
 };
 
 WServer::WServer(const std::string& applicationPath,
@@ -200,6 +204,7 @@
     // Stop the server.
     impl_->server_->stop();
 
+#ifdef THREADED
     int NUM_THREADS = impl_->serverConfiguration_.threads();
     for (int i = 0; i < NUM_THREADS; ++i) {
       impl_->threads_[i]->join();
@@ -208,6 +213,7 @@
 
     delete[] impl_->threads_;
     impl_->threads_ = 0;
+#endif
 
     delete impl_->server_;
     impl_->server_ = 0;
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
witty-interest mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/witty-interest

Reply via email to