quakeforge/ruamoko/lib/Object.r

324 lines
7.3 KiB
R

#include "Object.h"
#include "AutoreleasePool.h"
void (obj_module_t [] msg) __obj_exec_class = #0;
void (id object, integer code, string fmt, ...) obj_error = #0;
void (id object, integer code, string fmt, @va_list args) obj_verror = #0;
//obj_error_handler (objc_error_handler func) obj_set_error_handler = #0;
IMP (id receiver, SEL op) obj_msg_lookup = #0;
IMP (Super class, SEL op) obj_msg_lookup_super = #0;
id (id receiver, SEL op, ...) obj_msgSend = #0;
id (Super[] class, SEL op, ...) obj_msgSend_super = #0;
@param (id receiver, SEL op, @va_list args) obj_msg_sendv = #0;
(void []) (integer size) obj_malloc = #0;
(void []) (integer size) obj_atomic_malloc = #0;
(void []) (integer size) obj_valloc = #0;
(void []) (void [] mem, integer size) obj_realloc = #0;
(void []) (integer nelem, integer size) obj_calloc = #0;
void (void [] mem) obj_free = #0;
//(void []) (void) obj_get_uninstalled_dtable = #0;
Class (string name) obj_get_class = #0;
Class (string name) obj_lookup_class = #0;
//Class (void [][] enum_stage) obj_next_class = #0;
string (SEL selector) sel_get_name = #0;
string (SEL selector) sel_get_type = #0;
SEL (string name) sel_get_uid = #0;
//SEL (string name) sel_get_any_uid = #0;
//SEL (string name) sel_get_any_typed_uid = #0;
//SEL (string name, string type) sel_get_typed_uid = #0;
SEL (string name) sel_register_name = #0;
//SEL (string name, string type) sel_register_typed_name = #0;
BOOL (SEL aSel) sel_is_mapped = #0;
Method [](Class class, SEL aSel) class_get_class_method = #0;
Method [](Class class, SEL aSel) class_get_instance_method = #0;
Class (Class imposter, Class superclass) class_pose_as = #0;
id (Class class) class_create_instance = #0;
string (Class class) class_get_class_name = #0;
integer (Class class) class_get_instance_size = #0;
Class (Class class) class_get_meta_class = #0;
Class (Class class) class_get_super_class = #0;
integer (Class class) class_get_version = #0;
BOOL (Class class) class_is_class = #0;
BOOL (Class class) class_is_meta_class = #0;
void (Class class, integer version) class_set_version = #0;
(void []) (Class class) class_get_gc_object_type = #0;
void (Class class, string ivarname, BOOL gcInvisible) class_ivar_set_gcinvisible = #0;
IMP (Method []method) method_get_imp = #0;
IMP (Class class, SEL sel) get_imp = #0;
id (id object) object_copy = #0;
id (id object) object_dispose = #0;
Class (id object) object_get_class = #0;
string (id object) object_get_class_name = #0;
Class (id object) object_get_meta_class = #0;
Class (id object) object_get_super_class = #0;
BOOL (id object) object_is_class = #0;
BOOL (id object) object_is_instance = #0;
BOOL (id object) object_is_meta_class = #0;
@implementation Object (error)
- (void) error: (string)aString, ... = #0;
@end
@static BOOL allocDebug;
@static Class autoreleaseClass;
@static SEL autoreleaseSelector;
@static IMP autoreleaseIMP;
@implementation Object
+ (void) initialize
{
//allocDebug = localinfo ("AllocDebug");
autoreleaseClass = [AutoreleasePool class];
autoreleaseSelector = @selector(addObject:);
autoreleaseIMP = [autoreleaseClass methodForSelector: autoreleaseSelector];
return;
}
+ (id) alloc
{
return class_create_instance (self);
}
+ (Class) class
{
return self;
}
+ (Class) superclass
{
return class_get_super_class (self);
}
+ (string) description
{
return class_get_class_name (self);
}
+ (id) new
{
return [[self alloc] init];
}
+ (BOOL) isKindOfClass: (Class)aClass
{
if (aClass == [Object class])
return YES;
return NO;
}
+ (BOOL) conformsToProtocol: (Protocol)aProtocol = #0;
+ (BOOL) instancesRespondToSelector: (SEL)aSelector
{
return class_get_instance_method (self, aSelector) != NIL;
}
+ (BOOL) respondsToSelector: (SEL)aSelector
{
return (class_get_class_method (self, aSelector) != NIL);
}
/*
Returns a pointer to the function providing the instance method that is
used to respond to messages with the selector held in aSelector.
*/
+ (IMP) instanceMethodForSelector: (SEL)aSelector
{
if (!aSelector)
return NIL;
return method_get_imp (class_get_instance_method (self, aSelector));
}
+ (void) poseAsClass: (Class)aClass
{
class_pose_as (self, aClass);
}
/*
INSTANCE METHODS
*/
- (id) init
{
retainCount = 1;
return self;
}
- (void) dealloc
{
object_dispose (self);
}
- (Class) class
{
return object_get_class (self);
}
- (Class) superclass
{
return object_get_super_class (self);
}
- (string) description
{
return object_get_class_name (self);
}
- (id) self
{
return self;
}
- (unsigned) hash = #0; // can't cast pointer to integer
- (BOOL) isEqual: (id)anObject
{
return self == anObject;
}
- (BOOL) isKindOfClass: (Class)aClass
{
local Class class;
for (class = [self class]; class; class = class_get_super_class (class))
if (class == aClass)
return YES;
return NO;
}
- (BOOL) isMemberOfClass: (Class)aClass
{
return ([self class] == aClass);
}
- (BOOL) respondsToSelector: (SEL)aSelector
{
return (class_get_instance_method ([self class], aSelector) != NIL);
}
- (BOOL) conformsToProtocol: (Protocol [])aProtocol
{
return [[self class] conformsToProtocol: aProtocol];
}
/*
Returns a pointer to the function providing the method used to respond to
aSelector. If "self" is an instance, an instance method is returned. If
it's a class, a class method is returned.
*/
- (IMP) methodForSelector: (SEL)aSelector
{
local Class myClass = [self class];
if (!aSelector)
return NIL;
return method_get_imp (object_is_instance (self)
? class_get_instance_method (myClass, aSelector)
: class_get_class_method (myClass, aSelector));
}
//+(struct objc_method_description *)descriptionForInstanceMethod:(SEL)aSel = #0;
//-(struct objc_method_description *)descriptionForMethod:(SEL)aSel = #0;
- (id) performSelector: (SEL)aSelector
{
local IMP msg;
if (!aSelector || !(msg = obj_msg_lookup (self, aSelector)))
[self error: "invalid selector passed to %s: %s",
object_get_class_name (self),
sel_get_name (aSelector)];
return msg (self, aSelector);
}
- (id) performSelector: (SEL)aSelector withObject: (id)anObject
{
local IMP msg;
if (!aSelector || !(msg = obj_msg_lookup (self, aSelector)))
[self error: "invalid selector passed to %s: %s",
object_get_class_name (self),
sel_get_name (aSelector)];
return msg (self, aSelector, anObject);
}
- (id) performSelector: (SEL)aSelector
withObject: (id)anObject
withObject: (id)anotherObject
{
local IMP msg;
if (!aSelector || !(msg = obj_msg_lookup (self, aSelector)))
[self error: "invalid selector passed to %s",
sel_get_name (_cmd)];
return msg (self, aSelector, anObject, anotherObject);
}
- (void) doesNotRecognizeSelector: (SEL)aSelector
{
[self error: "%s does not recognize %s",
object_get_class_name (self),
sel_get_name (aSelector)];
}
/*
MEMORY MANAGEMENT
These methods handle the manual garbage collection scheme.
*/
- (id) retain
{
retainCount = [self retainCount] + 1;
return self;
}
- (/*oneway*/ void) release
{
if ([self retainCount] == 1) // don't let retain count actually reach zero
[self dealloc];
else
retainCount--;
}
- (id) autorelease
{
autoreleaseIMP (autoreleaseClass, autoreleaseSelector, self);
return self;
}
- (unsigned) retainCount
{
return retainCount;
}
/*
CONVENIENCE METHODS
These methods exist only so that certain methods always work.
*/
- (id) copy
{
return self;
}
- (id) mutableCopy
{
return self;
}
@end