[Kde-bindings] Splitting up the SMOKE library

Richard Dale rdale at foton.es
Wed Jul 18 12:25:27 UTC 2007


On Wednesday 18 July 2007, Ashley Winters wrote:
> --- Richard Dale <rdale at foton.es> wrote:
> > On Tuesday 17 July 2007, Ashley Winters wrote:
> > > From browsing through the code, it looks like smoke-qt and
> >
> > smoke-kde
> >
> > > didn't directly reference or inherit each other. They each filled
> >
> > in
> >
> > > the AUTOLOAD (method_missing for Perl) for the classes which they
> > > respectively defined, and let the language method dispatcher handle
> > > finding which class the method was defined in. Each class knew
> >
> > which
> >
> > > Smoke* object it came from, and each object knew which Smoke* it
> > > belonged to.
> >
> > OK, I've had a read, and in fact some of that code is still in
> > qtruby, and
> > then ported to qyoto. But I didn't understand the 'hasFire()' method
> > quite -
> > why would only certain classes know which Smoke instance they
> > belonged to?
> >
> > class SmokeClass {
> > ...
> >     bool hasFire() const { return !(flags() & Smoke::cf_undefined); }
>
> Ahh, that's due to each Smoke library needing an element in its class
> list representing, for instance, QWidget. However, only the SmokeQtGui
> library would have the implementation (hasFire() is true) of the class.
> The hasFire() flag triggered actually importing the implementation into
> Perl via registerSmoke():
>
> void SmokePerlQt::registerSmoke(const char *name, Smoke *smoke) {
>     hv_store(_registered_smoke, name, strlen(name), newSViv((IV)smoke),
> 0);
>
>     // This will also need to handle the per-class initialization
>     smoke->binding = new SmokeBindingQt(smoke, this);
>
>     // Introduce all the classnames first
>     for(int i = 1; i <= smoke->numClasses; i++)
> 	registerSmokeClass(SmokeClass(smoke, i));
>
>     for(int i = 1; i <= smoke->numClasses; i++) {
> 	SmokeClass c(smoke, i);
> 	if(c.hasFire())
> 	    registerClass(c);
>     }
> }
>
>     void registerSmokeClass(const SmokeClass &c) {
> 	if(c.hasFire()) {   // we are the definitive smoke instance
> 	    SV *className = makePerlClassName(c);
>
> 	    SV *evil = newSVpvn((char*)&c, sizeof(SmokeClass));
> 	    STRLEN len;
> 	    char *name = SvPV(className, len);
> 	    hv_store(_perl_class_names, name, len, evil, 0);
>
> 	    const Smoke::Class *cp = &c.c();
> 	    hv_store(_perl_smoke_classes, (char*)&cp, sizeof(const
> Smoke::Class*), className, 0);
> 	} else {		// our class must already exist
> 	    // TODO: search the smoke hierarchy and find the Smoke instance
> 	    // which has the fire, then cache it in _perl_smoke_classes
> 	}
>     }
>     void registerClass(const SmokeClass &c) {
> 	installIsa(c);
> 	installAutoLoad(c);
> 	if(c.hasConstructor()) {
> 	    installNew(c);
> 	    installConstructor(c);
> 	}
>     }
>
> The TODO above is probably not necessary, since each Smoke library
> would insert its own classes into the global mapping, like Richard
> suggested. Perhaps it was meant as a reverse mapping from the stub
> (sans fire) Smoke/classid combination to the genuine implementation?
>
> Some mechanism like that needs to handle the situation where a KDE
> class has the prototype:
>
>   QMenuBar *getMenuBar() const;
>
> The KDE smoke library would return a QMenuBar classid which is valid int
> its OWN smoke lib, but not in QtGui's smoke lib. Any attempt to call a
> method on that object would fail. I tried implementing some central
> object management in smokeperl.cpp (createObject(), rememberPointer(),
> and various shortcuts), but I'm not sure how close I ever got to the
> mark.
OK, I understand now. I was thinking in terms of having all the classIds for 
classes used in a given module, but labelling them either 'internal' 
or 'external' depending on whether or not there was actually a 
corresponding 'x_*' class. But 'hasFire()' is a bit more poetic..

Then there are template types like QList<QWidget>, which might be used in one 
module, but defined in another. So as well as a classes global hash, another 
one for looking up the type id may or may not be needed. Perhaps as there is 
already a hash the holds the marshallers against their typenames we don't 
need that. I think the slot marshalling code was designed to work with types 
from a mixture of smoke libs, and it uses type ids that are currently always 
in the same smoke lib. Maybe it should just hold a pointer to the appropriate 
marshalling function instead of a type id?

-- Richard



More information about the Kde-bindings mailing list