Hi Richard, all,

While updating QuartzCore under GNUstep, I ran into an obscure issue caused
by Richard's July 20th commit, revision 35304 with log message:

"Use GSSelectorTypesMatch() for types comparison where we are interested in
types but not qualifiers and stack layout information."

Primarily I'm having trouble with changes to NSValue.m around what's line
197 in revision 35403 (the revision of -base that I currently use). Here
are the changes to + (Class) valueClassWithObjCType: (const char *)type.

 35304        rfm   /* Try for equivalent types match.
 35304        rfm    */
 35304        rfm   else if (GSSelectorTypesMatch(@encode(id), type))
 35304        rfm     theClass = nonretainedObjectValueClass;
 35304        rfm   else if (GSSelectorTypesMatch(@encode(NSPoint), type))
 35304        rfm     theClass = pointValueClass;
 35304        rfm   else if (GSSelectorTypesMatch(@encode(void *), type))
 35304        rfm     theClass = pointerValueClass;
 35304        rfm   else if (GSSelectorTypesMatch(@encode(NSRange), type))
 35304        rfm     theClass = rangeValueClass;
 35304        rfm   else if (GSSelectorTypesMatch(@encode(NSRect), type))
 35304        rfm     theClass = rectValueClass;
 35304        rfm   else if (GSSelectorTypesMatch(@encode(NSSize), type))
 35304        rfm     theClass = sizeValueClass;
 35304        rfm

I'm currently considering this a bug, since the above behavior differs from
Cocoa's. Under Cocoa, if I request to store a CGPoint inside a NSValue
using @encode(CGPoint), that's exactly what I get out. However, with
GNUstep, if I store a CGPoint into a NSValue, I get a NSPoint out of it,
wreaking havoc with my current code that handles case when these structs
don't have equal members.

While this would ordinarily be a very welcome change and I'd love it if
Cocoa did the same, unfortunately it doesn't. Here's a part of my code that
breaks (for further context, see -calculatedAnimationValueAtTime:onLayer:
in libs/quartzcore/trunk/CAAnimation.m):

      /*
      NSValue * from = ....;
      */

      if (!strcmp([from objCType], @encode(NSPoint)))
        {
          CGPoint fromPt = CGPointMake([from pointValue].x, [from
pointValue].y);
          from = [NSValue valueWithBytes: &fromPt objCType:
@encode(CGPoint)];
        }
      if (!strcmp([from objCType], @encode(CGPoint)))
        {
          // ... actual handling of both NSPoint and CGPoint here
          return;
        }
      if (...

This code takes care of possibility that CGPoint, the native point type
that I work with, has different data types than NSPoint. Under GNUstep, it
trips up in case the data types are the same.

I'll modify the CGPoint section of my code to accept both NSPoint and
CGPoint; since the 'from' and 'to' values that happened to be NSPoints were
already replaced with a CGPoint, and -base erroneously decided to consider
the value a NSPoint just because all struct members are of equal type, it's
safe to extract values and put them in a CGPoint (they're surely that
already). However, it's still just a workaround; who knows what other
problems might this change trigger in third-party code.

I'll have QuartzCore print out a warning if it detects this bug in -base.

--
Ivan Vucica


-- 
Ivan Vučica - [email protected]
_______________________________________________
Discuss-gnustep mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep

Reply via email to