[Aptitude-svn-commit] r3754 - in branches/aptitude-0.3/aptitude: . src/vscreen

Daniel Burrows dburrows at costa.debian.org
Mon Aug 8 21:17:08 UTC 2005


Author: dburrows
Date: Mon Aug  8 21:17:04 2005
New Revision: 3754

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.h
   branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.h
   branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.h
   branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h
   branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.h
   branches/aptitude-0.3/aptitude/src/vscreen/vs_table.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_table.h
   branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.h
Log:
A new, sounder, safer, saner policy for destroying widgets.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Mon Aug  8 21:17:04 2005
@@ -1,5 +1,15 @@
 2005-08-08  Daniel Burrows  <dburrows at debian.org>
 
+	* src/vscreen/vs_bin.cc, src/vscreen/vs_bin.h, src/vscreen/vscreen_widget.cc, src/vscreen/vscreen_widget.h, src/vscreen/vs_menubar.cc, src/vscreen/vs_menubar.h, src/vscreen/vs_minibuf_win.cc, src/vscreen/vs_minibuf_win.h, src/vscreen/vs_multiplex.cc, src/vscreen/vs_multiplex.h, src/vscreen/vs_stacked.cc, src/vscreen/vs_stacked.h, src/vscreen/vs_table.cc, src/vscreen/vs_table.h:
+
+	  Create a new protocol for destroying widgets: a widget should
+	  destroy and disconnect all of its children immediately upon
+	  receiving destroy(), but the actual deletion of its instance
+	  might be deferred if strong references to it exist (for
+	  instance, if some information needs to be retrieved from it).
+
+	  The test program runs and exits without errors now.
+
 	* src/vscreen/vscreen_widget.cc:
 
 	  Only assert that we lost our window if we had an owner: owned

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.cc	Mon Aug  8 21:17:04 2005
@@ -53,6 +53,13 @@
   vscreen_queuelayout();
 }
 
+void vs_bin::destroy()
+{
+  set_subwidget(NULL);
+
+  vs_container::destroy();
+}
+
 void vs_bin::add_widget(const vs_widget_ref &w)
 {
   assert(!subwidget.valid());

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_bin.h	Mon Aug  8 21:17:04 2005
@@ -39,6 +39,8 @@
 
   vs_widget_ref get_subwidget() {return subwidget;}
 
+  void destroy();
+
   virtual void show_all();
 
   virtual void add_widget(const vs_widget_ref &w);

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.cc	Mon Aug  8 21:17:04 2005
@@ -25,6 +25,23 @@
 
 vs_menubar::~vs_menubar()
 {
+  assert(!subwidget.valid());
+  assert(items.empty());
+  assert(active_menus.empty());
+}
+
+void vs_menubar::destroy()
+{
+  set_subwidget(NULL);
+
+  for(vector<item>::const_iterator i = items.begin();
+      i != items.end(); ++i)
+    i->menu->set_owner(NULL);
+
+  items.clear();
+  active_menus.clear();
+
+  vs_container::destroy();
 }
 
 void vs_menubar::got_focus()
@@ -141,6 +158,44 @@
     subwidget->show_all();
 }
 
+void vs_menubar::add_widget(const vs_widget_ref &w)
+{
+  assert(!subwidget.valid());
+
+  set_subwidget(w);
+}
+
+void vs_menubar::rem_widget(const vs_widget_ref &w)
+{
+  if(w == subwidget)
+    set_subwidget(NULL);
+  else
+    {
+      assert(w->get_owner() == this);
+
+      bool found = false;
+
+      // make a new strong reference
+      vs_widget_ref w2 = w;
+
+      // hrm.
+      for(vector<item>::iterator i = items.begin();
+	  i != items.end(); ++i)
+	{
+	  if(i->menu == w2)
+	    {
+	      found = true;
+	      items.erase(i);
+	      break;
+	    }
+	}
+
+      assert(found);
+
+      active_menus.remove(w2);
+    }
+}
+
 int vs_menubar::width_request()
 {
   int w=0;

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_menubar.h	Mon Aug  8 21:17:04 2005
@@ -80,6 +80,8 @@
 
   ~vs_menubar();
 
+  void destroy();
+
   int width_request();
   int height_request(int w);
   void layout_me();
@@ -94,9 +96,10 @@
 
   void show_all();
 
-  // These aren't, unfortunately, particularly valid in this context. !!
-  void add_widget(const vs_widget_ref &w) {abort();}
-  void rem_widget(const vs_widget_ref &w) {abort();}
+  /** Add a widget as the new subwidget, like a bin. */
+  void add_widget(const vs_widget_ref &w);
+  /** Remove the subwidget OR a menu. */
+  void rem_widget(const vs_widget_ref &w);
 
   virtual void paint(const style &st);
   virtual bool focus_me();

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.cc	Mon Aug  8 21:17:04 2005
@@ -47,10 +47,19 @@
 
 vs_minibuf_win::~vs_minibuf_win()
 {
+}
+
+void vs_minibuf_win::destroy()
+{
   set_main_widget(NULL);
 
   header->set_owner(NULL);
   status->set_owner(NULL);
+
+  header = NULL;
+  status = NULL;
+
+  vs_container::destroy();
 }
 
 void vs_minibuf_win::set_main_widget(const vs_widget_ref &w)

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_minibuf_win.h	Mon Aug  8 21:17:04 2005
@@ -62,6 +62,8 @@
 
   ~vs_minibuf_win();
 
+  void destroy();
+
   void set_main_widget(const vs_widget_ref &w);
 
   int width_request();

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc	Mon Aug  8 21:17:04 2005
@@ -40,10 +40,19 @@
 
 vs_multiplex::~vs_multiplex()
 {
+  assert(children.empty());
+}
+
+void vs_multiplex::destroy()
+{
   for(list<child_info>::iterator i=children.begin();
       i!=children.end();
       i++)
     i->w->set_owner(NULL);
+
+  children.clear();
+
+  vs_passthrough::destroy();
 }
 
 bool vs_multiplex::tabs_visible() const

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h	Mon Aug  8 21:17:04 2005
@@ -95,6 +95,8 @@
   /** Returns the maximum height requested by any child. */
   int height_request(int width);
 
+  void destroy();
+
   void layout_me();
 
   virtual vs_widget_ref get_focus();

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.cc	Mon Aug  8 21:17:04 2005
@@ -12,6 +12,24 @@
   do_layout.connect(sigc::mem_fun(*this, &vs_stacked::layout_me));
 }
 
+vs_stacked::~vs_stacked()
+{
+  assert(children.empty());
+}
+
+void vs_stacked::destroy()
+{
+  for(std::list<child_info>::const_iterator i = children.begin();
+      i != children.end(); ++i)
+    {
+      assert(i->w->get_owner() == this);
+      i->w->set_owner(NULL);
+    }
+  children.clear();
+
+  vs_passthrough::destroy();
+}
+
 void vs_stacked::add_widget(const vs_widget_ref &w)
 {
   sigc::connection shown_conn=w->shown_sig.connect(sigc::bind(sigc::mem_fun(*this, &vs_stacked::raise_widget_bare), w.weak_ref()));

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_stacked.h	Mon Aug  8 21:17:04 2005
@@ -48,6 +48,10 @@
   // larger or smaller)
   vs_stacked(int w, int h);
 public:
+  ~vs_stacked();
+
+  void destroy();
+
   static ref_ptr<vs_stacked> create(int w=0, int h=0)
   {
     return new vs_stacked(w, h);

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_table.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_table.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_table.cc	Mon Aug  8 21:17:04 2005
@@ -61,10 +61,19 @@
 
 vs_table::~vs_table()
 {
+  assert(children.empty());
+}
+
+void vs_table::destroy()
+{
   // Delete all our children.
   for(childlist::const_iterator i=children.begin();
       i!=children.end(); ++i)
     i->w->set_owner(NULL);
+
+  children.clear();
+
+  vs_passthrough::destroy();
 }
 
 void vs_table::set_rowsep(int n)

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_table.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_table.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_table.h	Mon Aug  8 21:17:04 2005
@@ -155,6 +155,8 @@
 
   ~vs_table();
 
+  void destroy();
+
   void add_widget_opts(const vs_widget_ref &w, int row_start, int col_start, int row_span, int col_span, int xopts, int yopts);
   void add_widget_opts_bare(vscreen_widget &w, int row_start, int col_start, int row_span, int col_span, int xopts, int yopts);
 

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.cc	Mon Aug  8 21:17:04 2005
@@ -114,6 +114,13 @@
   return prevval;
 }
 
+void vscreen_widget::cleanup()
+{
+  destroy();
+  assert(is_destroyed);
+  delete this;
+}
+
 void vscreen_widget::destroy()
 {
   if(is_destroyed)

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vscreen_widget.h	Mon Aug  8 21:17:04 2005
@@ -169,6 +169,8 @@
    */
   virtual bool handle_key(const key &k);
 
+  /** Handle cleanup when the reference count goes to 0. */
+  void cleanup();
 protected:
   vscreen_widget();
 
@@ -184,10 +186,7 @@
 
     --refcount;
     if(refcount == 0)
-      {
-	destroy();
-	delete this;
-      }
+      cleanup();
   }
 
   static void handle_pending_deletes();
@@ -291,11 +290,9 @@
 
   int timeout(int msecs);
 
-  // Override with care!  The main reason to override this is if you
-  // want to use the destroy() routine to signal something.  Doing so
-  // is, uh, a hack.  A nasty hack.  In fact, this is mainly done to
-  // fix a bug in the download_list for aptitude which I don't have
-  // the motivation to fix properly yet.
+  /** Destroys the visible representation of this widget and
+   *  disconnects it from any children that it may have.
+   */
   virtual void destroy();
 
   vs_container *get_owner() {return owner;}



More information about the Aptitude-svn-commit mailing list