One of the comments on my last blog entry suggested a libmokoui binding. Since it was a nice small target, I went ahead and whipped up a binding for it this afternoon. It took me longer to write the tutorial I added to the wiki than it did to produce the binding.
Granted this was a very simple binding, since it is small and the source code was written perfectly for the GAPI parser's consumption. It also has no auto* magic. The tarball contains generated sources which could be copied into your project and compiled and installed as a private assembly. There is really no point to GAC magic for an assembly with no guarantees.
Friday, October 19, 2007
Friday, October 5, 2007
Bind this...
We are looking to add to the already impressive list of libraries accessible from mono. If you have any special requests of the latest and greatest libraries which you like to access from the sexy managed language of your choice, please let us know your needs so we can prioritize our efforts.
You can make your wishes known by commenting on this blog entry, mailing gtk-sharp-list@lists.ximian.com, filing a bug report, or writing on a cocktail napkin and mailing it to us, if you can figure out where we live.
You can make your wishes known by commenting on this blog entry, mailing gtk-sharp-list@lists.ximian.com, filing a bug report, or writing on a cocktail napkin and mailing it to us, if you can figure out where we live.
Wednesday, October 3, 2007
GInterface Implementation
Finally "finished" the framework for GInterface registration in Gtk# this week. I wrote up a small tutorial and API description. It points to the small test application I wrote to demonstrate TreeModel implementation, which is the most common reason people have requested GInterface registration for the past few years.
Here's a screenshot of the sample which uses reflection to display the assemblies, types, and members in the application's AppDomain.
Here's a screenshot of the sample which uses reflection to display the assemblies, types, and members in the application's AppDomain.

Friday, September 7, 2007
Reflection: a Cautionary Tale
Back in the day, I needed a mechanism to execute a method for a class for each new subclass of that type. Class constructors were not sufficient, because they are only run once per type, not once for every subclass of that type.
I decided to annotate the init method with an attribute and use reflection to lookup the method. When we register a new GType, we scan the class hierarchy for private static methods with a GLib.ClassInitializerAttribute and invoke any that exist. We use a similar mechanism to hook overridden virtual methods into the GObject class vtables for signal default handlers using the GLib.DefaultSignalHandlerAttribute.
This strategy works, but it turns out to be pretty suboptimal, especially from a memory usage standpoint. In order to find the methods with [ClassInitializer] defined, we had to load all the private static methods in the type hierarchy, and then iterate over them to look for the attribute. This caused a pretty substantial memory spike for types like Gtk.Widget which have a ton of static method delegate implementations for signal marshaling.
The root of the error was in not recognizing that the Class init problem is a one-to-one relationship of class to method, where the signal delegate problem I borrowed from is a one-to-many scenario. There is a [DefaultSignalHandler] method for each signal defined by a class.
To improve the mechanism, I added a GLib.TypeInitializerAttribute which takes a type and method name argument. With this attribute applied to a type declaration, we can lookup the specific methods by name and avoid loading all the static methods in the entire class hierarchy. This feature is now committed to trunk and the branch svn.
Since we have released the GLib.ClassInitializerAttribute as public API in a stable release, I couldn't just remove the reflection for it, even though it is unlikely that anyone out there really discovered the feature and is using it. In order to make it possible for subclass authors to avoid the reflection step, I also added the GLib.IgnoreClassInitializersAttribute which can be applied to any assemblies which contain GLib.Object subclass declarations. Svn trunk and branch add this attribute to all the gtk-sharp and gnome-sharp assemblies, so that all the types defined by the packages avoid this reflection overhead. The internal usage of [ClassInitializer] has been ported to [TypeInitializer] as well.
Thanks to Lluis for identifying the issue and Paolo for his usual insightful feedback in alternative approaches to the functionality. Lluis also helped refine the implementation of the [ClassInitializer] back-compat mechanism. My understanding is that the recent changes reduced MonoDevelop startup memory usage by about a MB.
I decided to annotate the init method with an attribute and use reflection to lookup the method. When we register a new GType, we scan the class hierarchy for private static methods with a GLib.ClassInitializerAttribute and invoke any that exist. We use a similar mechanism to hook overridden virtual methods into the GObject class vtables for signal default handlers using the GLib.DefaultSignalHandlerAttribute.
This strategy works, but it turns out to be pretty suboptimal, especially from a memory usage standpoint. In order to find the methods with [ClassInitializer] defined, we had to load all the private static methods in the type hierarchy, and then iterate over them to look for the attribute. This caused a pretty substantial memory spike for types like Gtk.Widget which have a ton of static method delegate implementations for signal marshaling.
The root of the error was in not recognizing that the Class init problem is a one-to-one relationship of class to method, where the signal delegate problem I borrowed from is a one-to-many scenario. There is a [DefaultSignalHandler] method for each signal defined by a class.
To improve the mechanism, I added a GLib.TypeInitializerAttribute which takes a type and method name argument. With this attribute applied to a type declaration, we can lookup the specific methods by name and avoid loading all the static methods in the entire class hierarchy. This feature is now committed to trunk and the branch svn.
Since we have released the GLib.ClassInitializerAttribute as public API in a stable release, I couldn't just remove the reflection for it, even though it is unlikely that anyone out there really discovered the feature and is using it. In order to make it possible for subclass authors to avoid the reflection step, I also added the GLib.IgnoreClassInitializersAttribute which can be applied to any assemblies which contain GLib.Object subclass declarations. Svn trunk and branch add this attribute to all the gtk-sharp and gnome-sharp assemblies, so that all the types defined by the packages avoid this reflection overhead. The internal usage of [ClassInitializer] has been ported to [TypeInitializer] as well.
Thanks to Lluis for identifying the issue and Paolo for his usual insightful feedback in alternative approaches to the functionality. Lluis also helped refine the implementation of the [ClassInitializer] back-compat mechanism. My understanding is that the recent changes reduced MonoDevelop startup memory usage by about a MB.
Monday, August 13, 2007
Change change change
After living with 4 German Shepherds for over 10 years, the past year has held a lot of painful if not unexpected changes for Sherry and I. We lost OD last fall at ten and a half. This summer was particularly bad, losing our 11 year old JR just two weeks after 13 year old Maggie.
Sherry, Qman, and I have sort of been moping around the house for the last month. It's amazing how empty a house can feel.
That all changed Wednesday night.

It's equally amazing how quickly a 3 month old puppy can fill up a house. Her name is Beebee. We haven't had a puppy in the house in over 11 years. The frantic dashes to the back yard during housebreaking. The brief periods of high-energy romping separated by hours of food-induced comas.
Qman has not been all that interested in playing her little puppy games, but has been very tolerant of her. At times, it seems like he's just laying there rolling his eyes at her. She has a pretty amazing personality. Extremely friendly and confident, and the shepherd drive to please is already evident. We are really looking forward to watching her develop and anticipating the fun we'll have earning obedience, agility, and tracking titles.
Oops, time to take her out back again!
Sherry, Qman, and I have sort of been moping around the house for the last month. It's amazing how empty a house can feel.
That all changed Wednesday night.

It's equally amazing how quickly a 3 month old puppy can fill up a house. Her name is Beebee. We haven't had a puppy in the house in over 11 years. The frantic dashes to the back yard during housebreaking. The brief periods of high-energy romping separated by hours of food-induced comas.
Qman has not been all that interested in playing her little puppy games, but has been very tolerant of her. At times, it seems like he's just laying there rolling his eyes at her. She has a pretty amazing personality. Extremely friendly and confident, and the shepherd drive to please is already evident. We are really looking forward to watching her develop and anticipating the fun we'll have earning obedience, agility, and tracking titles.
Oops, time to take her out back again!
Friday, June 29, 2007
Hack Week
This week was hack week at Novell. At the beginning of the week, it looked like I was going to be spending most of my time supporting new Gtk# users and fixing bugs they were tripping over. Things settled down a bit on Tuesday though, and I got to put some time into Exert for the remainder of the week.
Exert is a small Gtk# app that uses sqlite as a database to manage a fitness log. There are tons of running logs on the web and PC versions as well. While I plan to use exert as my own fitness log and potentially explore some new usability improvements, my main goal with exert is to provide an example of a small-scale database front-end application using Gtk#.
Prior to this week, I already had developed the database backend and created a couple of simple editor widgets to manage simple text only log entries. Additionally, I created a monthly calendar view to serve as the primary user interface for the application. There's a screenshot of a fairly stale version of the calendar view up on the sourceforge project page.
This week, I added a few new features:

So far, I haven't added any summary reports for running, but I will eventually add the usual weekly/monthly/annual summaries, as mile as accumulated mileage for Shoes.
Upcoming features include a specialized weightlifting entry editor to make it quick and easy to add and clone existing workouts. That will probably have to wait until the next hack week, though.
Exert is a small Gtk# app that uses sqlite as a database to manage a fitness log. There are tons of running logs on the web and PC versions as well. While I plan to use exert as my own fitness log and potentially explore some new usability improvements, my main goal with exert is to provide an example of a small-scale database front-end application using Gtk#.
Prior to this week, I already had developed the database backend and created a couple of simple editor widgets to manage simple text only log entries. Additionally, I created a monthly calendar view to serve as the primary user interface for the application. There's a screenshot of a fairly stale version of the calendar view up on the sourceforge project page.
This week, I added a few new features:
- Rendering of BodyWeight entries directly on the CalendarView
- A cardio entry editor for time/distance workouts with rest/avg/peak Heartrate logging.
- A running entry editor that builds on cardio entry but also tracks shoe usage.
- A Settings infrastructure based on XmlSerialization.

So far, I haven't added any summary reports for running, but I will eventually add the usual weekly/monthly/annual summaries, as mile as accumulated mileage for Shoes.
Upcoming features include a specialized weightlifting entry editor to make it quick and easy to add and clone existing workouts. That will probably have to wait until the next hack week, though.
Monday, May 7, 2007
Spring cleaning
After a brief hiatus helping out with the winforms bug count, I've spent the last few weeks shaking out bugs in Gtk#. The win32 instability issues with trunk seem to have been smoothed out. For the last week, I chased a bunch of ref management and object dispose/destroy issues down in MD and Stetic. Things seem pretty stable now with trunk, but as always, please report any trouble you run into.
I'd like to encourage anyone who has an interest in 2.10 to try out current svn trunk with your applications. It is possible you may see issues since we are getting closer to accurate object finalization now. Many of the issues I worked through in Stetic, for example, were related to using objects after they were already disposed, or marked for finalization by the GC through the circular ref handling capabilities of the GC. If you are doing any object destruction in Dispose overrides, for example, that can cause trouble. If you are invoking base.Dispose in a GLib.Object subclass, it should always be called after you do the additional work. When objects are leaking stuff like this doesn't bite you, but it just might now.
We would like to pull together a release in the near future, and I think things are stable enough at this point for more people to kick the tires. I've revised the Gtk# Plan wiki page to describe the recent changes in the tree and the planned feature additions.
And on a completely unrelated and personal note, I ran my first 5K race over the weekend and survived to hack another day.
I'd like to encourage anyone who has an interest in 2.10 to try out current svn trunk with your applications. It is possible you may see issues since we are getting closer to accurate object finalization now. Many of the issues I worked through in Stetic, for example, were related to using objects after they were already disposed, or marked for finalization by the GC through the circular ref handling capabilities of the GC. If you are doing any object destruction in Dispose overrides, for example, that can cause trouble. If you are invoking base.Dispose in a GLib.Object subclass, it should always be called after you do the additional work. When objects are leaking stuff like this doesn't bite you, but it just might now.
We would like to pull together a release in the near future, and I think things are stable enough at this point for more people to kick the tires. I've revised the Gtk# Plan wiki page to describe the recent changes in the tree and the planned feature additions.
And on a completely unrelated and personal note, I ran my first 5K race over the weekend and survived to hack another day.
Subscribe to:
Posts (Atom)