From: Charles S. <bas...@ch...> - 2012-07-05 08:46:16
|
On Jul 5, 2012, at 1:38 AM, Alexei Svitkine wrote: > On Thu, Jul 5, 2012 at 2:29 AM, Charles Srstka <bas...@ch...> wrote: > On Jul 5, 2012, at 12:39 AM, Alexei Svitkine wrote: > >> if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_5) >> ... new API >> else >> ... old API >> >> Is your new implementation strictly better than the clip_macosx.cpp one? Can you give a brief overview comparing them in terms of what works and what doesn't? This will help make it clear whether it makes sense to always prefer to use the new API code when running on 10.6 for 32-bit builds. (And hence whether it makes sense to consolidate them now like this.) > > Well, it’s definitely better than the clip_macosx.cpp in that the latter doesn’t run on 64-bit systems. I’ve also added a couple of features to it: > > 1. copy/paste styled text into and out of the emulator > > 2. copy/paste international text using non-Roman scripts into and out of the emulator > > As for the 10.6+ pasteboard API, that adds two features: > > 1. The ability to just say “lemme read/write an NSAttributedString off the pasteboard!” and have the OS do the conversion for you to and from whatever internal representation it’s using, instead of saying “Gimme some data of kUTTypeRTF and I hope that’s what OS X still uses!” > > 2. The fact that the API is just more current and is a complete replacement for the old one, and although the old API isn’t deprecated yet, you know how Apple is (Exhibit A: the fact that the implementation in clip_macosx.cpp no longer works). Basically, this is for future-proofing. > > Okay, but clip_macosx.cpp would still be able to handle scrap types that exist both under Classic and Mac OS X transparently (at least, on PPC or if there is no byteswapping needed), correct? Ones that wouldn't get handled without explicit support in clip_macosx64.mm. That's the big difference, still, right? I believe that can be done in the ... old API section; the docs for NSPasteboard claim that the API marked "10.5 and earlier” are still capable of taking types that aren’t UTIs, although it warns that this will probably stop working in some future version of OS X (which is why I feel that we definitely don’t want code that does that running on modern OS X versions). One thing about that, though — as you point out, it’s only a safe thing to do on PPC — on Intel, it could lead to all sorts of byte-swapping issues. And forgive me if I’m missing an important use case, but if you’re on Tiger/PPC, why would you need SheepShaver? Machines in that configuration have access to the Classic environment, which in my experience is generally much better at running Classic Mac OS applications than SheepShaver is. > I think there will also be problems compiling this combined file on 10.4, for example, since it wouldn't have headers for the new APIs. That can be worked around with additional ifdefs, but that gets hairy fast. With Objective-C, it can be done much more easily than that. The first thing to note is that Objective-C is a completely dynamic language, and all the “static typing” you get at the source code level is purely advisory; trying to send a message that isn’t defined in any header to an object only generates a warning at compile time, although if execution actually reaches that nonexistent call at runtime, it’ll throw an exception. So how much work this would be depends a lot on whether we care about warnings that only show up when compiling on ancient systems. There are a few exceptions, of course, one being that if we try to allocate a class that doesn’t exist in the 10.4 version of the frameworks, it won’t link. There are ways around that too, though, like for instance replacing this: SomeObjectThatsNotInTiger *myObject = [[SomeObjectThatsNotInTiger alloc] init]; with this: SomeObjectThatsNotInTiger *myObject = [[NSClassFromString(@“SomeObjectThatsNotInTiger”) alloc] init]; and that’ll work fine, as long as you keep the execution from getting to this line in Tiger. We’d definitely need to have a tester with Tiger and the dev tools to catch any surprises, though. > Let's leave merging these off for now, but we can revisit that later. I’m perfectly fine with that, and my original intent was to have this apply only to 10.6 and up; the only reason I brought it up was because you seemed to express some disappointment in it not being back-portable to 10.4, something that is certainly fixable in the future should the need arise. > >>> Still, if you do think the autorelease pools are really required, I suggest making a C++ scoped object that will alloc an autorelease pool in its ctor and release it in its dtor, which will eliminate the need for draining the pool at all the early return points. >> >> Yeah, that could work. >> >> Could you make that change? I think it would be much cleaner than all the early-return cleanup in your current patch. > > Sure thing. I think I’ll put the wrapper object in a header file so that it can be used elsewhere if people want to. This’ll be an Objective-C++ header file and will only be includable by Objective-C++ code; do you have any preference whether to put #ifdef guards around it or just use #import? > > My preference would be to still have ifdef guards. Thanks. Here’s a new patch: Thanks, Charles |