Re: [inti] OptionMenu width ?

Jeff Franks <[email protected]> Mon, 05 Jan 2004 22:27:12 +1100
Newsgroups gmane.comp.gnome.inti
Message-ID <[email protected]>
Bo Lorentsen wrote:

> Jeff Franks wrote:
>
>> Each widget class has two completely different ways to respond to a 
>> GTK signal. You can connect to it using the proxy signals (e.g. 
>> sig_clicked() in Gtk::Button). This method does not require you to 
>> declare your own class, you can just use one of the standard widget 
>> classes, "out of the box" so-to-speak. The other way is to derive 
>> your own class from  a standard widget and override one or more of 
>> its virtual signal handlers. The thing about these virtual signal 
>> handlers is that they're already connected. you don't need to 
>> explicitly connect to them. That's what all the _proxy functions are 
>> for in the soucre (cc) files. The logic behind moving all the virtual 
>> signal handlers into an interface class that needs to multiplley 
>> inherited is that it removes the memory slug for all those widgets 
>> that you don't need all those virtual functions. If you are going to 
>> write this
>
>
> Ahh, so the proxy classes in the EntryEvent class, not only define a 
> slot/proxy but also connect them, I din't know that.
>
> I see you do this connection in the EntryClass::init, but then what 
> have You achived ? The interface as somewhat smaller, but the proxy 
> classes still need to be called, and some runtime fee have to be 
> payed, or am I still missing the point ?

I was trying to reduce the size of the memory foot print of the 
application and improve its speed. The proxy connection occurs in the 
library itself but not in the application. Each proxy function is static 
so there is only one of each type for the entire library. The run time 
fee is no more than for GTK itself because this is what GTK does in an 
object's class_init function. It assigns an object specific function to 
the function pointers declared in a base object's class structure.

The point is that you're objects wont have such a big virtual function 
table and wont be slowed down by calls to the table. Just think of all 
the widgets in a average application. In Gtk::Widget there are about 60 
virtual functions. Most classes that derive from Gtk::Widget add there 
own virtual functions. All up, at a guess, each end widget could have up 
to 100 virtual functions. Multiply that memory by all the widgets in an 
application and there is a lot of memory. The thing I realized is that 
most widgets don't override these virtual functions and so that meant 
there was a potential memory saving. You still need to have these 
virtual functions though, because unlike proxy signals (that is, the 
sig_something() functions) they do not need to be connected. Instead 
they get called before the default handlers in GTK. You can override the 
default GTK handlers simply by not calling the parent virtual function. 
Calling the parent virtual function calls the default GTK signal 
handler. If you want the default behaviour then you must call the parent 
virtual function.

void
MyButton::on_clicked()
{
    // some code here
    Gtk::Button::on_clicked();
}

Now, the virtual function mechanism only gets added to your classes if 
you multiplely inherit from the new signal classes. Otherwise, it may be 
in the library but it's not in your application, and your application 
doesn't use these virtual fucntions if it was compiled without them.

>
> How does en EntryEvent class connect to the proxies, I don't se it ?
>
GType
Gtk::ButtonClass::get_type()
{
    static GType type = 0;
    if (!type)
    {
        type = G::TypeInstance::register_type(GTK_TYPE_BUTTON, 
(GClassInitFunc)init);
    }
    return type;
}

init in this function is Gtk::ButtonClass::init().

Then looking at the constructors of the widget classes, e.g. Gtk::Button

Gtk::Button::Button()
: Bin((GtkBin*)ButtonClass::create())
{
}

And looking at the Gtk::ButtonClass::create() function:

void*
Gtk::ButtonClass::create()
{
    return g_object_new(get_type(), 0);
}

so, Gtk::ButtonClass::create() calls Gtk::ButtonClass::get_type() which 
installs Gtk::ButtonClass::init() as the class initialization function, 
instead of GTK's. The first thing the init() function does is call the 
Inti parent class init() function and then it assigns function pointers 
the GTK widget class's function pointers. The proxy functions then call 
the GTK functions by default, as do the default implementations of all 
the virtual signal handlers (the on_something() functions). You can 
override this but that can be dangerous if you are not sure what your 
doing. For example, you might loose the default behaviour and a button 
wont click or an entry wont allow text to be entered.

And remeber, it seems like alot of code but it's all static. For 
example, there is only one Gtk::EntryClass and all the functions in it 
are static so there is only one each of them, shared by all entry 
widgets. The overhead is in the virtual signal handlers, not the _proxy 
functions.

>>
>> class MyEntry : public Gtk::Entry
>> {
>> };
>>
>> surely it's not too much effort to write this instead:
>>
>> class MyEntry : public Gtk::Entry, public Gtk::EntrySignals
>> {
>> };
>>
>> If you are deriving you own classes then I think you should override 
>> the virtual signal handlers since they are already hooked into the 
>> GTK signal emission system. You get them for free.
>
>
> Yeps, but not much are saved either, as I can se it !
>
Well, each call to a sig_something() fucntion adds several template 
classes to your application code, behind ther scenes. Multiply this by 
all the calls to all the sig_something() functions your application 
makes and there is some more overhead. Before you got the virtual 
fucntion overhead whether you used it or not. Now you have a choice, and 
I think it can be used to optomize an application.

>> I've never seen a major library that ever uses this file extension, 
>> only the odd program. If you remember my reason for not previously 
>> using inline functions then I suppose there is no reason why I 
>> shouldn't use hh.
>
>
> Anything other than .h will make me happy, but its not that important.
>

Regards,
Jeff Franks.


-------------------------------------------------------
This SF.net email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills.  Sign up for IBM's
Free Linux Tutorials.  Learn everything from the bash shell to sys admin.
Click now! http://ads.osdn.com/?ad_id=1278&alloc_id=3371&op=click