Re: Why are some Core Graphics APIs "hidden" from Swift?

2017-08-30 Thread Quincey Morris
On Aug 30, 2017, at 14:04 , Rick Mann  wrote:
> 
> But the X, Y versions have a double underscore:
> 
>CGContext.__addArc(x1: CGFloat, y1: CGFloat, x2: CGFloat, y2: CGFloat, 
> radius: CGFloat)
> 
> Why is this?

I believe the double-underscore prefix indicates an Obj-C API that is exposed 
through Swift but not intended for general use. It may be that it’s there for 
3rd party developers who insist on using that particular API, or it may be for 
the Swift compiler to call through to. There is generally a better (simpler) 
API that does the same thing.

In this case, it may be that the x/y plus 1/2 coordinate pattern is an outlier, 
and Swift standardizes on points instead, in geometrical methods. You can pass 
CGPoint(x: x1, y:y1) and CGPoint (x: x2, y: y2) into the other API. My guess is 
that Swift generates the exact same code for the parameters in either case, 
because it can *always* inline the CGPoint creation methods. You’re not paying 
a performance or code size penalty, and you are gaining consistency.

I don’t know if my reasoning is correct, but it’s an argument that can be made 
in other similar cases too, so I think it’s something like that.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Why are some Core Graphics APIs "hidden" from Swift?

2017-08-30 Thread Rick Mann
I notice the CGPoint version of APIs map to nice Swift method calls:

CGContext.addArc(tangent1End: CGPoint, tangent2End: CGPoint, radius: 
CGFloat)

But the X, Y versions have a double underscore:

CGContext.__addArc(x1: CGFloat, y1: CGFloat, x2: CGFloat, y2: CGFloat, 
radius: CGFloat)

Why is this?





-- 
Rick Mann
rm...@latencyzero.com


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSDocument -canCloseDocumentWithDelegate::: not called when terminating

2017-08-30 Thread Jonathan Mitchell

> On 30 Aug 2017, at 18:30, Quincey Morris 
>  wrote:
> 
> On Aug 30, 2017, at 06:18 , Jonathan Mitchell  > wrote:
>> 
>> My documents have a lot of variable user cancellable activity that must run 
>> prior to document closure regardless of whether the document is dirty or not.
> 
>> My solution is to run a termination preflight that processes my clean 
>> documents prior to allowing actual termination,
> 
> 
> Instead, the “applicationWillTerminate:” override of your app delegate seems 
> like the right place, especially because it explicitly permits you to delay 
> terminate while you do stuff, without having to run the run loop manually.  
> That’s the *point* of the “applicationWillTerminate:” mechanism.

Thanks for the thoughts.

Using the applicationWillTerminate is probably a less hacky approach like you 
say but it would mean refactoring to accommodate this one troublesome situation 
- I would likely still need to retain the code that handles normal document 
closing as well.

I am not sure that the NSApp -terminate: override is such an issue as the 
problem only occurs when -terminate: is called. If another termination method 
appears on the scene it will likely have its own foibles.

The doc close logic is quite tricky with copies of the NSDocument instance 
being sent to both local and remote URLs. Getting it all to hang together at 
termination in a way that integrates with the NSDocument architecture is 
challenging.
As you say running the loop manually mimics what applicationWillTerminate tries 
to achieve in the first place.

I will keep an eye on how the preflight code works out in the knowledge that I 
can fall back to an “applicationWillTerminate” style approach.
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: NSDocument -canCloseDocumentWithDelegate::: not called when terminating

2017-08-30 Thread Quincey Morris
On Aug 30, 2017, at 06:18 , Jonathan Mitchell  wrote:
> 
> My documents have a lot of variable user cancellable activity that must run 
> prior to document closure regardless of whether the document is dirty or not.

> My solution is to run a termination preflight that processes my clean 
> documents prior to allowing actual termination,

There’s a difference between your scenario and the one in the thread you linked 
to. In your case, you don’t need to write anything to the document itself, you 
say.

I think it’s a (slight) conceptual mistake to tie the termination processing to 
the document machinery, especially as overriding NSDocumentController is a bit 
hacky even when done right. I also think it’s a mistake to override 
“terminate:”, because it’s just an action method and you can’t be certain that 
it’s actually going to be called. (The standard menu item could have a 
different action method name in the future, or there may be paths within Cocoa 
that don’t invoke the action method.)

Instead, the “applicationWillTerminate:” override of your app delegate seems 
like the right place, especially because it explicitly permits you to delay 
terminate while you do stuff, without having to run the run loop manually.  
That’s the *point* of the “applicationWillTerminate:” mechanism.

The consequence of using this override, though, is that documents may already 
have been closed. So, what I would suggest is maintaining a separate pool of 
“tasks” (a set of document references would be the simplest approach). In an 
override of “close”, start the user cancellable activity and remove the 
corresponding task from the pool. In “appWillTerminate:”, trigger any remaining 
tasks, and send the termination reply when they’re all done.

The reason I’m suggesting “close” rather than “canClose…” is just that it’s 
simpler, and it avoids getting tangled up in any possible code path where the 
close is prevented.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


NSDocument -canCloseDocumentWithDelegate::: not called when terminating

2017-08-30 Thread Jonathan Mitchell
This is one from the archives:

https://lists.apple.com/archives/cocoa-dev/2012/Jul/msg00740.html

In short NSDocument -canCloseDocumentWithDelegate::: gets called on documents 
when closing the document window but only for dirty documents when closing the 
app via NSApp -terminate: (i.e.: the application Quit menu item).
My documents have a lot of variable user cancellable activity that must run 
prior to document closure regardless of whether the document is dirty or not.
Trying to fudge the document dirty flag as and when required just sounds like a 
maintenance headache.

My solution is to run a termination preflight that processes my clean documents 
prior to allowing actual termination,
My experience is that intervening in the NSDocument machinery at critical 
points can be a recipe for disaster if things are not quite right.

If anyone has attempted this in the past comments would be appreciated.

NSApplication subclass
==

- (void)terminate:(id)sender
{
   // The logic here is quite complex
   // 
https://developer.apple.com/documentation/appkit/nsapplication/1428417-terminate?language=objc
   // The receiver calls NSDocumentController to check if documents can be 
closed.
   // If those methods don't handle their callbacks accurately then then this 
method never returns (even in termination does not occur)
   // and I think we end up in an inner run loop.
   //
   // If the termination process succeeds then this method does not return.
   // If the termination process is cancelled then this method does return;

   self.isTerminating = YES;

   // preflight
   // see https://lists.apple.com/archives/cocoa-dev/2012/Jul/msg00740.html
   // when we call terminate: non edited document instances do not get 
processed like diirty docs hence the preflight
   BOOL preflight = [[BPDocumentController sharedDocumentController] 
preflightCloseAllDocumentsOnApplicationTerminate];
   if (preflight) {
   [super terminate:sender];
   }

   self.isTerminating = NO;
}


NSDocumentController subclass
=

- (BOOL)preflightCloseAllDocumentsOnApplicationTerminate
{
   // see https://lists.apple.com/archives/cocoa-dev/2012/Jul/msg00740.html
   // when we call NSApp -terminate: non edited document instances do not get 
processed like dirty docs hence this preflight
   BOOL success = YES;

   // this method is only available if within NSApp -terminate:
   BOOL appTerminating = [(BPApplication *)NSApp isTerminating];
   if (!appTerminating) {
   return NO;
   }

   // we need to preflight non edited documents
   NSArray *cleanDocuments = [self.documents linq_where:^BOOL(BPDocument * doc) 
{
   return !doc.isDocumentEdited;
   }];

   for (NSDocument *doc in cleanDocuments) {
   self.cleanDocumentTerminateInfo = nil;

   // this method is called by default on dirty docs but in order to retain 
our sanity and ensure that the doc close logic
   // is called in all situations we call it here too
   [doc canCloseDocumentWithDelegate:self 
shouldCloseSelector:@selector(onTerminateCleanDocument:shouldClose:contextInfo:)
 contextInfo:NULL];

   // process events until our close selector gets called
   while (!self.cleanDocumentTerminateInfo) {
   NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny 
untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES];
   [NSApp sendEvent:event];
   }

   success = [self.cleanDocumentTerminateInfo[@"shouldClose"] boolValue];
   if (!success) {
   break;
   }
   }

   self.cleanDocumentTerminateInfo = nil;

   return success;
}

- (void)onTerminateCleanDocument:(NSDocument *)doc 
shouldClose:(BOOL)shouldClose contextInfo:(void  *)contextInfo
{
   self.cleanDocumentTerminateInfo = @{@"document" : doc, @"shouldClose" : 
@(shouldClose)};
}

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com