Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Accessing shared instance in target application, or sending actions
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  3 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Dan Wood  
View profile  
 More options Jun 18 2010, 7:39 pm
From: Dan Wood <dw...@karelia.com>
Date: Fri, 18 Jun 2010 16:39:32 -0700 (PDT)
Local: Fri, Jun 18 2010 7:39 pm
Subject: Accessing shared instance in target application, or sending actions
Hi folks, just trying out JSTalk for the first time since seeing Gus's
talk at C4.

I'm trying to create a new document in my target app with a minimum of
code changes in the app.  I'm thinking about a couple of possible
approaches:

* [[NSDocumentController sharedDocumentController]
newDocument:nil] ... Well, the problem is that this addresses the
shared document controller for JSTalk editor, so I end up creating a
new JSTalk window!

* Could I send an action to the first responder? Not sure if it's even
possible to refer to a selector in JSTalk.  If I could, I could use -
[NSApplication sendAction:to:from:]

* I guess worse-come-to-worse I could make an accessor in my
NSApplication subclass to give me the application's shared document
controller.  That doesn't seem like the cleanest solution.

Thoughts?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gus Mueller  
View profile  
 More options Jun 19 2010, 1:17 pm
From: Gus Mueller <g...@flyingmeat.com>
Date: Sat, 19 Jun 2010 10:17:10 -0700
Local: Sat, Jun 19 2010 1:17 pm
Subject: Re: Accessing shared instance in target application, or sending actions
On Jun 18, 2010, at 4:39 PM, Dan Wood wrote:

> * I guess worse-come-to-worse I could make an accessor in my
> NSApplication subclass to give me the application's shared document
> controller.  That doesn't seem like the cleanest solution.

This is actually what I do in my apps.  If you've got the JSTalk framework bundled in your app, it includes a category on NSApplication that looks like this:

- (id) sharedDocumentController {
    return [NSDocumentController sharedDocumentController];

}

There's a couple more in there, which you can see in JSTExtras.m.

-gus

--  

August 'Gus' Mueller
Flying Meat Inc.
http://flyingmeat.com/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Patrick Geiller  
View profile  
 More options Jun 20 2010, 9:40 am
From: Patrick Geiller <parman...@gmail.com>
Date: Sun, 20 Jun 2010 15:40:23 +0200
Local: Sun, Jun 20 2010 9:40 am
Subject: Re: Accessing shared instance in target application, or sending actions

> * [[NSDocumentController sharedDocumentController]
> newDocument:nil] ... Well, the problem is that this addresses the
> shared document controller for JSTalk editor, so I end up creating a
> new JSTalk window!

You need to get the distant app's NSDocumentController for this to work. Distant objects don't work with classes - they do send back the class, but serve it in JSTalk's space, producing your bug : creating documents in JSTalk rather than in your app. There's a simple fix : box the distant class in a custom object, call your class methods (sharedDocumentController) on this distant object, and let this distant object forward calls to the distant class.

This will require a box class, some additions to your app's NSApplication, and will let you use distant classes like this :

var sketch = JSTalk.application_("Sketch");
// Get distant NSDocumentController class
[[[sketch NSDocumentController] sharedDocumentController] newDocument:nil]
// Same, but using a standard method call
[[[sketch classNamed:'NSDocumentController'] sharedDocumentController] newDocument:nil]

First, this object boxes a class and forwards its calls to it :

@implementation ClassBox

+ (id)withClass:(Class)c
{
        id o = [[self new] autorelease];
        [o setValue:c forKey:@"class"];
        return o;      

}

// Check boxed class for selector response
- (BOOL)respondsToSelector:(SEL)sel
{
        BOOL b = [super respondsToSelector:sel];
        if (!b)
                b = [class respondsToSelector:sel];
        return b;
}

// Query boxed class for method signature
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
        id sig = [super methodSignatureForSelector:sel];
        if (!sig)
        {
                Method m = class_getClassMethod(class, sel);
                if (!m)         return nil;
                sig = [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(m)];
        }
        return sig;
}

// Invoke boxed class
- (void)forwardInvocation:(NSInvocation *)invocation
{
        [invocation setTarget:class];
        [invocation invoke];

}

@end

Then, add these methods to NSApplication to get any distant class (boxed). The first method is enough to work by using [sketch classNamed:'....']. The last three treat an unknown selector as a class request and send the class back (boxed) if they find it, letting you call [sketch NSDocumentController].

@implementation NSApplication (ServeClassesToDistantObjects)

// [sketch classNamed:@"NSDocumentController"]
- (id)classNamed:(NSString*)name
{
        id class = objc_getClass([name UTF8String]);
        if (!class)     return nil;
        return [ClassBox withClass:class];

}

// The next three methods handle getting a distant class by using its name as selector, eg [sketch NSDocumentController]
// These might need to be swizzled
- (BOOL)respondsToSelector:(SEL)sel
{
        BOOL b = [super respondsToSelector:sel];
        if (!b)
        {
                if (objc_getClass([NSStringFromSelector(sel) UTF8String]))
                        return YES;
        }
        return b;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
        id sig = [super methodSignatureForSelector:sel];
        if (!sig)
        {
                // We're calling a method that doesn't exist, takes no parameters, and returns an object (the class)
                // use the signature of -(id)self which does the same thing
                if (objc_getClass([NSStringFromSelector(sel) UTF8String]))
                        return [NSMethodSignature signatureWithObjCTypes:method_getTypeEncoding(class_getInstanceMethod([self class], @selector(self)))];
        }
        return sig;
}

- (void)forwardInvocation:(NSInvocation *)invocation
{
        id class = [self classNamed:NSStringFromSelector([invocation selector])];
        [invocation setReturnValue:&class];

}

@end

You might need to swizzle the last three methods as they could interfere with NSApplication's implementations (if they exist).

-Patrick


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »