Hello, is it possible to code a wxWidgets GUI in C++ and pass the whole wxApp or just single windows to embedded Ruby code? This would be very nice to provide a scriptable plugin system. Greetings, Niklas _______________________________________________ wxruby-users mailing list wxruby-users@rubyforge.org http://rubyforge.org/mailman/listinfo/wxruby-users
Is it possible? Yes. How can you do it? I haven''t a clue. Basically, you would need to wrap the widgets you want available on the Ruby Side, through the wxRuby controls, using the Swigified Wrappers to create the objects, and so forth. Sorry, it''s not been a very much explored system, and I wouldn''t have a clue in how to do it. On Fri, Sep 12, 2008 at 12:25 PM, Niklas Baumstark < niklas.baumstark at googlemail.com> wrote:> Hello, > > is it possible to code a wxWidgets GUI in C++ and pass the whole wxApp or > just single windows to embedded Ruby code? This would be very nice to > provide a scriptable plugin system. > > Greetings, > Niklas > > _______________________________________________ > wxruby-users mailing list > wxruby-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/wxruby-users >-- Mario Steele http://www.trilake.net http://www.ruby-im.net http://rubyforge.org/projects/wxruby/ http://rubyforge.org/projects/wxride/ -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20080912/a6e049c9/attachment.html>
Hello, "Mario Steele" <mario at ruby-im.net> wrote:> Is it possible? Yes. How can you do it? I haven''t a clue. Basically, you > would need to wrap the widgets you want available on the Ruby Side, through > the wxRuby controls, using the Swigified Wrappers to create the objects, and > so forth. > > Sorry, it''s not been a very much explored system, and I wouldn''t have a clue > in how to do it.OK, thanks for you answer. Maybe I''ll dive a bit into it to try. Greetings, Niklas -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20080913/6f69226f/attachment-0001.bin>
Hello, as announced, I played a bit around with swig and now seem to have found a first solution for my embedded ruby GUI plugin system. So far, I managed to wrap a C++ wxWindow object into a ruby Wx::Window object. I had to do a change to the wxRuby source to add a "wxWindow_to_ruby" function to the SWIG interface file for wxWindow (Window.i). Below is the (necessary?) code change and some example code based on the minimal.cpp, where i abused the about dialog to test my code. ===== SAMPLE START ==== ======================================================== Append to the bottom of "wxruby2/swig/classes/Window.i": ======================================================== %{ VALUE wxWindow_to_ruby(wxWindow* w) { return SWIG_NewPointerObj( (void *) w, SWIGTYPE_p_wxWindow, 0); } %} ============================================ My sample app (it''s a modified minimal.cpp): ============================================ ... #include <ruby.h> extern "C" void Init_wxruby2(); extern "C" void Init_wxWindow(); extern VALUE wxWindow_to_ruby(wxWindow* w); ... void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { ruby_init(); ruby_init_loadpath(); // the ruby file is in a sub-directory rb_eval_string(" $: << ''src'' "); ruby_script("embed"); Init_wxruby2(); Init_wxWindow(); VALUE rubyWindow = wxWindow_to_ruby(this); cout << "Window in C++: " << rubyWindow << endl; rb_define_variable("$window", &rubyWindow); rb_require("ruby_test.rb"); ruby_finalize(); } ================= the ruby_test.rb: ================= if $0 != "embed" puts "WARNING: this script is supposed to be run only from ''embed''" exit end puts "Window in ruby: " + $window.inspect puts "Name of the window: " + $window.get_name ================= the output ================= Window in C++: 3019414920 Window in ruby: #<Wxruby2::Window:0xb3f89d88> Name of the window: frame ===== SAMPLE END ==== the linker has to be told to link to wxruby2.so, wxwidgets and ruby, of course. i share this because it may be of some use for someone. i think this seems fine for a first attempt, but * it is limited to be used with a wxWindow / Wx::Window and not at all generic. * the ruby script doesn''t know about wxRuby. It just gets the raw Wx::Window object. it can''t use $window.name instead of $window.get_name, for instance, and it can''t access it''s non-trivial members, because the corresponding types are not initialized. i didn''t figure out a way to setup the whole wxRuby namespace in one rush (i would have to call every single Init_XY). the wx.rb could probably be included via rb_eval_string or something similiar for the sugar functionalities. didn''t try it yet, however. * less important: the wxruby2.so has a size of 40MB. is it statically linked against wxWidgets? If so, can this easily be turned off? It would be great if someone has an idea on how to solve (some of) these problems. Greetings, Niklas -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20080914/a5142012/attachment.bin>
Hi Niklas Niklas Baumstark wrote:> as announced, I played a bit around with swig and now seem to have found a first solution for my embedded ruby GUI plugin system. So far, I managed to wrap a C++ wxWindow object into a ruby Wx::Window object. >Broadly, I think you should be able to use almost all of the existing wxRuby SWIG etc codebase in an embedded setting. The main things that will need to change are the library initialisation code (in swig/wx.i) and the Wx::App initialisation code (in swig/classes/App.i) . You will in some way need to link the wx C++ App object to a ruby instance and make it a constant (like Wx::THE_APP in wxRuby). Having the App as a constant is the link that wxRuby uses to protect long-lived C++ objects like Windows from Ruby''s garbage collection (see mark_wxApp).> ===== SAMPLE START ====....> * it is limited to be used with a wxWindow / Wx::Window and not at all generic. >Take a look at the function wxRuby_WrapWxObjectInRuby in swig/wx.i - this does exactly what you want. It uses wxWidgets type-information system to wrap a C++ object in the correct ruby class. It is applied to (almost) all methods in wxWidgets that return wxWindow* by a typemap.> * the ruby script doesn''t know about wxRuby. It just gets the raw > Wx::Window object. it can''t use $window.name instead of > $window.get_name, for instance, and it can''t access it''s non-trivial > members, because the corresponding types are not initialized. > i didn''t figure out a way to setup the whole wxRuby namespace in one rush > (i would have to call every single Init_XY).SWIG''s support for multi-module libraries is weak so wxRuby has to work around this by massaging the default generated code. The rake build system (in rake/rakewx.rb) appends a function called InitializeOtherModules to the generated file src/wx.cpp that initialises all the other modules, in alphabetic order. This is then called in Init_wxruby (in swig/wx.i). The other important thing is that each class should not be initialised before its parent class. The script swig/fixmodule.rb adds a line to each generated cpp file that calls Init_wx[PARENTCLASS] before proceeding with initialising self.> the wx.rb could probably be included via rb_eval_string or something > similiar for the sugar functionalities. didn''t try it yet, however. >The ruby API function you want is rb_require. Some of the things in the ruby code are not just "sugar" but needed to make the classes work properly - eg GC helpers.> * less important: the wxruby2.so has a size of 40MB. is it statically > linked against wxWidgets? If so, can this easily be turned off?You could try strip -x to reduce the size. But SWIG adds a lot of overhead - the same runtime code is repeated and compiled for each SWIG class. I estimate that just getting round that would reduce the library size by about a third. On Linux and OS X at least - haven''t tried with Windows - you can have a wxRuby that is dynamically linked. If you have a dynamic build available, either have wx-config point to it by default, or pass WXRUBY_DYNAMIC=1 as an environment variable to rake. Happy to help further but may be better to follow-up on the wxruby-dev list as this is fairly technical.... cheers alex
Hello, Alex Fenton <alex at pressure.to> wrote:> Hi Niklas > > Niklas Baumstark wrote: > > as announced, I played a bit around with swig and now seem to have found a first solution for my embedded ruby GUI plugin system. So far, I managed to wrap a C++ wxWindow object into a ruby Wx::Window object. > > > > Broadly, I think you should be able to use almost all of the existing > wxRuby SWIG etc codebase in an embedded setting. The main things that > will need to change are the library initialisation code (in swig/wx.i) > and the Wx::App initialisation code (in swig/classes/App.i) . > > You will in some way need to link the wx C++ App object to a ruby > instance and make it a constant (like Wx::THE_APP in wxRuby). Having the > App as a constant is the link that wxRuby uses to protect long-lived C++ > objects like Windows from Ruby''s garbage collection (see mark_wxApp).OK, this is more sophisticated than i need it. i just need to wrap a wxPanel, because the main interface is managed by C++.> Take a look at the function wxRuby_WrapWxObjectInRuby in swig/wx.i - > this does exactly what you want. It uses wxWidgets type-information > system to wrap a C++ object in the correct ruby class. > It is applied to (almost) all methods in wxWidgets that return wxWindow* > by a typemap.oh, very nice, this function is what i was searching for :) by mario''s answer i guessed it would not exist so i tried to write one by myself.> > * the ruby script doesn''t know about wxRuby. It just gets the raw > > Wx::Window object. it can''t use $window.name instead of > > $window.get_name, for instance, and it can''t access it''s non-trivial > > members, because the corresponding types are not initialized. > > i didn''t figure out a way to setup the whole wxRuby namespace in one rush > > (i would have to call every single Init_XY). > > SWIG''s support for multi-module libraries is weak so wxRuby has to work > around this by massaging the default generated code. > > The rake build system (in rake/rakewx.rb) appends a function called > InitializeOtherModules to the generated file src/wx.cpp that initialises > all the other modules, in alphabetic order. This is then called in > Init_wxruby (in swig/wx.i).OK good to know.> The other important thing is that each class should not be initialised > before its parent class. The script swig/fixmodule.rb adds a line to > each generated cpp file that calls Init_wx[PARENTCLASS] before > proceeding with initialising self.i discovered this already.> > the wx.rb could probably be included via rb_eval_string or something > > similiar for the sugar functionalities. didn''t try it yet, however. > >> The ruby API function you want is rb_require. Some of the things in the > ruby code are not just "sugar" but needed to make the classes work > properly - eg GC helpers.another one good to know.> > * less important: the wxruby2.so has a size of 40MB. is it statically > > linked against wxWidgets? If so, can this easily be turned off? > > You could try strip -x to reduce the size. But SWIG adds a lot of > overhead - the same runtime code is repeated and compiled for each SWIG > class. I estimate that just getting round that would reduce the library > size by about a third. > > On Linux and OS X at least - haven''t tried with Windows - you can have a > wxRuby that is dynamically linked. If you have a dynamic build > available, either have wx-config point to it by default, or pass > WXRUBY_DYNAMIC=1 as an environment variable to rake.I''ll try this. thank you very much!> Happy to help further but may be better to follow-up on the wxruby-dev > list as this is fairly technical....I would like to, but i can''t subscribe to it properly. It says 403 when i want to confirm the subscription :( at least it did yesterday. Greetings, Niklas -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20080915/a7982288/attachment.bin>
Niklas Baumstark wrote:>> >> You will in some way need to link the wx C++ App object to a ruby >> instance and make it a constant (like Wx::THE_APP in wxRuby). Having the >> App as a constant is the link that wxRuby uses to protect long-lived C++ >> objects like Windows from Ruby''s garbage collection (see mark_wxApp). >> > > OK, this is more sophisticated than i need it. i just need to wrap a wxPanel, because the main interface is managed by C++. >OK, but to avoid leaks, or crashes from prematurely deleted objects, you will need some sort of memory management strategy. It gets quite complicated but most of the work is done ;)>> Happy to help further but may be better to follow-up on the wxruby-dev >> list as this is fairly technical.... >> > > I would like to, but i can''t subscribe to it properly. It says 403 when i want to confirm the subscription :( at least it did yesterday. >Just tried it and it seems to be working. If clicking on the link from the email make sure the URL isn''t truncated as it contains an authentication string. alex
Hello, Alex Fenton <alex at pressure.to> wrote:> Niklas Baumstark wrote: > >> > >> You will in some way need to link the wx C++ App object to a ruby > >> instance and make it a constant (like Wx::THE_APP in wxRuby). Having the > >> App as a constant is the link that wxRuby uses to protect long-lived C++ > >> objects like Windows from Ruby''s garbage collection (see mark_wxApp). > >> > > > > OK, this is more sophisticated than i need it. i just need to wrap a wxPanel, because the main interface is managed by C++. > > > > OK, but to avoid leaks, or crashes from prematurely deleted objects, you > will need some sort of memory management strategy. It gets quite > complicated but most of the work is done ;)I''ll try to. thank you for the information.> >> Happy to help further but may be better to follow-up on the wxruby-dev > >> list as this is fairly technical.... > >> > > > > I would like to, but i can''t subscribe to it properly. It says 403 when i want to confirm the subscription :( at least it did yesterday. > > > > Just tried it and it seems to be working. If clicking on the link from > the email make sure the URL isn''t truncated as it contains an > authentication string.Yeah it''s working now. I will ask future questions on this subjects on the dev mailing list. Greetings, Niklas -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: not available URL: <http://rubyforge.org/pipermail/wxruby-users/attachments/20080915/3a6989b7/attachment.bin>