nobody at rubyforge.org
2007-May-21 18:36 UTC
[Wxruby-development] [1022] trunk/wxruby2/swig/classes/App.i: Memory mgmt: use Wx::App to mark still-alive Windows, set up Wx::THE_APP const
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:'':'';} #msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[1022] trunk/wxruby2/swig/classes/App.i: Memory mgmt: use Wx::App to mark still-alive Windows, set up Wx::THE_APP const</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1022</dd> <dt>Author</dt> <dd>brokentoy</dd> <dt>Date</dt> <dd>2007-05-21 14:36:03 -0400 (Mon, 21 May 2007)</dd> </dl> <h3>Log Message</h3> <pre>Memory mgmt: use Wx::App to mark still-alive Windows, set up Wx::THE_APP const</pre> <h3>Modified Paths</h3> <ul> <li><a href="#trunkwxruby2swigclassesAppi">trunk/wxruby2/swig/classes/App.i</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="trunkwxruby2swigclassesAppi"></a> <div class="modfile"><h4>Modified: trunk/wxruby2/swig/classes/App.i (1021 => 1022)</h4> <pre class="diff"><span> <span class="info">--- trunk/wxruby2/swig/classes/App.i        2007-05-21 18:35:15 UTC (rev 1021) +++ trunk/wxruby2/swig/classes/App.i        2007-05-21 18:36:03 UTC (rev 1022) </span><span class="lines">@@ -1,5 +1,5 @@ </span><del>-# Copyright 2004-2005 by Kevin Smith -# released under the MIT-style wxruby2 license </del><ins>+// Copyright 2004-2007 by Kevin Smith +// released under the MIT-like wxRuby license </ins><span class="cx"> </span><span class="cx"> %include "../common.i" </span><span class="cx"> </span><span class="lines">@@ -32,6 +32,8 @@ </span><span class="cx"> %{ </span><span class="cx"> </span><span class="cx"> extern swig_class cWxEvtHandler; </span><ins>+extern swig_class cWxWindow; +extern swig_class cWxEvent; </ins><span class="cx"> extern "C" void Init_wxRubyStockObjects(); </span><span class="cx"> </span><span class="cx"> </span><span class="lines">@@ -39,22 +41,81 @@ </span><span class="cx"> { </span><span class="cx"> </span><span class="cx"> public: </span><del>- static VALUE app_ptr; </del><span class="cx"> </span><span class="cx"> </span><del>- virtual ~wxRubyApp() - { </del><ins>+ virtual ~wxRubyApp() + { </ins><span class="cx"> #ifdef __WXDEBUG__ </span><del>- printf("~wxRubyApp\n"); </del><ins>+        printf("~wxRubyApp\n"); </ins><span class="cx"> #endif         </span><span class="cx"> } </span><span class="cx"> </span><ins>+ // special event handler for destruction of windows which is done + // automatically by wxWidgets. Tag the object as having been destroyed + // by WxWidgets. + void OnWindowDestroy(wxWindowDestroyEvent &event) + { +        wxObject* wx_obj = event.GetEventObject(); +        // Would be neater - but can''t do it this way b/c of destruction sequence +        // SWIG_RubyUnlinkObjects((void *)wx_obj); + +        VALUE rb_obj = SWIG_RubyInstanceFor((void *)wx_obj); +        rb_iv_set(rb_obj, "@__wx_destroyed__", Qtrue); +        event.Skip(); + } + + + static VALUE mark_iterate(VALUE pair, VALUE arg, VALUE self) + { +        VALUE key, val; + +        key = rb_ary_entry(pair, 0); +        val = rb_ary_entry(pair, 1); +        VALUE rb_obj = SWIG_RubyReferenceToObject(val); +        // Check if it''s a descendant of Wx::Window, and if it has not yet been +        // deleted by WxWidgets. +        if ( rb_obj_is_kind_of(rb_obj, cWxWindow.klass) && +                 rb_iv_get(rb_obj, "@__wx_destroyed__") != Qtrue ) +         { +                rb_gc_mark(rb_obj); +         } +        return Qnil; + } + + static void mark_wxRubyApp(void *ptr) + { + +#ifdef __WXDEBUG__ +        printf("=== Starting App GC mark phase\n"); +#endif + +        // If the App has ended, the ruby object will have been unlinked from +        // the C++ one; this implies that all Windows have already been destroyed +        // so there is no point trying to mark them, and doing so may cause +        // errors. +        VALUE the_app = rb_const_get(mWxruby2, rb_intern("THE_APP")); +        if ( DATA_PTR(the_app) == 0 ) +         { +                return; +         } + +        rb_iterate(rb_each, swig_ruby_trackings, (VALUE(*)(...))mark_iterate, Qnil); +#ifdef __WXDEBUG__ + printf("=== App GC mark phase completed\n"); +#endif + + } + </ins><span class="cx"> // This is the method run when main_loop is called in Ruby </span><span class="cx"> // wxEntry calls the C++ App::OnInit method </span><span class="cx"> int main_loop() </span><span class="cx"> { </span><del>- static int argc = 1; - static wxChar *argv[] = {wxT("wxruby"), NULL}; </del><ins>+         rb_define_const(mWxruby2, "THE_APP", SWIG_RubyInstanceFor(this)); +         static int argc = 1; +         static wxChar *argv[] = {wxT("wxruby"), NULL}; +         this->Connect(wxEVT_DESTROY, +                                        wxWindowDestroyEventHandler(wxRubyApp::OnWindowDestroy)); + </ins><span class="cx"> #ifdef __WXDEBUG__ </span><span class="cx"> printf("Calling wxEntry, this=%p\n", this); </span><span class="cx"> #endif </span><span class="lines">@@ -88,7 +149,8 @@ </span><span class="cx"> bool OnInit() </span><span class="cx"> { </span><span class="cx"> Init_wxRubyStockObjects(); </span><del>-         VALUE result = rb_funcall(wxRubyApp::app_ptr, rb_intern("on_init"), 0, NULL); </del><ins>+         VALUE the_app = rb_const_get(mWxruby2, rb_intern("THE_APP")); +         VALUE result = rb_funcall(the_app, rb_intern("on_init"), 0, NULL); </ins><span class="cx">          if ( result == Qfalse || result == Qnil ) { </span><span class="cx">                 return false; </span><span class="cx">          } </span><span class="lines">@@ -101,27 +163,23 @@ </span><span class="cx"> { </span><span class="cx"> </span><span class="cx"> </span><del>-#ifdef __WXDEBUG__ </del><ins>+#ifdef __WXDEBUG__         </ins><span class="cx"> printf("OnExit...\n"); </span><del>-#endif         - rb_gc_start(); -#ifdef __WXDEBUG__         - printf("survived gc\n"); -#endif </del><ins>+#endif </ins><span class="cx"> </span><ins>+                // unhook the App ruby object from the C++ object +                SWIG_RubyUnlinkObjects((void *)this); + </ins><span class="cx"> wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr); </span><span class="cx"> SetTopWindow(0); </span><span class="cx"> if ( oldlog ) </span><del>- { -#ifdef __WXDEBUG__ -         printf("Deleting oldlog...\n"); -#endif         - delete oldlog; -#ifdef __WXDEBUG__         - printf("worked\n"); -#endif         - } </del><ins>+                 { +                        delete oldlog; +                         +                 } + </ins><span class="cx"> return 0; </span><ins>+                 </ins><span class="cx"> } </span><span class="cx">          </span><span class="cx"> // actually implemented in ruby in classes/app.rb </span><span class="lines">@@ -132,10 +190,10 @@ </span><span class="cx"> </span><span class="cx"> }; </span><span class="cx"> </span><del>-VALUE wxRubyApp::app_ptr = Qnil; - </del><span class="cx"> %} </span><span class="cx"> </span><ins>+%markfunc wxRubyApp "wxRubyApp::mark_wxRubyApp"; + </ins><span class="cx"> class wxRubyApp : public wxApp </span><span class="cx"> { </span><span class="cx"> public: </span></span></pre> </div> </div> </body> </html>
Reasonably Related Threads
- [1136] trunk/wxruby2/swig/classes/App.i: Note when the Wx::App is exiting and avoid doing GC if in process of
- [898] branches/wxruby2/wxwidgets_282/swig/classes/App.i: Fix init of stock objects for Wx2.8 - was causing infinite loop +crash on OS X
- [1025] trunk/wxruby2/swig: Use Wx::THE_APP constant as global reference to App (as per WxWidgets);
- [1109] trunk/wxruby2/swig: Move marking of MenuBar from direct %markfunc to via mark_wxFrame, so
- [1070] trunk/wxruby2/swig/fixdeleting.rb: Remove old, now unused, fixdeleting script