November 01, 2014
On 2014-11-01 01:58, Michel Fortin wrote:

> That said, there are other parts of D/Objective-C that could pose
> difficulties to existing languages tools, some syntactic (__selector, or
> "this.class" to get the metaclass)

"this.class" could perhaps be called "this.classof", at least that's valid syntax. Although I don't know what to do about __selector.

-- 
/Jacob Carlborg
November 03, 2014
I have a question regarding selectors. I wanted to set a double-click action in the tableview example. Currently i get the selector like this:


    objc.runtime.SEL doubleAction = cast(objc.runtime.SEL)&AppDelegate.doubleClickAction ;
    demoTableView.setDoubleAction(doubleAction) ;


Is this the recommended/right way to do it?

Then the double-click action looks like this:


    void doubleClickAction(NSObject sender) {

	NSTableView tableView = cast(NSTableView)sender ;

	if (sender is demoTableView) {
	     NSInteger clickedRow = demoTableView.clickedRow() ;
	     Item item = cast(Item)_applications.objectAtIndex(clickedRow) ;
	     NSWorkspace.sharedWorkspace().launchApplication(item.itemDisplayName()) ;
	}
    }


I would expect to be using an ObjcObject instead of an NSObject here, but this does not compile. The signature of the target action seems to be irrelevant, it may have no or more parameters. I guess this is just ok and the expected behavior. In Objective-C, if the action signature does not comply you will get warnings or errors.
November 03, 2014
On 2014-11-03 09:51, Christian Schneider wrote:
> I have a question regarding selectors. I wanted to set a double-click
> action in the tableview example. Currently i get the selector like this:
>
>
>      objc.runtime.SEL doubleAction =
> cast(objc.runtime.SEL)&AppDelegate.doubleClickAction ;
>      demoTableView.setDoubleAction(doubleAction) ;
>
>
> Is this the recommended/right way to do it?

No, have a look at the tests for selectors [1]. I'm not sure if you need to cast it to "SEL". Try just using "auto":

auto doubleAction = &AppDelegate.doubleClickAction;

> Then the double-click action looks like this:
>
>
>      void doubleClickAction(NSObject sender) {
>
>      NSTableView tableView = cast(NSTableView)sender ;
>
>      if (sender is demoTableView) {
>           NSInteger clickedRow = demoTableView.clickedRow() ;
>           Item item = cast(Item)_applications.objectAtIndex(clickedRow) ;
> NSWorkspace.sharedWorkspace().launchApplication(item.itemDisplayName()) ;
>      }
>      }
>
>
> I would expect to be using an ObjcObject instead of an NSObject here,
> but this does not compile. The signature of the target action seems to
> be irrelevant, it may have no or more parameters. I guess this is just
> ok and the expected behavior.

Hmm, that sounds strange. What exact errors do you get?

[1] https://github.com/jacob-carlborg/dmd/blob/d-objc/test/runnable/objc/objc_selector.d

-- 
/Jacob Carlborg
November 04, 2014
>>
>> I would expect to be using an ObjcObject instead of an NSObject here,
>> but this does not compile. The signature of the target action seems to
>> be irrelevant, it may have no or more parameters. I guess this is just
>> ok and the expected behavior.
>
> Hmm, that sounds strange. What exact errors do you get?


source/appdelegate.d(47): Error: function
appkit.tableview.NSTableView.setDoubleAction (objc_selector*
aSelector) is not callable using argument types (extern
(Objective-C) void __selector(ObjcObject))

Line 46 & 47:

auto doubleAction = &AppDelegate.doubleClickAction ;
demoTableView.setDoubleAction(doubleAction) ;

Line 80:

void doubleClickAction(ObjcObject sender) {

actually, when line 46 & 47 are like above, it doesn't matter if
I change ObjcObject to NSObject, but I guess my problem here is
how Map the function in tableview.d:

void setDoubleAction(objc.runtime.SEL aSelector)
[setDoubleAction:] ;


> [1] https://github.com/jacob-carlborg/dmd/blob/d-objc/test/runnable/objc/objc_selector.d

I know Dip 43 almost by heart now, but I haven't yet discovered
the tests you wrote. Nice, this will be extremely helpful.

Best!
November 04, 2014
Ok, some more info:

I changed the mapping in tableview.d to:

void setDoubleAction(void __selector(ObjcObject))
[setDoubleAction:] ;

This should be the way to do it. Now in the implementation of the
action:

     void doubleClickAction(ObjcObject sender) {
         NSLog("double click action") ;
         NSLog("the sender: %@", sender) ;
     }

This works fine and prints the log:  2014-11-04 10:01:57.967
tableview[9988:507] the sender: <NSTableView: 0x7f8309f156b0>

But now I would like to do something with this sender, like I do
often in an Objective-C project:

NSTableView tableView = cast(NSTableView)sender ;

I get a  EXC_BAD_ACCESS (SIGSEGV) on this line. Only when I
replace both ObjcObject with NSObject (in tableview.d, the
mapping, and the target action) this cast works. I might be
missing something obvious here.

Thanks again.
November 04, 2014
what is funky in this context (see above): even when using
ObjcObject in both the mapping and the action method, the test

if (sender is demoTableView) {
    //
}

does not fail in the action, only a cast to a NSTableView object
fails. Of course, in this setting it's not really a problem, I
can work directly on the demoTableView member and can forget
about the sender, but this is against how I would do it in
Objective-C where I can always cast an id reference to the
expected type.

November 04, 2014
On 2014-11-04 09:07:08 +0000, "Christian Schneider" <schneider@gerzonic.net> said:

> Ok, some more info:
> 
> I changed the mapping in tableview.d to:
> 
> void setDoubleAction(void __selector(ObjcObject))
> [setDoubleAction:] ;

That's indeed the best way to do it.


> This should be the way to do it. Now in the implementation of the
> action:
> 
>       void doubleClickAction(ObjcObject sender) {
>           NSLog("double click action") ;
>           NSLog("the sender: %@", sender) ;
>       }
> 
> This works fine and prints the log:  2014-11-04 10:01:57.967
> tableview[9988:507] the sender: <NSTableView: 0x7f8309f156b0>
> 
> But now I would like to do something with this sender, like I do
> often in an Objective-C project:
> 
> NSTableView tableView = cast(NSTableView)sender ;
> 
> I get a  EXC_BAD_ACCESS (SIGSEGV) on this line. Only when I
> replace both ObjcObject with NSObject (in tableview.d, the
> mapping, and the target action) this cast works. I might be
> missing something obvious here.

There is no test for interface-to-class casts in the D/Objective-C test suite, which means you're likely the first person to try that. It's probably just an oversight in the compiler code.


-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

November 04, 2014
On 2014-11-01 10:47:54 +0000, Jacob Carlborg <doob@me.com> said:

> On 2014-11-01 01:58, Michel Fortin wrote:
> 
>> That said, there are other parts of D/Objective-C that could pose
>> difficulties to existing languages tools, some syntactic (__selector, or
>> "this.class" to get the metaclass)
> 
> "this.class" could perhaps be called "this.classof", at least that's valid syntax. Although I don't know what to do about __selector.

Once this is merged in DMD, __selector could be documented to be syntactically identical to a delegate (although semantically different) and it could be made syntactically valid for regular D code compiled with no Objective-C support (although it'd remain semantically invalid). That'd allow you to hide it in version blocks and static ifs.

-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

November 05, 2014
On 2014-11-04 13:29, Christian Schneider wrote:
> what is funky in this context (see above): even when using
> ObjcObject in both the mapping and the action method, the test
>
> if (sender is demoTableView) {
>      //
> }
>
> does not fail in the action

That will just compare the address of the objects.

> , only a cast to a NSTableView object
> fails. Of course, in this setting it's not really a problem, I
> can work directly on the demoTableView member and can forget
> about the sender, but this is against how I would do it in
> Objective-C where I can always cast an id reference to the
> expected type.

See the reply by Michel. It's probably a bug/oversight in the compiler. As a workaround you can, as you said, use NSObject instead of ObjcObject in both places.

What happens if you declare "doubleClickAction" like this:

void doubleClickAction(NSTableView sender) { ... }

That will probably require a cast when passing the selector to "setDoubleAction".

-- 
/Jacob Carlborg
November 05, 2014
On 2014-11-04 23:46, Michel Fortin wrote:

> Once this is merged in DMD, __selector could be documented to be
> syntactically identical to a delegate (although semantically different)
> and it could be made syntactically valid for regular D code compiled
> with no Objective-C support (although it'd remain semantically invalid).
> That'd allow you to hide it in version blocks and static ifs.

Yeah, that would be preferable. I would like to avoid the mess that the migration from D1 to D2 caused. Where if one wanted to support both some D2 code needed to be in a string mixin guarded with a version block.

-- 
/Jacob Carlborg