mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +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
f59ba481f0
commit
026d6fc751
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>
|
||||
|
||||
* Source/Additions/GSCompatibility.h:
|
||||
|
|
|
@ -116,9 +116,66 @@ GSObjCMethodNames(id obj, BOOL recurse);
|
|||
GS_EXPORT NSArray *
|
||||
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
|
||||
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 *
|
||||
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
|
||||
GSObjCAddClassBehavior(Class receiver, Class behavior)
|
||||
{
|
||||
|
@ -853,6 +829,55 @@ GSObjCAddClassBehavior(Class receiver, Class behavior)
|
|||
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