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>
Maybe Matching 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
