December 08, 2017
On Thursday, 7 December 2017 at 09:39:45 UTC, Jacob Carlborg wrote:
> The latest DMD compiler only supports what's in the official documentation, i.e. [1]. What's documented in DIP43 [2] (except anything marked with "unimplemented") is what's been implemented in one of my forks. I'm working on adding what's in my fork piece by piece to upstream.

Ok thanks for clearing that up! Your work looks really appealing. Hope it gets into the official compiler soon.

December 08, 2017
On Thursday, 7 December 2017 at 12:27:36 UTC, Guillaume Piolat wrote:
> On Thursday, 7 December 2017 at 12:18:21 UTC, Guillaume Piolat wrote:
>>
>> You can easily make a DUB frontend to do that, for example https://github.com/AuburnSounds/Dplug/tree/master/tools/dplug-build
>
> And it might be cleaner to do this as a post-build step.

Thanks, I'll have a look at that.

December 13, 2017
On Thursday, 23 November 2017 at 17:28:43 UTC, Jacob Carlborg wrote:
> I have a simple example [2] of an application that shows a window with a WebKit view, i.e. and embedded browser. This works with the upstream DMD and LDC compilers. It basically only contains bindings for what I needed for that sample application. As you'll see there you need to use some parts of the Objective-C runtime to create class instances and subclasses. Also some gymnastics are required for class/static methods.

I have been taking a look at your example. Looks pretty neat! Some advanced mixin stuff there that looks pretty useful. However, as far as I can tell there is no handling of retain/release. How would you incorporate this into your mixin system without having to put "release" in all the interface definitions? Would it be possible to somehow hook this up automatically to the D destructor perhaps? Interested in hearing your thoughts on this!

December 13, 2017
On 2017-12-13 13:18, mrphobby wrote:

> I have been taking a look at your example. Looks pretty neat! Some advanced mixin stuff there that looks pretty useful.

They're pretty basic ;)

> However, as far as I can tell there is no handling of retain/release.

No, that's correct.

> How would you incorporate this into your mixin system without having to put "release" in all the interface definitions?

You can add methods for retain/release in the ClassTrait template [1].

> Would it be possible to somehow hook this up automatically to the D destructor perhaps? Interested in hearing your thoughts on this!

As far as I know, the destructor is only called (automatically by the GC). Since the Objective-C objects are not created using the GC the destructor will never be called. I don't think it's possible to implement reference counting (that would call retain/release) for classes in D, since it's not possible to overload the assignment operator for classes [2] or implement a postblit [3]. The only option, as far as I know, would be to wrap the class in a struct that calls retain/release automatically. But then you need to box/unbox the wrapped class constantly and all the method signatures would probably need to use this wrapper as well.

[1] https://github.com/jacob-carlborg/d_webkit_test/blob/master/source/foundation/util.d#L28

[2] https://dlang.org/spec/operatoroverloading.html#assignment
[3] https://dlang.org/spec/struct.html#struct-postblit

-- 
/Jacob Carlborg
December 13, 2017
On 2017-12-13 16:07, Jacob Carlborg wrote:
> On 2017-12-13 13:18, mrphobby wrote:

>> Would it be possible to somehow hook this up automatically to the D destructor perhaps? Interested in hearing your thoughts on this!
> 
> As far as I know, the destructor is only called (automatically by the GC). Since the Objective-C objects are not created using the GC the destructor will never be called. I don't think it's possible to implement reference counting (that would call retain/release) for classes in D, since it's not possible to overload the assignment operator for classes [2] or implement a postblit [3]. The only option, as far as I know, would be to wrap the class in a struct that calls retain/release automatically. But then you need to box/unbox the wrapped class constantly and all the method signatures would probably need to use this wrapper as well.

I forgot to mention that there have been several discussions around adding support for reference counted classes. Several of the mentioning interfacing with Objective-C is important/a requirement.

https://wiki.dlang.org/Language_design_discussions#Automatic_Reference_Counting_.28ARC.29_as_an_alternative_to_D.27s_Garbage_Collector

http://forum.dlang.org/post/n0nnu0$1tth$1@digitalmars.com

https://wiki.dlang.org/FatPointer#Interfacing_with_Objective-C

-- 
/Jacob Carlborg
December 13, 2017
On Wednesday, 13 December 2017 at 15:17:59 UTC, Jacob Carlborg wrote:
> I forgot to mention that there have been several discussions around adding support for reference counted classes. Several of the mentioning interfacing with Objective-C is important/a requirement.

Ok, good to know!

I have another question about your Webkit test example... I see that you are doing some elaborate setup in order to bind the application delegate methods. Can you explain a bit about why you are doing it in this way instead of using the @selector attribute in a class?

The thing is that I'm currently attempting to get it to work using the "easy" way using @selector but the methods in my AppDelegate class are not called. Not sure why that is, but I probably screwed something up :)

December 14, 2017
On 2017-12-13 16:59, mrphobby wrote:

> I have another question about your Webkit test example... I see that you are doing some elaborate setup in order to bind the application delegate methods. Can you explain a bit about why you are doing it in this way instead of using the @selector attribute in a class?

That is to register the methods with the Objective-C runtime. Currently the @selector attribute can only be used on methods that are already implemented in Objective-C. If a need to implement a new method or override an existing method in a subclass, then it's necessary to manually register that method with the runtime.

This is because the full implementation of DIP43 [1] is not done/merged yet.

But trust me, this is a lot simpler than without any compiler support at all. Then you would need to know details of the ABI to call Objective-C methods.

The methods I've added in the WebKit example are methods that will only be called as callbacks by the Objective-C code. If I want to call them myself I would need the @selector attribute as well, in addition to the manual registering.

> The thing is that I'm currently attempting to get it to work using the "easy" way using @selector but the methods in my AppDelegate class are not called. Not sure why that is, but I probably screwed something up :)

Yes, see above.

[1] https://wiki.dlang.org/DIP43

-- 
/Jacob Carlborg
December 14, 2017
On Thursday, 14 December 2017 at 10:14:13 UTC, Jacob Carlborg wrote:
> That is to register the methods with the Objective-C runtime. Currently the @selector attribute can only be used on methods that are already implemented in Objective-C. If a need to implement a new method or override an existing method in a subclass, then it's necessary to manually register that method with the runtime.

Ok I understand it now, thanks!

I'm thinking it would be nice to wrap this setup code into some kind of mixin template so that I could put the required configuration setup in each class. In other languages like Python or C# I would maybe decorate my methods with an attribute and then use reflection to build the proper data structures at runtime. However, I'm completely new to D so it's a bit difficult to see a good solution here. If you have any ideas how to do this I'd appreciate it. Thanks for all help!

December 14, 2017
On Thursday, 14 December 2017 at 11:36:46 UTC, mrphobby wrote:
> I'm thinking it would be nice to wrap this setup code into some kind of mixin template so that I could put the required configuration setup in each class. In other languages like Python or C# I would maybe decorate my methods with an attribute and then use reflection to build the proper data structures at runtime. However, I'm completely new to D so it's a bit difficult to see a good solution here. If you have any ideas how to do this I'd appreciate it. Thanks for all help!

Also, it feels a bit awkward to implement the callback handling methods as static methods, with the "self" and SEL arguments. Would have been nice if it was possible to use instance methods.

After thinking about it for a while I guess it could work with one static dispatch method that maps selectors to specific instance methods. So when callbacks are made from Objective-C they are made to this one static method, which would then call the right method on the class.

I'm still struggling with D syntax, so here's some pseudo code:

class AppDelegate {
   static var methodMap = {}    // Maps selector name to methods

   static void handleCallback(AppDelegate self, SEL sel, ...) {
      var method = methodMap[sel];
      self.call(method, va_list);      // Call the method with args (not sure if possible in D)
   }

   void applicationDidFinishLaunching(NSNotification notification) {
      // Normal instance method here
   }
}

Now, you would also need a registration step somewhere that sets up the selectors to use, perhaps in a static constructor that is run when AppDelegate class is used for the first time.

I hope this makes sense. Just throwing out some ideas :)

December 14, 2017
On Thursday, 14 December 2017 at 13:56:28 UTC, mrphobby wrote:
> After thinking about it for a while I guess it could work with one static dispatch method that maps selectors to specific instance methods. So when callbacks are made from Objective-C they are made to this one static method, which would then call the right method on the class.

I was playing with this myself based on Jacob's code and made it look like this:

extern (Objective-C) interface ViewController : NSViewController {
        extern (C)
        @ObjCMethodOverride("loadView")
        static void loadView(ViewController self, SEL sel) {
                printf("loadView\n");
        }

        extern (C)
        @ObjCMethodOverride("viewDidLoad")
        static void viewDidLoad(ViewController self, SEL sel) {
                printf("viewDidLoad\n");
        }

        ViewController init() @selector("init");
        mixin RegisterObjCClass;
}



so the mixin does some registering based on the method override attrs. It is still static with self cuz I actually felt hiding that made things a bit worse (inheritance wouldn't work like you expect), but most the registration stuff is now pulled from the attribute metadata.


Of course, my goal here isn't actually to do all of obj-c... just enough to port my simpledisplay.d. So I'm not sure if I'll make this public yet or just leave it as private and/or undocumented inside my library file.