Skip to content

Commit 64c0b9e

Browse files
committed
Assert messages improved.
Added some special case error hint messages to help locate the cause for an assert.
1 parent 7625920 commit 64c0b9e

File tree

1 file changed

+101
-6
lines changed

1 file changed

+101
-6
lines changed

cocos2d-ui/CCBReader/CCBReader.m

Lines changed: 101 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ @interface CCBFile : CCNode
4646
@end
4747

4848

49+
@interface CCBReader()
50+
51+
@property (nonatomic, copy) NSString *currentCCBFile;
52+
53+
@end
54+
4955

5056
@implementation CCBReader
5157

@@ -308,6 +314,15 @@ - (void) readPropertyForNode:(CCNode*) node parent:(CCNode*)parent isExtraProp:(
308314

309315
[extraPropNames addObject:name];
310316
}
317+
318+
#if DEBUG
319+
if (isExtraProp
320+
&& ![self isPropertyKeySettable:name onInstance:node])
321+
{
322+
NSLog(@"*** [PROPERTY] ERROR HINT: Did you set a custom property \"%@\"? In file \"%@\" ", name, _currentCCBFile);
323+
NSLog(@"*** [PROPERTY] ERROR HINT: Make sure the class \"%@\" is KVC compliant and \"%@\" can be set", [node class], name);
324+
}
325+
#endif
311326

312327
if (type == kCCBPropTypePosition)
313328
{
@@ -676,7 +691,16 @@ - (void) readPropertyForNode:(CCNode*) node parent:(CCNode*)parent isExtraProp:(
676691
NSString* path = [[CCFileUtils sharedFileUtils] fullPathForFilename:ccbFileName];
677692
NSData* d = [NSData dataWithContentsOfFile:path];
678693

679-
NSAssert(d,@"Failed to find ccb file: %@",ccbFileName);
694+
#if DEBUG
695+
// Special case: scroll view missing content node
696+
if (!d && [ccbFileName isEqualToString:@".ccbi"] && [NSStringFromClass([node class]) isEqualToString:@"CCScrollView"])
697+
{
698+
NSLog(@"*** [PROPERTY] ERROR HINT: Did you forget to set the content node for your CCScrollView?");
699+
}
700+
#endif
701+
702+
NSAssert(d,@"[PROPERTY] %@ - kCCBPropTypeCCBFile - Failed to find ccb file: \"%@\", node class name: \"%@\", name: \"%@\", in ccb file: \"%@\"",
703+
name, ccbFileName, [node class], [node name], _currentCCBFile);
680704

681705
CCBReader* reader = [[CCBReader alloc] init];
682706
reader.animationManager.rootContainerSize = parent.contentSize;
@@ -706,8 +730,74 @@ - (void) readPropertyForNode:(CCNode*) node parent:(CCNode*)parent isExtraProp:(
706730
}
707731
else
708732
{
709-
NSLog(@"CCBReader: Failed to read property type %d",type);
733+
NSAssert(false, @"[PROPERTY] %@ - Failed to read property type %d, node class name: \"%@\", name: \"%@\", in ccb file: \"%@\"",
734+
name, type, [node class], [node name], _currentCCBFile);
735+
}
736+
}
737+
738+
- (BOOL)isPropertyKeySettable:(NSString *)key onInstance:(id)instance
739+
{
740+
if (!key || !instance || ([key length] == 0))
741+
{
742+
return NO;
710743
}
744+
745+
NSString *firstCharacterOfKey = [[key substringWithRange:NSMakeRange(0, 1)] uppercaseString];
746+
NSString *uppercaseKey = [key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:firstCharacterOfKey];
747+
NSString *setterName = [NSString stringWithFormat:@"set%@", uppercaseKey];
748+
749+
if ([instance respondsToSelector:NSSelectorFromString(setterName)])
750+
{
751+
return YES;
752+
}
753+
754+
NSArray *setOfDirectlySettableIvarNames = @[[NSString stringWithFormat:@"_%@", key],
755+
[NSString stringWithFormat:@"_is%@", uppercaseKey],
756+
key,
757+
[NSString stringWithFormat:@"is%@", uppercaseKey]];
758+
759+
return [self doesIvarNameExistInClassHierarchy:[instance class] searchForIvarNames:setOfDirectlySettableIvarNames];
760+
}
761+
762+
- (BOOL)doesIvarNameExistInClassHierarchy:(Class)class searchForIvarNames:(NSArray *)searchedIvarNames
763+
{
764+
if ([class accessInstanceVariablesDirectly])
765+
{
766+
NSArray *ivarNames = [self getIvarNamesOfClass:class];
767+
768+
for (NSString *ivarName in ivarNames)
769+
{
770+
if ([searchedIvarNames containsObject:ivarName])
771+
{
772+
return YES;
773+
}
774+
}
775+
}
776+
777+
Class superClass = class_getSuperclass(class);
778+
if (superClass)
779+
{
780+
return [self doesIvarNameExistInClassHierarchy:superClass searchForIvarNames:searchedIvarNames];
781+
}
782+
783+
return NO;
784+
}
785+
786+
- (NSArray *)getIvarNamesOfClass:(Class)class
787+
{
788+
NSMutableArray *result = [NSMutableArray array];
789+
unsigned int iVarCount;
790+
791+
Ivar *vars = class_copyIvarList(class, &iVarCount);
792+
for (int i = 0; i < iVarCount; i++)
793+
{
794+
Ivar var = vars[i];
795+
NSString *ivarName = [NSString stringWithCString:ivar_getName(var) encoding:NSUTF8StringEncoding];
796+
[result addObject:ivarName];
797+
}
798+
free(vars);
799+
800+
return result;
711801
}
712802

713803
- (CCBKeyframe*) readKeyframeOfType:(int)type
@@ -798,7 +888,10 @@ - (CCNode*) readNodeGraphParent:(CCNode*)parent
798888
Class class = NSClassFromString(className);
799889
if (!class)
800890
{
801-
NSAssert(false,@"CCBReader: Could not create class of type %@",className);
891+
#if DEBUG
892+
NSLog(@"*** [CLASS] ERROR HINT: Did you set a custom class for a CCNode? Please check if the specified class name is spelled correctly and available in your project.");
893+
#endif
894+
NSAssert(nil, @"[CLASS] Could not create class named: \"%@\". in CCB file: \"%@\"", className, _currentCCBFile);
802895
return NULL;
803896
}
804897
CCNode* node = [[class alloc] init];
@@ -937,8 +1030,8 @@ - (CCNode*) readNodeGraphParent:(CCNode*)parent
9371030
if (numPoints > 0)
9381031
body = [CCPhysicsBody bodyWithCircleOfRadius:cornerRadius andCenter:points[0]];
9391032
}
940-
NSAssert(body, @"Unknown body shape");
941-
1033+
NSAssert(body, @"[PHYSICS] Unknown body shape %i, class name \"%@\", in CCB file: \"%@\"", bodyShape, className, _currentCCBFile);
1034+
9421035
BOOL dynamic = readBool(self);
9431036
BOOL affectedByGravity = readBool(self);
9441037
BOOL allowsRotation = readBool(self);
@@ -1190,7 +1283,9 @@ - (CCNode*) nodeGraphFromFile:(NSString*) file owner:(id)o parentSize:(CGSize)pa
11901283

11911284
NSString* path = [[CCFileUtils sharedFileUtils] fullPathForFilename:file];
11921285
NSData* d = [NSData dataWithContentsOfFile:path];
1193-
1286+
1287+
self.currentCCBFile = file;
1288+
11941289
return [self loadWithData:d owner:(id)o];
11951290
}
11961291

0 commit comments

Comments
 (0)