Re: GUI program on Mac OS in D?
On Monday, 5 February 2018 at 19:44:37 UTC, Jacob Carlborg wrote: Note that this applies to all classes, not just NSString. Ah yes, I will make sure it works for all the NSObject types. class NSStringRef { public: this(string s) { str_ = NSString.alloc.initWithBytes(cast(immutable(ubyte)*) s.ptr, s.length, NSStringEncoding.NSUTF8StringEncoding); } ~this() { str_.release(); } Note that this is not deterministic. There's not even a guarantee that a destructor for a class will be run at all. Oh I simply tested this by running millions of allocations and it seemed to work but I will have to use a struct then instead I guess. NSStringRef s = new NSStringRef("Hello"); NSLog(s.str); You can add an "alias this" [1] to avoid calling "str" explicitly. Ah that's neat! Currently the only correct way would be to wrap the class in a struct. There as been some talk to extend the language to support for reference counted classes [2]. Ok that sounds good. However, I'm mostly interested in how to make it work with the tools that are available now :)
Re: GUI program on Mac OS in D?
On Thursday, 21 December 2017 at 17:56:54 UTC, mrphobby wrote: Thanks for sharing! Your solution is more complete for sure. I think I will borrow a few ideas here :) I've been playing around with this a bit and it works pretty well. One thing that bothers me is the handling of NSString. I came up with the following class to handle strings and make sure they do not leak. But maybe there is a nicer way to handle this in D? class NSStringRef { public: this(string s) { str_ = NSString.alloc.initWithBytes(cast(immutable(ubyte)*) s.ptr, s.length, NSStringEncoding.NSUTF8StringEncoding); } ~this() { str_.release(); } NSString str() @property { return str_; } private: NSString str_; } And then you have to use it like this: NSStringRef s = new NSStringRef("Hello"); NSLog(s.str); Ideally I would like to write code more like this (without leaking the NSString): NSLog("Hello".nsstring); Surely this must be possible in D somehow? :)
Re: GUI program on Mac OS in D?
On Thursday, 21 December 2017 at 15:45:32 UTC, Adam D. Ruppe wrote: oh sorry i forgot to post this sooner here's my code so far. when i'm reasonably happy with it, it will be part of my simpledisplay.d. I might leave it undocumented, but if you wanted to dive into my source the final version will be in there somewhere. Thanks for sharing! Your solution is more complete for sure. I think I will borrow a few ideas here :)
Re: GUI program on Mac OS in D?
On Thursday, 14 December 2017 at 19:10:26 UTC, mrphobby wrote: On Thursday, 14 December 2017 at 14:07:25 UTC, Adam D. Ruppe wrote: 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; } This looks pretty awesome and very much like something I was looking for. Would really appreciate if you could share your work. Otherwise I'll have to roll up my sleeves and try hacking it on my own :) Ok, I finally had some time to work this out today. Thanks to the ideas posted here I was able to wrap something up despite my very limited knowledge of D and its compile time features :) Basically this is what your classes will look like: extern (Objective-C) @ObjCSuperClass("NSObject") interface AppDelegate : NSApplicationDelegate { mixin ObjCClass; AppDelegate init() @selector("init"); extern (C): @ObjCMethod("applicationDidFinishLaunching:") static void applicationDidFinishLaunching(AppDelegate self, SEL sel, NSNotification notification) { writefln("applicationDidFinishLaunching"); } } In this case I needed to add the explicit superclass attribute since NSApplicationDelegate is a protocol and not a class. If your object inherits from an interface representing a regular Objective-C class you don't need this. The actual registration and setup principle is based on Jacobs code and I added stuff to handle the attributes. Obviously you need declarations for Objective-C runtime calls but you can find those in Jacobs example source as well. Anyway, hope this helps. Feel free to fork and improve! https://gist.github.com/mrphobby/a247deb15d38aea86b3346079f32ce58
Re: GUI program on Mac OS in D?
On Thursday, 14 December 2017 at 14:07:25 UTC, Adam D. Ruppe wrote: 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. This looks pretty awesome and very much like something I was looking for. Would really appreciate if you could share your work. Otherwise I'll have to roll up my sleeves and try hacking it on my own :) Thanks for sharing your ideas!
Re: GUI program on Mac OS in D?
On Thursday, 14 December 2017 at 16:12:30 UTC, Jacob Carlborg wrote: No, that would not work. Several years ago I created an The bridge basically wrapped an Objective-C object inside a D object, resulted in two objects for each object instead of one. That bridge turned out to be a failure, vary complicated, huge amount of template instantiations and bloat from a lot of virtual methods that could not be removed. A simple test application with a window and a button resulted in a 60 MB executable. DIP43 is the next step in the evolution after the bridge and it's a much better approach. When DIP43 is done, or at least has made some more progress it will be much simpler. Please keep in mind that all this is work in progress, that's why it is as complicated now as it is. [1] http://dsource.org/projects/dstep/browser/dstep/objc Ok, I see! Sounds like I'll have to wait then. How long do you think it will take until DIP43 is available for use? Is it months or years we are talking about here?
Re: GUI program on Mac OS in D?
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 :)
Re: GUI program on Mac OS in D?
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!
Re: GUI program on Mac OS in D?
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 :)
Re: GUI program on Mac OS in D?
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!
Re: GUI program on Mac OS in D?
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.
Re: What is "stringImportPaths"
On Thursday, 7 December 2017 at 09:47:31 UTC, Jacob Carlborg wrote: On 2017-12-06 20:05, mrphobby wrote: There are two kinds of language constructs that uses the "import" keyword. One is the "Import Declaration" [1] which is the most common one and is used to import other symbols. The other language construct is the "Import Expression" [2], which is used to read a file at compile time and put its content into a string literal in your source code. Anything specified to the "stringImportPaths" build setting will be sent to the compiler with the -J flag. [1] https://dlang.org/spec/module.html#ImportDeclaration [2] https://dlang.org/spec/expression.html#import_expressions Ok thanks! I couldn't find that in the docs so kudos for pointing me to it. I still think using the word "import" is confusing. Would rather have it called "load" or something. But at least I understand it now :)
Re: GUI program on Mac OS in D?
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.
What is "stringImportPaths"
Can anyone explain what "stringImportPaths" is? I have seen this being used in dub.json files and I think I kind of know what it does, but I haven't been able to find a clear explanation in any documentation of what it does. It does not look like anything I'm familiar with from other languages. I understand it can be used for resources but I have seen it being used with both text files and binary files so I'm a bit confused. The documentation says I can import "whatever", but that feels a bit weird since importing is a construct used for importing symbols, right?
Re: GUI program on Mac OS in D?
On Friday, 24 November 2017 at 15:56:21 UTC, Jacob Carlborg wrote: BTW, the following line [3] of the Dub file will embed the Info.plist file in the executable, which can be handy if you don't want to use application bundles. The Info.plist file is not always necessary, I think my sample application will work without it, but for some things is necessary. I also have a Dockerfile [4] with a cross-compiler setup that targets macOS. You should also know that there's a bug in DMD, which I haven't manged to fix, that occurs when returning certain structs from Objective-C methods. I'm pretty sure if works correctly in LDC, since it's using the LLVM backend that already knows about Objective-C. Finally, since you're using D you'll not have ARC (Automatic Reference Counting) which these days are preformed by the Objective-C and Swift compilers. You'll need to resort to traditional release/retain calls where appropriate. I have not included those calls in my sample application. I'm also interested in making native macOS apps. I have a lot of experience in Objective-C but I'm new at D. I'm a bit confused at what documentation to look at. In [1] I get the impression that support for creating instances is very rudimentary, but in [2] it looks much better with constructors mapped with @selector. What level of support is there in the latest DMD compiler? Also, is there any support for creating macOS application bundles? [1] https://dlang.org/spec/objc_interface.html [2] https://wiki.dlang.org/DIP43