On 29 Apr 2011, at 17:10, Mathieu Suen wrote:

> Hi All,
> 
> I am back from a refactoring of my smalltalk objc binding.
> Now I have proxy from both side that forward send back and forth.

Nice!

> But I guess something is missing, for example in smalltalk I create a windows:
> 
> 
>  nsApplication := Objc.ObjcRuntime at: 'NSApplication'.
>  nsApp := nsApplication sharedApplication.
>  nsWindow :=  Objc.ObjcRuntime at: 'NSWindow'.
>  nsWindow := nsWindow alloc.
>  nsWindow initWithContentRect: nsRect styleMask: 15 backing:Objc.ObjcAppKit 
> nsBackingStoreBuffered defer: (Character value:1).
>  nsWindow setTitle: 'Test windows' asNSString.
> 
> 
>  view := NSView new.
>  nsWindow setContentView: view.
> 
> 
>  nsWindow center.
>  nsWindow orderFront: 0.
>  nsWindow contentView.
>  nsApp run.

Is the window actually being displayed at this point?

> Now my 'view' is a instance of a proxy to a objective-c NSView:
> Using gnu-smalltalk syntax:
> 
> Object subclass: NSView [
>    | objcRect |
> 
>    NSView class >> new [
>    ^(self basicNew) initialize; yourself
>    ]
> 
>    drawRect: rect [
>    | nsColor |
>    'drawRect called' printNl. 
>    nsColor := Objc.ObjcRuntime at: 'NSColor'.
>    nsColor := nsColor redColor.
>    nsColor set.
>    (objcRect gstBounds) printNl.
>    Objc.ObjcAppKit nsRectFill: (objcRect gstBounds) objcPtr
> 
>    ]
> 
>    doesNotUnderstand: aMessage [
>    ^objcRect send: aMessage selector with: aMessage arguments
>    ]
> 
>    initialize [
>    | cls |
>    cls := Objc.ObjcRuntime at: 'NSView'.
>    objcRect := cls alloc init.
> 
>    ]
> ]
> 
> NSView should be a subclass of ObjcObject but it does not change the issue:
> drawRect: is never called.
> 
> So I want to know if there is a kind of check like [view respondTo: 
> @"drawRect:"] or something similar?

You don't want to do this.  NSView is an insanely complex class - trying to 
completely reimplement it in Smalltalk will be far more effort than it's worth. 
 

In Objective-C, you would provide an NSView subclass here.  You want to do the 
same thing in Smalltalk, which means a bit more work on the bridge.  You will 
need to do something like this in Smalltalk:

ObjC.ObjcRuntime at: 'NSView' subclass: MyView [ ... ]

You will then need to override the subclass: method in the proxy.  
Alternatively, you can make the abstraction a little bit less clean, and just 
provide a method that makes an existing Smalltalk class into a subclass of an 
Objective-C class.

On the Objective-C side, you then need to create a new class.  Do this with 
objc_allocateClassPair() and later objc_registerClassPair().  In the middle, 
add an instance variable to the class that holds the Smalltalk proxy and some 
methods for passing the messages - the simplest way of doing this is just to 
use the same -forwardInvocation: trampoline that you use for normal messages 
going from Objective-C to Smalltalk, although the best thing to do here is 
probably to use -resolveInstanceMethod: and -resolveClassMethod:.

You will also have some fun handling message sends to super from Smalltalk.  
Probably the best thing to do is support some kind of composition that looks 
like subclassing from the Objective-C side, but not from the Smalltalk side.

David

-- Sent from my STANTEC-ZEBRA


_______________________________________________
Etoile-discuss mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-discuss

Répondre à