Hello everyone.
Today I’m bringing you a function that I think can be integrated inside cocos2d-x because it’s a very important one.
If you are an objective c programmer, it’s almost impossible that you have never printed an object with NSLog. Well, after that cool experience with “@" and the “description” method it’s hard to debug in c++, because every time you have to print a CCArray or a CCDictionary you have to iterate. Even if you have written code snippets to accelerate that process, that’s never gonna be equal or better than the cool “`” flag in objective c. I miss NSLog so much!!!
That’s why I think that our CCLog method must be changed. I wrote a method that replaces any "%`” inside the log with the string returned from a “description” method that every subclass of CCObject must have. So basically to resume what has to be changed inside cocos2d-x is:
- Modify CCLog method to call my method instead of vsnprintf.
- Create a virtual description method inside CCObject that must return a string.
- Inside all important classes like CCArray and CCDictionary write a better implementation of the description method.
There are several classes inside cocos2d-x (ex. CCNode) that already have a description method, I’m wondering if actually we have to call them ourselves or they get called somewhere that I don’t know?
Anyway, I hope that somebody of the cocos2d-x team will take this method in consideration, you can change it or create another better one, but please do something like this because it’s a very useful technique to log objects!
This is the public method that CCObject must contain:
virtual const char * description();
This is my method:
#include "CCObject.h"
void ccprintf(char * buffer, const char * format, va_list &args)
{
char szBuf[kMaxLogLen+1] = {0};
int len = strlen(format)-1;
int counter = 0;
int j=0, i=0;
for (; i0) va_arg(args,int);
j=0;
//get object (argument)
CCObject * ptr = va_arg(args,CCObject*);
//get description of object and add it to buffer
const char * desc = ptr->description();
strcpy(&buffer[j],desc);
j+=strlen(desc);
i++;
continue;
}
else if (format[i+1]!='%') { //skip argument
counter++;
}
else { //next symbol is %, skip it
i++;
}
}
buffer[j++] = format[i];
}
buffer[j++] = format[i];
buffer[j] = '\0';
vsnprintf(szBuf, kMaxLogLen, buffer, args);
printf("%s",szBuf);
}
This is the modified CCLog:
void CCLog(const char * pszFormat, ...)
{
printf("Cocos2d: ");
char szBuf[kMaxLogLen];
va_list ap;
va_start(ap, pszFormat);
//vsnprintf(szBuf, kMaxLogLen, pszFormat, ap);
ccprintf(szBuf, pszFormat, ap);
va_end(ap);
//printf("%s", szBuf);
printf("\n");
}
And this is how you use it:
CCSprite * sprite = CCSprite::create("hello.png");
CCLog("%@",sprite);
Cool right?
I havent’s tested so much, so if you find bugs, please let me know!
Regards,
Artavazd