/* Copyright (c) 2003, Steve Dekorte * All rights reserved. See _BSDLicense.txt. */ #include "ObjcSubclass.h" #include "List.h" #include "IoState.h" #include "IoMessage.h" #include #include "Objc2Io.h" /* * globals are evil, but Objective-C classes are globals already, * so who cares if we have these globals for tracking the ones we add? * * IMPORTANT: can't use this addon with multiple Io states. */ static IoState *state = NULL; static Hash *classProtos = NULL; @implementation ObjcSubclass + new { return [[self alloc] init]; } + (Hash *)classProtos { if (!classProtos) classProtos = Hash_new(); return classProtos; } + (void)mark { if (classProtos) { Hash *h = classProtos; IoObject *k = Hash_firstKey(h); while (k) { IoObject *v = Hash_at_(h, k); IoObject_shouldMark(v); k = Hash_nextKey(h); } } } + (Class)newClassNamed:(IoSymbol *)ioName proto:(IoObject *)proto { Class class = objc_makeClass(CSTRING(ioName), "ObjcSubclass", NO); objc_addClass(class); state = proto->tag->state; if (class) Hash_at_put_([self classProtos], ioName, proto); return class; } /*- (BOOL)respondsToSelector:(SEL)sel { BOOL r = [super respondsToSelector:sel]; //printf("ObjcSubclass respondsToSelector:\"%s\"] = %i\n", (char *)sel_getName(sel), r); return r; }*/ + (id)allocWithZone:(NSZone *)zone { id v = [super allocWithZone:zone]; //printf("ObjcSubclass allocWithZone\n"); [v setProto]; return v; } + alloc { id v = [super alloc]; //printf("[ObjcSubclass alloc]\n"); //[v setProto]; return v; } - (void)setProto { const char *s = [[self className] cString]; printf("classname = %s state = %p\n", s, state); if (state) { IoSymbol *className = IoState_symbolWithCString_(state, (char *)s); IoObject *proto = (IoObject *)Hash_at_((void *)[[self class] classProtos], className); [super init]; ioValue = (IoObject *)IOCLONE(proto); bridge = IoObjcBridge_sharedBridge(); IoObjcBridge_addValue_(bridge, ioValue, self); } } - copy { id obj = [super copy]; NSMethodSignature *methodSignature=[self methodSignatureForSelector:@selector(copy)]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; [invocation setTarget:obj]; [invocation setSelector:@selector(copy)]; [self forwardInvocation:invocation]; [invocation getReturnValue:&obj]; return obj; } //- copyWithZone:(NSZone *)zone //{ // id obj = [super copyWithZone:zone]; // NSMethodSignature *methodSignature = [self methodSignatureForSelector:@selector(copyWithZone:)]; // NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; // [invocation setTarget:obj]; // [invocation setSelector:@selector(copyWithZone:)]; // [invocation setArgument:zone atIndex:2]; // [self forwardInvocation:invocation]; // [invocation getReturnValue:&obj]; // return obj; //} - init { id obj = [super init]; NSMethodSignature *methodSignature = [self methodSignatureForSelector:@selector(init)]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; [invocation setTarget:obj]; [invocation setSelector:@selector(init)]; [self forwardInvocation:invocation]; [invocation getReturnValue:&obj]; return obj; } - mutableCopy { id obj = [super mutableCopy]; NSMethodSignature *methodSignature = [self methodSignatureForSelector:@selector(mutableCopy)]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; [invocation setTarget:obj]; [invocation setSelector:@selector(mutableCopy)]; [self forwardInvocation:invocation]; [invocation getReturnValue:&obj]; return obj; } @end