mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-03 13:21:00 +00:00
Add mechanism for gdl2.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29866 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
95ced52af1
commit
53165d0baf
3 changed files with 114 additions and 24 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2010-03-07 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Source/Additions/GSObjCRuntime.m:
|
||||||
|
* Headers/Additions/GNUstepBase/GSObjCRuntime.h:
|
||||||
|
Add function to add 'overrides' as a form of programmatically
|
||||||
|
controlled category similar to behaviors, giving an app control
|
||||||
|
over the order in which methods are added to a class.
|
||||||
|
|
||||||
2010-03-05 Richard Frith-Macdonald <rfm@gnu.org>
|
2010-03-05 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/Additions/GSCompatibility.h:
|
* Source/Additions/GSCompatibility.h:
|
||||||
|
|
|
@ -116,9 +116,66 @@ GSObjCMethodNames(id obj, BOOL recurse);
|
||||||
GS_EXPORT NSArray *
|
GS_EXPORT NSArray *
|
||||||
GSObjCVariableNames(id obj, BOOL recurse);
|
GSObjCVariableNames(id obj, BOOL recurse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>A Behavior can be seen as a "Protocol with an implementation" or a
|
||||||
|
* "Class without any instance variables". A key feature of behaviors
|
||||||
|
* is that they give a degree of multiple inheritance.
|
||||||
|
* </p>
|
||||||
|
* <p>Behavior methods, when added to a class, override the class's
|
||||||
|
* superclass methods, but not the class's methods.
|
||||||
|
* </p>
|
||||||
|
* <p>Whan a behavior class is added to a receiver class, not only are the
|
||||||
|
* methods defined in the behavior class added, but the methods from the
|
||||||
|
* behavior's class hierarchy are also added (unless already present).
|
||||||
|
* </p>
|
||||||
|
* <p>It's not the case that a class adding behaviors from another class
|
||||||
|
* must have "no instance vars". The receiver class just has to have the
|
||||||
|
* same layout as the behavior class (optionally with some additional
|
||||||
|
* ivars after those of the behavior class).
|
||||||
|
* </p>
|
||||||
|
* <p>This function provides Behaviors without adding any new syntax to
|
||||||
|
* the Objective C language. Simply define a class with the methods you
|
||||||
|
* want to add, then call this function with that class as the behavior
|
||||||
|
* argument.
|
||||||
|
* </p>
|
||||||
|
* <p>This function should be called in the +initialize method of the receiver.
|
||||||
|
* </p>
|
||||||
|
* <p>If you add several behaviors to a class, be aware that the order of
|
||||||
|
* the additions is significant.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
GS_EXPORT void
|
GS_EXPORT void
|
||||||
GSObjCAddClassBehavior(Class receiver, Class behavior);
|
GSObjCAddClassBehavior(Class receiver, Class behavior);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>An Override can be seen as a "category implemented as a separate class
|
||||||
|
* and manually added to the receiver class under program control, rather
|
||||||
|
* than automatically added by the compiler/runtime.
|
||||||
|
* </p>
|
||||||
|
* <p>Override methods, when added to a receiver class, replace the class's
|
||||||
|
* class's methods of the same name (or are added if the class did not define
|
||||||
|
* methods with that name).
|
||||||
|
* </p>
|
||||||
|
* <p>It's not the case that a class adding overrides from another class
|
||||||
|
* must have "no instance vars". The receiver class just has to have the
|
||||||
|
* same layout as the override class (optionally with some additional
|
||||||
|
* ivars after those of the override class).
|
||||||
|
* </p>
|
||||||
|
* <p>This function provides overrides without adding any new syntax to
|
||||||
|
* the Objective C language. Simply define a class with the methods you
|
||||||
|
* want to add, then call this function with that class as the override
|
||||||
|
* argument.
|
||||||
|
* </p>
|
||||||
|
* <p>This function should usually be called in the +initialize method
|
||||||
|
* of the receiver.
|
||||||
|
* </p>
|
||||||
|
* <p>If you add several overrides to a class, be aware that the order of
|
||||||
|
* the additions is significant.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
GS_EXPORT void
|
||||||
|
GSObjCAddClassOverride(Class receiver, Class override);
|
||||||
|
|
||||||
GS_EXPORT NSValue *
|
GS_EXPORT NSValue *
|
||||||
GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary *iVars);
|
GSObjCMakeClass(NSString *name, NSString *superName, NSDictionary *iVars);
|
||||||
|
|
||||||
|
|
|
@ -757,30 +757,6 @@ GSProtocolFromName(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>A Behavior can be seen as a "Protocol with an implementation" or a
|
|
||||||
* "Class without any instance variables". A key feature of behaviors
|
|
||||||
* is that they give a degree of multiple inheritance.
|
|
||||||
* </p>
|
|
||||||
* <p>Behavior methods, when added to a class, override the class's
|
|
||||||
* superclass methods, but not the class's methods.
|
|
||||||
* </p>
|
|
||||||
* <p>It's not the case that a class adding behaviors from another class
|
|
||||||
* must have "no instance vars". The receiver class just has to have the
|
|
||||||
* same layout as the behavior class (optionally with some additional
|
|
||||||
* ivars after those of the behavior class).
|
|
||||||
* </p>
|
|
||||||
* <p>This function provides Behaviors without adding any new syntax to
|
|
||||||
* the Objective C language. Simply define a class with the methods you
|
|
||||||
* want to add, then call this function with that class as the behavior
|
|
||||||
* argument.
|
|
||||||
* </p>
|
|
||||||
* <p>This function should be called in the +initialize method of the receiver.
|
|
||||||
* </p>
|
|
||||||
* <p>If you add several behaviors to a class, be aware that the order of
|
|
||||||
* the additions is significant.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
GSObjCAddClassBehavior(Class receiver, Class behavior)
|
GSObjCAddClassBehavior(Class receiver, Class behavior)
|
||||||
{
|
{
|
||||||
|
@ -853,6 +829,55 @@ GSObjCAddClassBehavior(Class receiver, Class behavior)
|
||||||
GSFlushMethodCacheForClass (receiver);
|
GSFlushMethodCacheForClass (receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GSObjCAddClassOverride(Class receiver, Class override)
|
||||||
|
{
|
||||||
|
unsigned int count;
|
||||||
|
Method *methods;
|
||||||
|
|
||||||
|
if (YES == class_isMetaClass(receiver))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Trying to add override (%s) to meta class (%s)\n",
|
||||||
|
class_getName(override), class_getName(receiver));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (YES == class_isMetaClass(override))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Trying to add meta class as override (%s) to (%s)\n",
|
||||||
|
class_getName(override), class_getName(receiver));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (class_getInstanceSize(receiver) < class_getInstanceSize(override))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Trying to add override (%s) with instance "
|
||||||
|
"size larger than class (%s)\n",
|
||||||
|
class_getName(override), class_getName(receiver));
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
BDBGPrintf("Adding override to class %s\n", class_getName(receiver));
|
||||||
|
BDBGPrintf(" instance methods from %s\n", class_getName(override));
|
||||||
|
|
||||||
|
/* Add instance methods */
|
||||||
|
methods = class_copyMethodList(override, &count);
|
||||||
|
if (methods != NULL)
|
||||||
|
{
|
||||||
|
GSObjCAddMethods (receiver, methods, YES);
|
||||||
|
free(methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add class methods */
|
||||||
|
BDBGPrintf("Adding class methods from %s\n",
|
||||||
|
class_getName(object_getClass(override)));
|
||||||
|
methods = class_copyMethodList(object_getClass(override), &count);
|
||||||
|
if (methods != NULL)
|
||||||
|
{
|
||||||
|
GSObjCAddMethods (object_getClass(receiver), methods, YES);
|
||||||
|
free(methods);
|
||||||
|
}
|
||||||
|
GSFlushMethodCacheForClass (receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue