[Ongui-dev] Thoughts on programming idioms
Status: Alpha
Brought to you by:
robinrowe
|
From: Mike D. <mi...@cs...> - 2003-12-24 15:57:35
|
Hi Robin,
Having a hell of a time getting Pango to work. Nearly there.
In the meantime, lest you think I'm dawdling my time away, I have been doing some
thinking about the new paradigm that we'll be selling along with OnGui's model. That
is, lots of GUI developers have the "listener" model hardwired in their brains.
We're going to have to convince them that the OnGui way is worth unlearning this
model.
So, I've been trying to figure out (perhaps prematurely) how programmers will write
code in this model; what common idioms might be used; and what we can do to serve
those needs.
If you'll bear with me, let's take a simple GTK+ app (please ignore the fact that
there are no parent containers):
<code>
void onClick (GtkButton *button, GtkLabel *label)
{
gtk_label_set_label (label, "Clicked!");
}
int main (int a_argc, char* a_argv[])
{
gtk_init (a_argc, a_argv);
GtkButton *button1 = gtk_button_new_with_label ("Hello, World!");
GtkLabel *label1 = gtk_label_new ("Not clicked (yet).");
gtk_signal_connect (GTK_OBJECT (button1), "clicked",
onClick, label1);
gtk_main() ;
return 0 ;
}
</code>
This is a pretty tight 18 lines of code. In it, we've created two objects, bound an
event to a handler, and even made a quasi-closure, where _label1_ is passed as a
parameter to the handler. The drawbacks, of course, include no type-safety, lots of
potentially slow indirection, wonky signal connection syntax, and the fact that I
haven't correctly implemented the reference counting I'd need in a larger app.
Here's the same app in OnGui (or, at least the version of it existing in my head):
<code>
int main (int a_argc, char* a_argv[])
{
class Button1 : public OnGui::Button
{
public:
Button1() : OnGui::Button ("Hello, World!") , m_label (0) {} ;
virtual void onClick () {m_label->setText ("Clicked!");} ;
void setLabel (OnGui::Label &a_label) {m_label = &a_label ;} ;
private:
OnGui::Label *m_label ;
} ;
OnGui::init (a_argc, a_argv);
Button1 button1 ;
OnGui::Label label1 ("Not clicked (yet).");
button1.setLabel (label1);
OnGui::run() ;
return 0 ;
}
</code>
This is 20+ lines, a little more than the GTK+ model. Again, we've created two
objects, defined a handler, and created a quasi-closure. The new class, _Button1_,
acts as its own functor (closure), storing state which will be used in the handler
later on. Binding of the handler to the event is inherited from _OnGui::Button_.
I'm pretty sure this is the form which OnGui code will tend to take: a local class
representing a specific object, with data members to bind parameters for use in a
handler method.
Two things come to mind, for me, after doing this gedankenexperiment.
1) A very common idiom, binding parameters to a callback (which is handled by the
GTK+ connection model) is not provided for. From what little I know of Java Swing
and Qt, their models don't provide for it, and that's certainly not stopping the
anybody from using either. I know you think this kind of machinery should be
avoided. However, if it will enable developers to do it in less lines of code, this
might be something we may want to think about addressing down the road.
2) Reference counting. If programmers are going to be storing pointers (or
references) to objects for use in binding callback parameters, we may discover
refcounting is a necessity. I know you want to avoid the use of an inherited common
object class, but how would you feel about this? I think we're certainly going to
need a common base class for the "Widget" concept anyway ("something that takes up
space on the screen"). Or as an alternative, we could make reference counting part
of a virtual base class that objects would inherit only when necessary. A form of
"autoptr" may be a good thing, too, to establish ownership of an object where
ownership might be ambiguous.
Thoughts? Comments?
-m
--
mike dalessio
mi...@cs...
|