lib/DDInvocationGrabber.m
author Dave Dribin <dave@dribin.org>
Thu Feb 12 17:20:13 2009 -0600 (2009-02-12)
changeset 163 702f3ad9dc6f
parent 158 14076243f425
permissions -rw-r--r--
Fix method misspelling
dave@39
     1
/*
dave@158
     2
 * Copyright (c) 2007-2009 Dave Dribin
dave@39
     3
 * 
dave@39
     4
 * Permission is hereby granted, free of charge, to any person
dave@39
     5
 * obtaining a copy of this software and associated documentation
dave@39
     6
 * files (the "Software"), to deal in the Software without
dave@39
     7
 * restriction, including without limitation the rights to use, copy,
dave@39
     8
 * modify, merge, publish, distribute, sublicense, and/or sell copies
dave@39
     9
 * of the Software, and to permit persons to whom the Software is
dave@39
    10
 * furnished to do so, subject to the following conditions:
dave@39
    11
 * 
dave@39
    12
 * The above copyright notice and this permission notice shall be
dave@39
    13
 * included in all copies or substantial portions of the Software.
dave@39
    14
 *
dave@39
    15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
dave@39
    16
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
dave@39
    17
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
dave@39
    18
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
dave@39
    19
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
dave@39
    20
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
dave@39
    21
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
dave@39
    22
 * SOFTWARE.
dave@39
    23
 */
dave@38
    24
dave@48
    25
dave@48
    26
/*
dave@48
    27
 *  This class is based on CInvocationGrabber:
dave@48
    28
 *
dave@48
    29
 *  Copyright (c) 2007, Toxic Software
dave@48
    30
 *  All rights reserved.
dave@48
    31
 *  Redistribution and use in source and binary forms, with or without
dave@48
    32
 *  modification, are permitted provided that the following conditions are
dave@48
    33
 *  met:
dave@48
    34
 *  
dave@48
    35
 *  * Redistributions of source code must retain the above copyright notice,
dave@48
    36
 *  this list of conditions and the following disclaimer.
dave@48
    37
 *  
dave@48
    38
 *  * Redistributions in binary form must reproduce the above copyright
dave@48
    39
 *  notice, this list of conditions and the following disclaimer in the
dave@48
    40
 *  documentation and/or other materials provided with the distribution.
dave@48
    41
 *  
dave@48
    42
 *  * Neither the name of the Toxic Software nor the names of its
dave@48
    43
 *  contributors may be used to endorse or promote products derived from
dave@48
    44
 *  this software without specific prior written permission.
dave@48
    45
 *  
dave@48
    46
 *  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
dave@48
    47
 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
dave@48
    48
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
dave@48
    49
 *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
dave@48
    50
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
dave@48
    51
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
dave@48
    52
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dave@48
    53
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dave@48
    54
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
dave@48
    55
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
dave@48
    56
 *  THE POSSIBILITY OF SUCH DAMAGE.
dave@48
    57
 *
dave@48
    58
 */
dave@48
    59
dave@38
    60
#import "DDInvocationGrabber.h"
dave@38
    61
dave@38
    62
dave@38
    63
@implementation DDInvocationGrabber
dave@38
    64
dave@38
    65
+ (id)invocationGrabber
dave@38
    66
{
dave@38
    67
    return([[[self alloc] init] autorelease]);
dave@38
    68
}
dave@38
    69
dave@38
    70
- (id)init
dave@38
    71
{
dave@38
    72
    _target = nil;
dave@38
    73
    _invocation = nil;
dave@38
    74
    _forwardInvokesOnMainThread = NO;
dave@160
    75
    _invocationThread = nil;
dave@38
    76
    _waitUntilDone = NO;
dave@38
    77
    
dave@38
    78
    return self;
dave@38
    79
}
dave@38
    80
dave@38
    81
- (void)dealloc
dave@38
    82
{
dave@38
    83
    [self setTarget:NULL];
dave@38
    84
    [self setInvocation:NULL];
dave@38
    85
    //
dave@38
    86
    [super dealloc];
dave@38
    87
}
dave@38
    88
dave@38
    89
#pragma mark -
dave@38
    90
dave@38
    91
- (id)target
dave@38
    92
{
dave@38
    93
    return _target;
dave@38
    94
}
dave@38
    95
dave@38
    96
- (void)setTarget:(id)inTarget
dave@38
    97
{
dave@38
    98
    if (_target != inTarget)
dave@38
    99
	{
dave@38
   100
        [_target autorelease];
dave@38
   101
        _target = [inTarget retain];
dave@38
   102
	}
dave@38
   103
}
dave@38
   104
dave@38
   105
- (NSInvocation *)invocation
dave@38
   106
{
dave@38
   107
    return _invocation;
dave@38
   108
}
dave@38
   109
dave@38
   110
- (void)setInvocation:(NSInvocation *)inInvocation
dave@38
   111
{
dave@38
   112
    if (_invocation != inInvocation)
dave@38
   113
	{
dave@38
   114
        [_invocation autorelease];
dave@38
   115
        _invocation = [inInvocation retain];
dave@38
   116
	}
dave@38
   117
}
dave@38
   118
dave@38
   119
- (BOOL)forwardInvokesOnMainThread;
dave@38
   120
{
dave@38
   121
    return _forwardInvokesOnMainThread;
dave@38
   122
}
dave@38
   123
dave@38
   124
- (void)setForwardInvokesOnMainThread:(BOOL)forwardInvokesOnMainThread;
dave@38
   125
{
dave@38
   126
    _forwardInvokesOnMainThread = forwardInvokesOnMainThread;
dave@38
   127
}
dave@38
   128
dave@160
   129
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
dave@160
   130
- (void)setInvokesOnThread:(NSThread *)thread;
dave@160
   131
{
dave@160
   132
    _invocationThread = thread;
dave@160
   133
}
dave@160
   134
#endif
dave@160
   135
dave@38
   136
- (BOOL)waitUntilDone;
dave@38
   137
{
dave@38
   138
    return _waitUntilDone;
dave@38
   139
}
dave@38
   140
dave@38
   141
- (void)setWaitUntilDone:(BOOL)waitUntilDone;
dave@38
   142
{
dave@38
   143
    _waitUntilDone = waitUntilDone;
dave@38
   144
}
dave@38
   145
dave@38
   146
#pragma mark -
dave@38
   147
dave@46
   148
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
dave@38
   149
{
dave@46
   150
    return [[self target] methodSignatureForSelector:selector];
dave@38
   151
}
dave@38
   152
dave@38
   153
- (void)forwardInvocation:(NSInvocation *)ioInvocation
dave@38
   154
{
dave@38
   155
    [ioInvocation setTarget:[self target]];
dave@38
   156
    [self setInvocation:ioInvocation];
dave@160
   157
    BOOL invokeOnOtherThread = _forwardInvokesOnMainThread || (_invocationThread != nil);
dave@160
   158
    if (invokeOnOtherThread && !_waitUntilDone)
dave@160
   159
    {
dave@160
   160
        [_invocation retainArguments];
dave@160
   161
    }
dave@160
   162
    
dave@38
   163
    if (_forwardInvokesOnMainThread)
dave@38
   164
    {
dave@44
   165
        [_invocation performSelectorOnMainThread:@selector(invoke)
dave@44
   166
                                      withObject:nil
dave@44
   167
                                   waitUntilDone:_waitUntilDone];
dave@38
   168
    }
dave@160
   169
    
dave@160
   170
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
dave@160
   171
    if (_invocationThread != nil)
dave@160
   172
    {
dave@160
   173
        [_invocation performSelector:@selector(invoke)
dave@160
   174
                            onThread:_invocationThread
dave@160
   175
                          withObject:nil
dave@160
   176
                       waitUntilDone:_waitUntilDone];
dave@160
   177
    }
dave@160
   178
#endif
dave@38
   179
}
dave@38
   180
dave@38
   181
@end
dave@38
   182
dave@38
   183
#pragma mark -
dave@38
   184
dave@38
   185
@implementation DDInvocationGrabber (DDnvocationGrabber_Conveniences)
dave@38
   186
dave@38
   187
- (id)prepareWithInvocationTarget:(id)inTarget
dave@38
   188
{
dave@38
   189
    [self setTarget:inTarget];
dave@38
   190
    return(self);
dave@38
   191
}
dave@38
   192
dave@39
   193
@end