[Kde-bindings] Re: Smoke: On classes and objects

Ashley Winters jahqueel at yahoo.com
Mon Apr 4 02:30:40 UTC 2005


--- Luca Fascione <lukes at wetafx.co.nz> wrote:
> TCL doesn't have types and so doesn't have type control.

Well, you're going to want to use the Tcl_Obj system to efficiently use
Smoke in Tcl. For each argument passed to a function, you need to
determine whether it's a list/dict aggregate type, a Qt object, or a
simple type (any of string/int/float). Trying to figure that out
automagically from everything's string representation would be hard.

> This way when you in TCL write
> 
> $myButton setText "OK"
> 
> on the C(++) side you end up in function call with an interface on
> the 
> lines of
> 
> int myMethodCaller (/*some context information, like the interpreter 
> address */,
>     char* className,
>     char* objPointer,
>     char* methodName,
>     int argc,
>     char** argv)

You'll want to use ObjCmdProc instead. Pure strings are hard...

> whose body in turn I was imagining to be on the lines of
> 
> {
>     /* ?check if the pointer and the type make sense together? */

We keep a global dictionary of objects created in the binding
interface, with the pointer being the key, and the language
representation being the value. You could use the same technique, in
either direction.

>     /* ask Smoke if the method is somewhere in the hierarchy of
> classes
>        of the object pointed to by objPointer */

See the do_autoload in PerlQt's Qt.pm for how to lookup methods in
Smoke. You don't need to distinguish between int/string/whatever; you
just need the name of the function, the type of the object, the number
of arguments, and to be able to tell the difference between a Qt object
being passed to the function, and a regular (scalar) type.

>     /* ask Smoke to grab the interface of the actual method to be
> used */

This is the tricky part. Smoke will offer you all the candidate
functions which match the particular signature you asked for. Most of
the time, there's only one possible candidate. If there's more than
one, you have to decide which one to call. When you pick a candidate,
you just coerce the argument(s) to the required type, and move on to...

>     /* convert the data in argv as appropriate from its string 
> representation */

That's called Marshalling in Smoke, and there are examples on how to do
that in PerlQt's handlers.cpp (see marshall_basetype() for the main
function to implement for ANY language binding)

>     /* ask Smoke to run the method on the given arguments,
> interestingly 
> enough, arguments will be in an
>        array of unions or some similar fairly dark magic... */

Dark magic indeed. It's dark magic that works the same way for
arguments, return-values, virtual functions, AND signals/slots. That
was not an easy thing to arrange!

>     /* convert all the results and relevant side effects back to
> strings 
> as appropriate */

The marshall_basetype() function converts in both directions, to and
from the C++ type.

> I guess with some patience subclassing can be actually made to work,

It's more a matter of deciding what you want to do. Just because the OO
languages require subclassing to override the paintEvent doesn't mean
you do too. You could allow it with:

qt new Widget .w
.w on paintEvent {e} {
    # your code here, use $e for the event
}

In the OO languages, that psuedo-looks like:

class MyWidget inherits Qt::Widget {
    sub paintEvent($e) {
        # your code here
    }
}
$w = MyWidget.new;

> but 
> it would be completely simulated, with basically no support from the 
> language. So when you do subclassing what happens is that you would
> have 
> to teach Smoke of the existance of a new derived class, and its
> position 
> in the class hierarchy.

The main convenience of subclassing is that you can create many objects
with the same behavior. Tcl isn't really suited for that, but it
wouldn't be hard to implement it Tcl-style using the above system:

proc MyClass {path text} {
    set $path [qt new PushButton]   # or however you do this
    $path setText $text
    $path on resizeEvent {...}
    $path on paintEvent {...}
    $path new signal {buttonWasClickedByUser()}
    $path connect {clicked()} $path {buttonWasClickedByUser()}
}

MyClass .w "foo"
.w show

You're going to feel limited if you don't allow creation of signals and
slots or implementation of event handlers (which, in the OO languages,
require subclassing).

Ashley Winters


		
__________________________________ 
Yahoo! Messenger 
Show us what our next emoticon should look like. Join the fun. 
http://www.advision.webevents.yahoo.com/emoticontest



More information about the Kde-bindings mailing list