home *** CD-ROM | disk | FTP | other *** search
- /* SelPairAgent.m
- * Written By: Thomas Burkholder
- *
- * You may freely copy, distribute, and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to its
- * fitness for any particular use.
- */
-
- #import "../Utilities.subproj/ClassAdditions.h"
- #import "SelectorBrowsingFunctions.h"
- #import "SelPairAgent.h"
- #import "TBinderListConnectInspector.h"
- #import <objc/objc-class.h>
- #import <apps/InterfaceBuilder.h>
-
- #define T_UNKNOWN 0
- #define T_ORDINAL 1
- #define T_STRING 2
- #define T_OBJECT 3
- #define T_SELECTOR 4
-
- int abstractType(char c)
- {
- if ((c==*@encode(char)) || (c==*@encode(int)) ||
- (c==*@encode(short)) || (c==*@encode(long)) ||
- (c==*@encode(unsigned char)) || (c==*@encode(unsigned int)) ||
- (c==*@encode(unsigned short)) || (c==*@encode(unsigned long)) ||
- (c==*@encode(float)) || (c==*@encode(double)))
- return T_ORDINAL;
- if (c==*@encode(char *)) return T_STRING;
- if (c==*@encode(id)) return T_OBJECT;
- if (c==*@encode(SEL)) return T_SELECTOR;
- return T_UNKNOWN;
- }
-
- void filterForReturnTypes(id storage, id srcClass, SEL srcSelector,id destClass)
- {
- // Icky, nasty. storage is assumed to contain SEL's. srcClass and
- // srcSelector give us the templateArgs - the arg types of the
- // srcSelector method in the srcClass class. destClass we need, in
- // order to get the arg types of each selector in the storage.
- int i,tp1,tp2;
-
- // we get the arg types from class and aSelector:
- struct objc_method *m = class_getInstanceMethod(srcClass,srcSelector);
- const char *candidateArgs, *templateArgs = m->method_types;
-
- // eliminate all selectors whose return values don't match.
-
- for(i=0;(i<[storage count]);) {
- m = class_getInstanceMethod(destClass,*(SEL *)[storage elementAt:i]);
- candidateArgs = m->method_types;
- // Some primitive type-matching, taking advantage of type
- // coersion...
- tp1 = abstractType(candidateArgs[0]);
- tp2 = abstractType(templateArgs[0]);
- if ((candidateArgs[0]==templateArgs[0])||(tp1&&tp2&&(tp1==tp2)))
- i++;
- else
- [storage removeElementAt:i];
- }
- }
-
- @implementation SelPairAgent
-
- - initFrom:anObject
- {
- // A bit crude; we use initialStorage to determine leafdom.
- [super init];
- initialStorage = anObject;
- secondaryStorage = [[SortedStorage alloc] init];
- [secondaryStorage setAgent:self];
- return self;
- }
-
- - free
- {
- [secondaryStorage free];
- return [super free];
- }
-
- - subdirectoryFor:(void *)anElement sender:sender
- {
- if (sender != initialStorage || ![NXApp isConnecting])
- return nil;
- [[[NXApp connectDestination] class] methodSelectors:secondaryStorage
- includeAncestors:YES
- filterWith:isAccessor];
- // match the return type of the selected SEL.
- filterForReturnTypes(secondaryStorage,
- [[getDSConnectorForSource([NXApp connectSource]) destination] class],
- *(SEL *)anElement,
- [[NXApp connectDestination] class]);
- return secondaryStorage;
- }
-
- - (BOOL)isLeaf:(void *)anElement sender:sender
- {
- return (![NXApp isConnecting] || sender != initialStorage);
- }
-
- - (const char *)displayStringFor:(void *)anElement sender:sender
- {
- return sel_getName(*(SEL *)anElement);
- }
-
- - (int)compare:(void *)first with:(void *)second sender:sender
- {
- return strcmp(sel_getName(*(SEL *)first), sel_getName(*(SEL *)second));
- }
-
- - (const char *)titleOfColumn:(int)col
- {
- return (col)?"Interface":"DataSource";
- }
-
- @end