From 57ce8496763c15889b18636b88c8d9ceae95fa61 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Mon, 16 Jul 2012 12:05:43 +0200 Subject: [PATCH] Improve AbstractCall --- Classes/ChatTableViewController.m | 12 ++-- Classes/ContactDetailsTableViewController.m | 9 ++- Classes/ContactsTableViewController.m | 14 ++-- Classes/ContactsViewController.m | 14 ++-- Classes/DialerViewController.m | 9 +-- Classes/HistoryDetailsViewController.h | 5 +- Classes/HistoryDetailsViewController.m | 18 +++++ Classes/HistoryTableViewController.m | 9 ++- Classes/HistoryViewController.m | 1 + Classes/LinphoneUI/UICallBar.m | 26 +++---- Classes/LinphoneUI/UIChatCell.m | 12 ++-- Classes/LinphoneUI/UIHistoryCell.m | 16 ++--- Classes/LinphoneUI/UIMainBar.m | 2 +- Classes/PhoneMainView.h | 8 ++- Classes/PhoneMainView.m | 48 +++++++------ Classes/Utils/AbstractCall.h | 10 ++- Classes/Utils/AbstractCall.m | 79 ++++++++++++++++----- 17 files changed, 174 insertions(+), 118 deletions(-) diff --git a/Classes/ChatTableViewController.m b/Classes/ChatTableViewController.m index 1bdd7e8a3..47ea4ebc5 100644 --- a/Classes/ChatTableViewController.m +++ b/Classes/ChatTableViewController.m @@ -81,12 +81,12 @@ [tableView deselectRowAtIndexPath:indexPath animated:NO]; ChatModel *chat = [data objectAtIndex:[indexPath row]]; - // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: [chat remoteContact], nil] autorelease] - , @"setRemoteContact:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_ChatRoom dict:dict push:TRUE]; + // Go to ChatRoom view + [[PhoneMainView instance] changeView:PhoneView_ChatRoom + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"setRemoteContact:", [chat remoteContact]], + nil] + push:TRUE]; } @end diff --git a/Classes/ContactDetailsTableViewController.m b/Classes/ContactDetailsTableViewController.m index 2f58bab51..d8cdd335e 100644 --- a/Classes/ContactDetailsTableViewController.m +++ b/Classes/ContactDetailsTableViewController.m @@ -455,11 +455,10 @@ CFRelease(lDisplayName); // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: dest, displayName, nil] autorelease] - , @"call:displayName:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"call:displayName:", dest, displayName], + nil]]; } } else { NSString *key = nil; diff --git a/Classes/ContactsTableViewController.m b/Classes/ContactsTableViewController.m index a40e80853..5690a34b7 100644 --- a/Classes/ContactsTableViewController.m +++ b/Classes/ContactsTableViewController.m @@ -193,20 +193,14 @@ static void sync_address_book (ABAddressBookRef addressBook, CFDictionaryRef inf ABRecordRef lPerson = [subDic objectForKey: [subDic keyAtIndex:[indexPath row]]]; // Go to Contact details view - NSDictionary * dict; + NSArray * calls; if(tempAddress == nil) { - dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: lPerson, nil] autorelease] - , @"setContact:", - nil] autorelease]; + calls = [NSArray arrayWithObject: [AbstractCall abstractCall:@"setContact:", lPerson]]; } else { - dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: lPerson, tempAddress, nil] autorelease] - , @"editContact:address:", - nil] autorelease]; + calls = [NSArray arrayWithObject: [AbstractCall abstractCall:@"editContact:address:", lPerson, tempAddress]]; [self setTempAddress:nil]; } - [[PhoneMainView instance] changeView:PhoneView_ContactDetails dict:dict push:TRUE]; + [[PhoneMainView instance] changeView:PhoneView_ContactDetails calls:calls push:TRUE]; } @end diff --git a/Classes/ContactsViewController.m b/Classes/ContactsViewController.m index 17f8b6efb..3ce634fe0 100644 --- a/Classes/ContactsViewController.m +++ b/Classes/ContactsViewController.m @@ -150,20 +150,14 @@ typedef enum _HistoryView { - (IBAction)onAddContactClick:(id)event { // Go to Contact details view - NSDictionary * dict; + NSArray * calls; if([tableController tempAddress] == nil) { - dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: nil] autorelease] - , @"newContact", - nil] autorelease]; + calls = [NSArray arrayWithObject: [AbstractCall abstractCall:@"newContact"]]; } else { - dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: [tableController tempAddress], nil] autorelease] - , @"newContact:", - nil] autorelease]; + calls = [NSArray arrayWithObject: [AbstractCall abstractCall:@"newContact:", [tableController tempAddress]]]; [tableController setTempAddress:nil]; } - [[PhoneMainView instance] changeView:PhoneView_ContactDetails dict:dict push:TRUE]; + [[PhoneMainView instance] changeView:PhoneView_ContactDetails calls:calls push:TRUE]; } @end diff --git a/Classes/DialerViewController.m b/Classes/DialerViewController.m index dd5370a0a..35c986982 100644 --- a/Classes/DialerViewController.m +++ b/Classes/DialerViewController.m @@ -214,12 +214,9 @@ #pragma mark - Action Functions - (IBAction)onAddContactClick: (id) event { - // Go to Contact details view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects:[addressField text], nil] autorelease] - , @"setAddress:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_Contacts dict:dict push:TRUE]; + [[PhoneMainView instance] changeView:PhoneView_Contacts + calls:[NSArray arrayWithObject:[AbstractCall abstractCall:@"setAddress:", [addressField text]]] + push:TRUE]; } - (IBAction)onBackClick: (id) event { diff --git a/Classes/HistoryDetailsViewController.h b/Classes/HistoryDetailsViewController.h index e31835684..61902b6f6 100644 --- a/Classes/HistoryDetailsViewController.h +++ b/Classes/HistoryDetailsViewController.h @@ -21,8 +21,9 @@ #import "linphonecore.h" #import +#import "UICompositeViewController.h" -@interface HistoryDetailsViewController : UIViewController { +@interface HistoryDetailsViewController : UIViewController { LinphoneCallLog *callLog; UIImageView *avatarImage; UILabel *addressLabel; @@ -46,6 +47,8 @@ @property (nonatomic, assign) LinphoneCallLog *callLog; +- (void)setCallLogValue:(NSValue*)vcallLog; + - (IBAction)onBackClick:(id)event; - (IBAction)onContactClick:(id)event; - (IBAction)onAddressClick:(id)event; diff --git a/Classes/HistoryDetailsViewController.m b/Classes/HistoryDetailsViewController.m index ccbabf51a..cdf42aada 100644 --- a/Classes/HistoryDetailsViewController.m +++ b/Classes/HistoryDetailsViewController.m @@ -52,8 +52,26 @@ } +#pragma mark - UICompositeViewDelegate Functions + ++ (UICompositeViewDescription*) compositeViewDescription { + UICompositeViewDescription *description = [UICompositeViewDescription alloc]; + description->content = @"HistoryDetailsViewController"; + description->tabBar = @"UIMainBar"; + description->tabBarEnabled = true; + description->stateBar = nil; + description->stateBarEnabled = false; + description->fullscreen = false; + return description; +} + + #pragma mark - Property Functions +- (void)setCallLogValue:(NSValue*)vcallLog { + [self setCallLog:[vcallLog pointerValue]]; +} + - (void)setCallLog:(LinphoneCallLog *)acallLog { self->callLog = acallLog; [self update]; diff --git a/Classes/HistoryTableViewController.m b/Classes/HistoryTableViewController.m index 4dff3398e..45a588252 100644 --- a/Classes/HistoryTableViewController.m +++ b/Classes/HistoryTableViewController.m @@ -140,11 +140,10 @@ NSString* dispName = [[NSString alloc] initWithCString:displayName encoding:[NSString defaultCStringEncoding]]; // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: phoneNumber, dispName, nil] autorelease] - , @"call:displayName:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"call:displayName:", phoneNumber, dispName], + nil]]; [phoneNumber release]; [dispName release]; diff --git a/Classes/HistoryViewController.m b/Classes/HistoryViewController.m index f5df61576..f1491fc4b 100644 --- a/Classes/HistoryViewController.m +++ b/Classes/HistoryViewController.m @@ -66,6 +66,7 @@ typedef enum _HistoryView { return description; } + #pragma mark - ViewController Functions - (void)viewWillAppear:(BOOL)animated { diff --git a/Classes/LinphoneUI/UICallBar.m b/Classes/LinphoneUI/UICallBar.m index 42a9319c5..3bb67f760 100644 --- a/Classes/LinphoneUI/UICallBar.m +++ b/Classes/LinphoneUI/UICallBar.m @@ -365,26 +365,22 @@ - (IBAction)onOptionsTransferClick:(id)sender { [self hideOptions]; - // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: @"", nil] autorelease] - , @"setAddress:", - [[[NSArray alloc] initWithObjects: [NSNumber numberWithInt: TRUE], nil] autorelease] - , @"setTransferMode:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; + // Go to dialer view + [[PhoneMainView instance] changeView:PhoneView_Dialer + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"setAddress:", @""], + [AbstractCall abstractCall:@"setTransferMode:", [NSNumber numberWithInt: TRUE]], + nil]]; } - (IBAction)onOptionsAddClick:(id)sender { [self hideOptions]; // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: @"", nil] autorelease] - , @"setAddress:", - [[[NSArray alloc] initWithObjects: [NSNumber numberWithInt: FALSE], nil] autorelease] - , @"setTransferMode:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_Dialer dict:dict]; + [[PhoneMainView instance] changeView:PhoneView_Dialer + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"setAddress:", @""], + [AbstractCall abstractCall:@"setTransferMode:", [NSNumber numberWithInt: FALSE]], + nil]]; } - (IBAction)onOptionsClick:(id)sender { diff --git a/Classes/LinphoneUI/UIChatCell.m b/Classes/LinphoneUI/UIChatCell.m index 851aa24f8..c00994736 100644 --- a/Classes/LinphoneUI/UIChatCell.m +++ b/Classes/LinphoneUI/UIChatCell.m @@ -124,12 +124,12 @@ #pragma mark - Action Functions - (IBAction)onDetailsClick: (id) event { - // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: [chat remoteContact], nil] autorelease] - , @"setRemoteContact:", - nil] autorelease]; - [[PhoneMainView instance] changeView:PhoneView_ChatRoom dict:dict push:TRUE]; + // Go to Chat room view + [[PhoneMainView instance] changeView:PhoneView_ChatRoom + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"setRemoteContact:", [chat remoteContact]], + nil] + push:TRUE]; } - (IBAction)onDeleteClick: (id) event { diff --git a/Classes/LinphoneUI/UIHistoryCell.m b/Classes/LinphoneUI/UIHistoryCell.m index acac6f940..a1944bf45 100644 --- a/Classes/LinphoneUI/UIHistoryCell.m +++ b/Classes/LinphoneUI/UIHistoryCell.m @@ -19,6 +19,7 @@ #import "UIHistoryCell.h" #import "LinphoneManager.h" +#import "PhoneMainView.h" @implementation UIHistoryCell @@ -28,8 +29,6 @@ @synthesize deleteButton; @synthesize detailsButton; -#define DETAILS_DISABLED - #pragma mark - Lifecycle Functions - (id)initWithIdentifier:(NSString*)identifier { @@ -69,7 +68,12 @@ - (IBAction)onDetails:(id) event { if(callLog != NULL) { - + // Go to History details view + [[PhoneMainView instance] changeView:PhoneView_HistoryDetails + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"setCallLogValue:", [NSValue valueWithPointer: callLog]], + nil] + push:TRUE]; } } @@ -120,11 +124,7 @@ [deleteButton setAlpha:1.0f]; [detailsButton setAlpha:0.0f]; } else { -#ifdef DETAILS_DISABLED - [detailsButton setAlpha:0.0f]; -#else - [detailsButtonsetAlpha:1.0f]; -#endif + [detailsButton setAlpha:1.0f]; [deleteButton setAlpha:0.0f]; } if(animated) { diff --git a/Classes/LinphoneUI/UIMainBar.m b/Classes/LinphoneUI/UIMainBar.m index f7cd3c63e..1cfb7d105 100644 --- a/Classes/LinphoneUI/UIMainBar.m +++ b/Classes/LinphoneUI/UIMainBar.m @@ -155,7 +155,7 @@ } // Update buttons - if(view == PhoneView_History) { + if(view == PhoneView_History || view == PhoneView_HistoryDetails) { historyButton.selected = TRUE; } else { historyButton.selected = FALSE; diff --git a/Classes/PhoneMainView.h b/Classes/PhoneMainView.h index 212884dea..6b887e1b1 100644 --- a/Classes/PhoneMainView.h +++ b/Classes/PhoneMainView.h @@ -23,12 +23,14 @@ #import "CallDelegate.h" #import "UICompositeViewController.h" #import "UIModalViewController.h" +#import "AbstractCall.h" typedef enum _PhoneView { PhoneView_Wizard, PhoneView_FirstLogin, PhoneView_Dialer, PhoneView_History, + PhoneView_HistoryDetails, PhoneView_Settings, PhoneView_Chat, PhoneView_ChatRoom, @@ -58,10 +60,10 @@ typedef enum _PhoneView { - (void)changeView:(PhoneView)view; - (void)changeView:(PhoneView)view push:(BOOL)push; -- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict; -- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict push:(BOOL)push; +- (void)changeView:(PhoneView)view calls:(NSArray *)calls; +- (void)changeView:(PhoneView)view calls:(NSArray *)calls push:(BOOL)push; - (void)popView; -- (void)popView:(NSDictionary *)dict; +- (void)popView:(NSArray *)calls; - (void)showTabBar:(BOOL)show; - (void)fullScreen:(BOOL)enabled; - (PhoneView)currentView; diff --git a/Classes/PhoneMainView.m b/Classes/PhoneMainView.m index 0eab53ed0..d8b83fbac 100644 --- a/Classes/PhoneMainView.m +++ b/Classes/PhoneMainView.m @@ -28,14 +28,14 @@ #import "ChatViewController.h" #import "DialerViewController.h" #import "ContactsViewController.h" +#import "ContactDetailsViewController.h" #import "HistoryViewController.h" +#import "HistoryDetailsViewController.h" #import "InCallViewController.h" #import "SettingsViewController.h" #import "FirstLoginViewController.h" #import "WizardViewController.h" -#import "ContactDetailsViewController.h" -#import "AbstractCall.h" #import "UIView+ModalStack.h" static PhoneMainView* phoneMainViewInstance=nil; @@ -111,12 +111,13 @@ static PhoneMainView* phoneMainViewInstance=nil; [viewDescriptions setObject:[ChatViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Chat]]; [viewDescriptions setObject:[DialerViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Dialer]]; [viewDescriptions setObject:[ContactsViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Contacts]]; + [viewDescriptions setObject:[ContactDetailsViewController compositeViewDescription] forKey:[NSNumber numberWithInt:PhoneView_ContactDetails]]; [viewDescriptions setObject:[HistoryViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_History]]; + [viewDescriptions setObject:[HistoryDetailsViewController compositeViewDescription] forKey:[NSNumber numberWithInt:PhoneView_HistoryDetails]]; [viewDescriptions setObject:[InCallViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_InCall]]; [viewDescriptions setObject:[SettingsViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Settings]]; [viewDescriptions setObject:[FirstLoginViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_FirstLogin]]; [viewDescriptions setObject:[WizardViewController compositeViewDescription] forKey:[NSNumber numberWithInt: PhoneView_Wizard]]; - [viewDescriptions setObject:[ContactDetailsViewController compositeViewDescription] forKey:[NSNumber numberWithInt:PhoneView_ContactDetails]]; } - (void)viewWillAppear:(BOOL)animated { @@ -235,13 +236,11 @@ static PhoneMainView* phoneMainViewInstance=nil; [self dismissIncomingCall:call]; if (canHideInCallView) { // Go to dialer view - NSDictionary *dict = [[[NSDictionary alloc] initWithObjectsAndKeys: - [[[NSArray alloc] initWithObjects: @"", nil] autorelease] - , @"setAddress:", - [[[NSArray alloc] initWithObjects: [NSNumber numberWithInt: FALSE], nil] autorelease] - , @"setTransferMode:", - nil] autorelease]; - [self changeView:PhoneView_Dialer dict:dict]; + [self changeView:PhoneView_Dialer + calls:[NSArray arrayWithObjects: + [AbstractCall abstractCall:@"setAddress:", @""], + [AbstractCall abstractCall:@"setTransferMode:", [NSNumber numberWithInt: FALSE]], + nil]]; } else { [self changeView:PhoneView_InCall]; } @@ -283,7 +282,7 @@ static PhoneMainView* phoneMainViewInstance=nil; + (CATransition*)getTransition:(PhoneView)old new:(PhoneView)new { bool left = false; - if(old == PhoneView_Chat) { + if(old == PhoneView_Chat || old == PhoneView_ChatRoom) { if(new == PhoneView_Contacts || new == PhoneView_Dialer || new == PhoneView_Settings || @@ -301,7 +300,7 @@ static PhoneMainView* phoneMainViewInstance=nil; new == PhoneView_History) { left = true; } - } else if(old == PhoneView_Contacts) { + } else if(old == PhoneView_Contacts || old == PhoneView_ContactDetails) { if(new == PhoneView_History) { left = true; } @@ -327,27 +326,27 @@ static PhoneMainView* phoneMainViewInstance=nil; } - (void)changeView:(PhoneView)view { - [self changeView:view dict:nil push:FALSE]; + [self changeView:view calls:nil push:FALSE]; } -- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict { - [self changeView:view dict:dict push:FALSE]; +- (void)changeView:(PhoneView)view calls:(NSArray *)dict { + [self changeView:view calls:dict push:FALSE]; } - (void)changeView:(PhoneView)view push:(BOOL)push { - [self changeView:view dict:nil push:push]; + [self changeView:view calls:nil push:push]; } -- (void)changeView:(PhoneView)view dict:(NSDictionary *)dict push:(BOOL)push { +- (void)changeView:(PhoneView)view calls:(NSArray *)calls push:(BOOL)push { if(push && currentView != -1) { [viewStack addObject:[NSNumber numberWithInt: currentView]]; } else { [viewStack removeAllObjects]; } - [self _changeView:view dict:dict transition:nil]; + [self _changeView:view calls:calls transition:nil]; } -- (void)_changeView:(PhoneView)view dict:(NSDictionary *)dict transition:(CATransition*)transition { +- (void)_changeView:(PhoneView)view calls:(NSArray *)calls transition:(CATransition*)transition { UICompositeViewDescription* description = [viewDescriptions objectForKey:[NSNumber numberWithInt: view]]; if(description == nil) return; @@ -361,8 +360,11 @@ static PhoneMainView* phoneMainViewInstance=nil; } // Call abstractCall - if(dict != nil) - [AbstractCall call:[mainViewController getCurrentViewController] dict:dict]; + if(calls != nil) { + for(AbstractCall *call in calls) { + [call call:[mainViewController getCurrentViewController]]; + } + } NSDictionary* mdict = [NSMutableDictionary dictionaryWithObject: [NSNumber numberWithInt:currentView] forKey:@"view"]; [[NSNotificationCenter defaultCenter] postNotificationName:@"LinphoneMainViewChange" object:self userInfo:mdict]; @@ -372,11 +374,11 @@ static PhoneMainView* phoneMainViewInstance=nil; [self popView:nil]; } -- (void)popView:(NSDictionary *)dict { +- (void)popView:(NSArray *)calls { if([viewStack count] > 0) { PhoneView view = [[viewStack lastObject] intValue]; [viewStack removeLastObject]; - [self _changeView:view dict:dict transition:[PhoneMainView getBackwardTransition]]; + [self _changeView:view calls:calls transition:[PhoneMainView getBackwardTransition]]; } } diff --git a/Classes/Utils/AbstractCall.h b/Classes/Utils/AbstractCall.h index 170c022ab..0be1a57e0 100644 --- a/Classes/Utils/AbstractCall.h +++ b/Classes/Utils/AbstractCall.h @@ -19,9 +19,17 @@ #import + @interface AbstractCall : NSObject { + NSString *functionName; + NSArray *functionArgs; } -+ (void)call:(id) object dict:(NSDictionary *) dict; +@property (retain) NSString *functionName; +@property (retain) NSArray *functionArgs; + ++ (id)abstractCall:(NSString *)name, ...; +- (id)init:(NSString *)name, ...; +- (void)call:(id) object; @end diff --git a/Classes/Utils/AbstractCall.m b/Classes/Utils/AbstractCall.m index 8a76bd041..7c9f35780 100644 --- a/Classes/Utils/AbstractCall.m +++ b/Classes/Utils/AbstractCall.m @@ -21,26 +21,69 @@ @implementation AbstractCall -+ (void)call:(id) object dict:(NSDictionary *) dict { - for (NSString* identifier in dict) { - if([identifier characterAtIndex:([identifier length] -1)] == ':') { - NSArray *arguments = [dict objectForKey:identifier]; - SEL selector = NSSelectorFromString(identifier); - NSMethodSignature *signature = [object methodSignatureForSelector:selector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; - [invocation setTarget:object]; - [invocation setSelector:selector]; - for(int i=0; i<[arguments count]; i++) - { - id arg = [arguments objectAtIndex:i]; - [invocation setArgument:&arg atIndex:i+2]; // The first two arguments are the hidden arguments self and _cmd +@synthesize functionName; +@synthesize functionArgs; + ++ (id)abstractCall:(NSString *)name, ... { + AbstractCall *object; + va_list args; + va_start(args, name); + object = [[AbstractCall alloc] init:name args:args]; + va_end(args); + return [object autorelease]; +} + +- (id)init:(NSString *)name, ... { + AbstractCall *object; + va_list args; + va_start(args, name); + object = [self init:name args:args]; + va_end(args); + return object; +} + +- (id)init:(NSString *)name args:(va_list)args { + self = [super init]; + if(self != nil) { + self->functionName = name; + NSMutableArray *array = [[NSMutableArray alloc] init]; + int count = 0; + for(int i = 0; i < [self->functionName length]; ++i) { + if([self->functionName characterAtIndex:i] == ':') { + ++count; } - [invocation invoke]; // Invoke the selector - } else { - NSDictionary *arguments = [dict objectForKey:identifier]; - id new_object = [object performSelector:NSSelectorFromString(identifier)]; - [AbstractCall call:new_object dict:arguments]; } + for (int i = 0; i < count; ++i) { + id arg = va_arg(args, id); + [array addObject:arg]; + } + self->functionArgs = array; + } + return self; +} + +- (void)dealloc { + [functionName release]; + [functionArgs release]; + + [super dealloc]; +} + +- (void)call:(id)object { + @try { + SEL selector = NSSelectorFromString(functionName); + NSMethodSignature *signature = [object methodSignatureForSelector:selector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + [invocation setTarget:object]; + [invocation setSelector:selector]; + for(int i=0; i<[functionArgs count]; i++) + { + id arg = [functionArgs objectAtIndex:i]; + [invocation setArgument:&arg atIndex:i+2]; // The first two arguments are the hidden arguments self and _cmd + } + [invocation invoke]; // Invoke the selector + } @catch (NSException *exception) { + NSLog(@"Abstract Call: Can't call %@ with arguments %@ on %@", functionName, functionArgs, object); } }