Added CCNodeLoaderLibrary (more of a factory pattern, compared to adding the CCNodeLoaders directly to the CCBReader. Fixed all TODOs regarding (potential) memory leaks (Thanks to Ricardo Quesada). CCNodeLoaders are now autorelease objects (having a static 'loader()' method to be used).

This commit is contained in:
Nicolas Gramlich 2012-06-05 17:15:28 -07:00
parent c9db868d93
commit bcf53f1453
20 changed files with 235 additions and 99 deletions

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCBFileLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCBFileLoader, loader);
protected:
virtual CCNode * createCCNode(CCNode *, CCBReader *);

View File

@ -1,19 +1,7 @@
#include "CCBReader.h"
#include "CCNodeLoader.h"
#include "CCLayerLoader.h"
#include "CCLayerColorLoader.h"
#include "CCLayerGradientLoader.h"
#include "CCLabelBMFontLoader.h"
#include "CCLabelTTFLoader.h"
#include "CCSpriteLoader.h"
#include "CCScale9SpriteLoader.h"
#include "CCBFileLoader.h"
#include "CCMenuLoader.h"
#include "CCMenuItemLoader.h"
#include "CCMenuItemImageLoader.h"
#include "CCControlButtonLoader.h"
#include "CCParticleSystemQuadLoader.h"
#include "CCNodeLoaderLibrary.h"
#ifdef __CC_PLATFORM_IOS
#import <UIKit/UIDevice.h>
@ -22,56 +10,55 @@
using namespace cocos2d;
using namespace cocos2d::extension;
CCBReader::CCBReader(CCBMemberVariableAssigner * pCCBMemberVariableAssigner, CCBSelectorResolver * pCCBSelectorResolver) {
CCBReader::CCBReader(CCNodeLoaderLibrary * pCCNodeLoaderLibrary, CCBMemberVariableAssigner * pCCBMemberVariableAssigner, CCBSelectorResolver * pCCBSelectorResolver) {
this->mRootNode = NULL;
this->mRootCCBReader = true;
this->mCCNodeLoaderLibrary = pCCNodeLoaderLibrary;
this->mCCBMemberVariableAssigner = pCCBMemberVariableAssigner;
this->mCCBSelectorResolver = pCCBSelectorResolver;
this->mResolutionScale = 1;
#ifdef __CC_PLATFORM_IOS
/* iPad */
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
this->mResolutionScale = 2;
}
#endif
this->registerCCNodeLoader("CCNode", new CCNodeLoader());
this->registerCCNodeLoader("CCLayer", new CCLayerLoader());
this->registerCCNodeLoader("CCLayerColor", new CCLayerColorLoader());
this->registerCCNodeLoader("CCLayerGradient", new CCLayerGradientLoader());
this->registerCCNodeLoader("CCSprite", new CCSpriteLoader());
this->registerCCNodeLoader("CCLabelBMFont", new CCLabelBMFontLoader());
this->registerCCNodeLoader("CCLabelTTF", new CCLabelTTFLoader());
this->registerCCNodeLoader("CCScale9Sprite", new CCScale9SpriteLoader());
this->registerCCNodeLoader("CCBFile", new CCBFileLoader());
this->registerCCNodeLoader("CCMenu", new CCMenuLoader());
this->registerCCNodeLoader("CCMenuItemImage", new CCMenuItemImageLoader());
this->registerCCNodeLoader("CCControlButton", new CCControlButtonLoader());
this->registerCCNodeLoader("CCParticleSystemQuad", new CCParticleSystemQuadLoader());
}
CCBReader::~CCBReader() {
if(this->mBytes) {
if(this->mBytes != NULL) {
delete this->mBytes;
this->mBytes = NULL;
}
// TODO Also delete mCCNodeLoaders, mLoadedSpritesheets, etc... ? (Keep in mind they might be copied/inherited from another CCBReader through the copy constructor!)
/* Clear string cache. */
this->mStringCache.clear();
if(this->mRootCCBReader) {
/* Clear loaded spritesheets. */
this->mLoadedSpriteSheets.clear();
}
if(this->mRootNode != NULL) {
this->mRootNode->release();
}
}
CCBReader::CCBReader(CCBReader * pCCBReader) {
/* Borrow data from the 'parent' CCBLoader. */
this->mRootNode = NULL;
this->mRootCCBReader = false;
/* Borrow data from the 'parent' CCBReader. */
this->mResolutionScale = pCCBReader->mResolutionScale;
this->mLoadedSpriteSheets = pCCBReader->mLoadedSpriteSheets;
this->mCCNodeLoaders = pCCBReader->mCCNodeLoaders;
this->mCCNodeLoaderLibrary = pCCBReader->mCCNodeLoaderLibrary;
this->mCCBMemberVariableAssigner = pCCBReader->mCCBMemberVariableAssigner;
this->mCCBSelectorResolver = pCCBReader->mCCBSelectorResolver;
}
void CCBReader::registerCCNodeLoader(const char * pClassName, CCNodeLoader * pCCNodeLoader) {
this->mCCNodeLoaders.insert(std::pair<const char *, CCNodeLoader *>(pClassName, pCCNodeLoader));
}
CCBMemberVariableAssigner * CCBReader::getCCBMemberVariableAssigner() {
return this->mCCBMemberVariableAssigner;
}
@ -84,19 +71,13 @@ float CCBReader::getResolutionScale() {
return this->mResolutionScale;
}
CCNodeLoader * CCBReader::getCCNodeLoader(const char * pClassName) {
std::map<const char *, CCNodeLoader *>::iterator ccNodeLoadersIterator = this->mCCNodeLoaders.find(pClassName);
assert(ccNodeLoadersIterator != this->mCCNodeLoaders.end());
return ccNodeLoadersIterator->second;
}
CCNode * CCBReader::readNodeGraphFromFile(const char * pCCBFileName, CCObject * pOwner) {
return this->readNodeGraphFromFile(pCCBFileName, pOwner, CCDirector::sharedDirector()->getWinSize());
}
CCNode * CCBReader::readNodeGraphFromFile(const char * pCCBFileName, CCObject * pOwner, CCSize pRootContainerSize) {
const char * path = CCFileUtils::fullPathFromRelativePath(pCCBFileName);
unsigned long size = 0;
this->mBytes = CCFileUtils::getFileData(path, "r", &size);
@ -104,15 +85,15 @@ CCNode * CCBReader::readNodeGraphFromFile(const char * pCCBFileName, CCObject *
this->mCurrentBit = 0;
this->mOwner = pOwner;
this->mRootContainerSize = pRootContainerSize;
if(!this->readHeader()) {
return NULL;
}
if(!this->readStringCache()) {
return NULL;
}
return this->readNodeGraph();
}
@ -157,13 +138,11 @@ void CCBReader::readStringCacheEntry() {
int numBytes = b0 << 8 | b1;
const char * src = (const char *) (this->mBytes + this->mCurrentByte);
char * ptr = new char[numBytes + 1]; // TODO I'm most likely leaking memory here. Unfortunately I'm not sure if I can safely delete the items in the mStringCache in ~CCBReader. =(
strncpy(ptr, src, numBytes);
ptr[numBytes] = '\0';
std::string string(src, numBytes);
this->mCurrentByte += numBytes;
this->mStringCache.push_back(ptr);
this->mStringCache.push_back(string);
}
unsigned char CCBReader::readByte() {
@ -263,7 +242,7 @@ void CCBReader::alignBits() {
const char * CCBReader::readCachedString() {
int i = this->readInt(false);
return this->mStringCache[i];
return this->mStringCache[i].c_str();
}
CCNode * CCBReader::readNodeGraph(CCNode * pParent) {
@ -276,23 +255,24 @@ CCNode * CCBReader::readNodeGraph(CCNode * pParent) {
memberVarAssignmentName = this->readCachedString();
}
CCNodeLoader * ccNodeLoader = this->getCCNodeLoader(className);
CCNodeLoader * ccNodeLoader = this->mCCNodeLoaderLibrary->getCCNodeLoader(className);
CCNode * node = ccNodeLoader->loadCCNode(pParent, this);
/* Set root node, if not set yet. */
if(this->mRootNode == NULL) {
this->mRootNode = node; // TODO retain?
this->mRootNode = node;
this->mRootNode->retain();
}
if(memberVarAssignmentType != kCCBTargetTypeNone) {
CCObject * target = NULL;
if(memberVarAssignmentType == kCCBTargetTypeDocumentRoot) {
target = this->getRootNode();
} else if (memberVarAssignmentType == kCCBTargetTypeOwner) {
target = this->getOwner();
target = this->mRootNode;
} else if(memberVarAssignmentType == kCCBTargetTypeOwner) {
target = this->mOwner;
}
if (target != NULL) {
if(target != NULL) {
if(this->mCCBMemberVariableAssigner != NULL) {
this->mCCBMemberVariableAssigner->onAssignCCBMemberVariable(target, memberVarAssignmentName, node);
}
@ -305,7 +285,7 @@ CCNode * CCBReader::readNodeGraph(CCNode * pParent) {
CCNode * child = this->readNodeGraph(node);
node->addChild(child);
}
// TODO
/*
if([node respondsToSelector:@selector(didLoadFromCCB)]) {
@ -345,37 +325,33 @@ void CCBReader::addLoadedSpriteSheet(const char * pSpriteSheet) {
}
const char * CCBReader::lastPathComponent(const char * pPath) {
// TODO Memory leaks?
std::string path(pPath);
int slashPos = path.find_last_of("/");
if (slashPos != std::string::npos) {
if(slashPos != std::string::npos) {
return path.substr(slashPos + 1, path.length() - slashPos).c_str();
}
return pPath;
}
const char * CCBReader::deletePathExtension(const char * pPath) {
// TODO Memory leaks?
std::string path(pPath);
int dotPos = path.find_last_of(".");
if (dotPos != std::string::npos) {
if(dotPos != std::string::npos) {
return path.substr(0, dotPos).c_str();
}
return pPath;
}
const char * CCBReader::toLowerCase(const char * pString) {
// TODO Memory leaks?
std::string copy(pString);
std::transform(copy.begin(), copy.end(), copy.begin(), ::tolower);
return copy.c_str();
}
bool CCBReader::endsWith(const char * pString, const char * pEnding) {
// TODO Memory leaks?
std::string string(pString);
std::string ending(pEnding);
if (string.length() >= ending.length()) {
if(string.length() >= ending.length()) {
return (string.compare(string.length() - ending.length(), ending.length(), ending) == 0);
} else {
return false;

View File

@ -5,6 +5,12 @@
#include "CCBMemberVariableAssigner.h"
#include "CCBSelectorResolver.h"
#define STATIC_NEW_AUTORELEASE_OBJECT_METHOD(T, METHOD) static T * METHOD() { \
T * t = new T(); \
t->autorelease(); \
return t; \
}
#define kCCBVersion 2
#define kCCBPropTypePosition 0
@ -68,20 +74,17 @@
NS_CC_EXT_BEGIN
struct cmp_str {
bool operator() (char const *a, char const *b) {
return std::strcmp(a, b) < 0;
}
};
/* Forward declaration. */
class CCNodeLoader;
class CCNodeLoaderLibrary;
/**
* @brief Parse CCBI file which is generated by CocosBuilder
*/
class CC_DLL CCBReader : public CCObject { // TODO Why extend CCObject? -> Also all Loaders should extend from CCObject?
private:
class CC_DLL CCBReader : public CCObject {
private:
bool mRootCCBReader;
unsigned char * mBytes;
int mCurrentByte;
int mCurrentBit;
@ -90,24 +93,22 @@ class CC_DLL CCBReader : public CCObject { // TODO Why extend CCObject? -> Also
CCSize mRootContainerSize;
float mResolutionScale;
CCNodeLoaderLibrary * mCCNodeLoaderLibrary;
CCBMemberVariableAssigner * mCCBMemberVariableAssigner;
CCBSelectorResolver * mCCBSelectorResolver;
std::vector<const char *> mStringCache;
std::map<const char *, CCNodeLoader *, cmp_str> mCCNodeLoaders;
std::set<const char *, cmp_str> mLoadedSpriteSheets;
std::vector<std::string> mStringCache;
std::set<std::string> mLoadedSpriteSheets;
public:
public:
/* Constructor. */
CCBReader(CCBMemberVariableAssigner * = NULL, CCBSelectorResolver * = NULL);
CCBReader(CCNodeLoaderLibrary *, CCBMemberVariableAssigner * = NULL, CCBSelectorResolver * = NULL);
CCBReader(CCBReader *);
/* Destructor. */
~CCBReader();
CCNode * readNodeGraphFromFile(const char * pCCBFileName, CCObject * pOwner = NULL);
CCNode * readNodeGraphFromFile(const char * pCCBFileName, CCObject * pOwner, CCSize pRootContainerSize);
void registerCCNodeLoader(const char * pClassName, CCNodeLoader * pCCNodeLoader);
CCNodeLoader * getCCNodeLoader(const char * pClassName);
CCBMemberVariableAssigner * getCCBMemberVariableAssigner();
CCBSelectorResolver * getCCBSelectorResolver();
@ -118,7 +119,7 @@ class CC_DLL CCBReader : public CCObject { // TODO Why extend CCObject? -> Also
bool isSpriteSheetLoaded(const char *);
void addLoadedSpriteSheet(const char *);
/* Utility methods. */
const char * lastPathComponent(const char *);
const char * deletePathExtension(const char *);
@ -131,14 +132,14 @@ class CC_DLL CCBReader : public CCObject { // TODO Why extend CCObject? -> Also
bool readBool();
float readFloat();
const char * readCachedString();
private:
bool readHeader();
bool readStringCache();
void readStringCacheEntry();
CCNode * readNodeGraph();
CCNode * readNodeGraph(CCNode *);
bool getBit();
void alignBits();
const char * readUTF8();

View File

@ -36,11 +36,17 @@ void CCControlButtonLoader::onHandlePropTypeCheck(CCNode * pNode, CCNode * pPare
void CCControlButtonLoader::onHandlePropTypeString(CCNode * pNode, CCNode * pParent, const char * pPropertyName, const char * pString, CCBReader * pCCBReader) {
if(strcmp(pPropertyName, PROPERTY_TITLE_NORMAL) == 0) {
((CCControlButton *)pNode)->setTitleForState(new CCString(pString), CCControlStateNormal); // TODO Leak?
CCString * ccString = new CCString(pString);
ccString->autorelease();
((CCControlButton *)pNode)->setTitleForState(ccString, CCControlStateNormal);
} else if(strcmp(pPropertyName, PROPERTY_TITLE_HIGHLIGHTED) == 0) {
((CCControlButton *)pNode)->setTitleForState(new CCString(pString), CCControlStateHighlighted); // TODO Leak?
CCString * ccString = new CCString(pString);
ccString->autorelease();
((CCControlButton *)pNode)->setTitleForState(ccString, CCControlStateHighlighted);
} else if(strcmp(pPropertyName, PROPERTY_TITLE_DISABLED) == 0) {
((CCControlButton *)pNode)->setTitleForState(new CCString(pString), CCControlStateDisabled); // TODO Leak?
CCString * ccString = new CCString(pString);
ccString->autorelease();
((CCControlButton *)pNode)->setTitleForState(ccString, CCControlStateDisabled);
} else {
CCControlLoader::onHandlePropTypeString(pNode, pParent, pPropertyName, pString, pCCBReader);
}

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCControlButtonLoader : public CCControlLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCControlButtonLoader, loader);
protected:
virtual CCControl * createCCNode(CCNode *, CCBReader *);

View File

@ -19,8 +19,7 @@ void CCControlLoader::onHandlePropTypeCheck(CCNode * pNode, CCNode * pParent, co
void CCControlLoader::onHandlePropTypeBlockCCControl(CCNode * pNode, CCNode * pParent, const char * pPropertyName, BlockCCControlData * pBlockCCControlData, CCBReader * pCCBReader) {
if(strcmp(pPropertyName, PROPERTY_CCCONTROL) == 0) {
// TODO selector thingy...
((CCControl *)pNode)->addTargetWithActionForControlEvents(pBlockCCControlData->mTarget, pBlockCCControlData->mSELMenuHandler, pBlockCCControlData->mControlEvents); // TODO First paramater is wrong!
((CCControl *)pNode)->addTargetWithActionForControlEvents(pBlockCCControlData->mTarget, pBlockCCControlData->mSELMenuHandler, pBlockCCControlData->mControlEvents);
} else {
CCNodeLoader::onHandlePropTypeBlockCCControl(pNode, pParent, pPropertyName, pBlockCCControlData, pCCBReader);
}

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCLabelBMFontLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCLabelBMFontLoader, loader);
protected:
virtual CCLabelBMFont * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCLabelTTFLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCLabelTTFLoader, loader);
protected:
virtual CCLabelTTF * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,8 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCLayerColorLoader : public CCLayerLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCLayerColorLoader, loader);
protected:
virtual CCLayerColor * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCLayerGradientLoader : public CCLayerLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCLayerGradientLoader, loader);
protected:
virtual CCLayerGradient * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCLayerLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCLayerLoader, loader);
protected:
virtual CCLayer * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCMenuItemImageLoader : public CCMenuItemLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCMenuItemImageLoader, loader);
protected:
virtual CCMenuItemImage * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCMenuLoader : public CCLayerLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCMenuLoader, loader);
protected:
virtual CCMenu * createCCNode(CCNode *, CCBReader *);
};

View File

@ -84,7 +84,7 @@ void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader *
if(setProp) {
this->onHandlePropTypeScaleLock(pNode, pParent, propertyName, scaleLock, pCCBReader);
}
delete scaleLock; // TODO Can this just be deleted?
delete scaleLock;
break;
}
case kCCBPropTypeFloat: {
@ -127,7 +127,7 @@ void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader *
if(setProp) {
this->onHandlePropTypeFloatVar(pNode, pParent, propertyName, floatVar, pCCBReader);
}
delete floatVar; // TODO Can this just be deleted?
delete floatVar;
break;
}
case kCCBPropTypeCheck: {
@ -142,7 +142,6 @@ void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader *
if(setProp) {
this->onHandlePropTypeSpriteFrame(pNode, pParent, propertyName, ccSpriteFrame, pCCBReader);
}
// TODO delete ccSpriteFrame; ???
break;
}
case kCCBPropTypeAnimation: {
@ -150,7 +149,6 @@ void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader *
if(setProp) {
this->onHandlePropTypeAnimation(pNode, pParent, propertyName, ccAnimation, pCCBReader);
}
// TODO delete ccAnimation; ???
break;
}
case kCCBPropTypeTexture: {
@ -158,7 +156,6 @@ void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader *
if(setProp) {
this->onHandlePropTypeTexture(pNode, pParent, propertyName, ccTexture2D, pCCBReader);
}
// TODO delete ccTexture2D; ???
break;
}
case kCCBPropTypeByte: {
@ -180,7 +177,7 @@ void CCNodeLoader::parseProperties(CCNode * pNode, CCNode * pParent, CCBReader *
if(setProp) {
this->onHandlePropTypeColor4FVar(pNode, pParent, propertyName, color4FVar, pCCBReader);
}
delete color4FVar; // TODO Can this just be deleted?
delete color4FVar;
break;
}
case kCCBPropTypeFlip: {
@ -624,17 +621,16 @@ CCNode * CCNodeLoader::parsePropTypeCCBFile(CCNode * pNode, CCNode * pParent, CC
/* Change path extension to .ccbi. */
const char * ccbFileWithoutPathExtension = pCCBReader->deletePathExtension(ccbFileName);
int ccbiFileNameLenght = strlen(ccbFileWithoutPathExtension) + strlen(".ccbi");
char * ccbiFileName = new char[ccbiFileNameLenght + 1]; // TODO Memory leak?
char ccbiFileName[ccbiFileNameLenght + 1];
strcpy(ccbiFileName, ccbFileWithoutPathExtension);
strcat(ccbiFileName, ".ccbi");
ccbiFileName[ccbiFileNameLenght] = '\0';
CCBReader * ccbReader = new CCBReader(pCCBReader);
ccbReader->autorelease();
CCNode * ccbFileNode = ccbReader->readNodeGraphFromFile(ccbiFileName, pCCBReader->getOwner(), pParent->getContentSize());
delete ccbReader;
return ccbFileNode;
}

View File

@ -20,8 +20,10 @@ struct BlockCCControlData {
/* Forward declaration. */
class CCBReader;
class CC_DLL CCNodeLoader {
class CC_DLL CCNodeLoader : public CCObject {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCNodeLoader, loader);
virtual CCNode * loadCCNode(CCNode *, CCBReader *);
virtual void parseProperties(CCNode *, CCNode *, CCBReader *);

View File

@ -0,0 +1,89 @@
#include "CCNodeLoaderLibrary.h"
#include "CCLayerLoader.h"
#include "CCLayerColorLoader.h"
#include "CCLayerGradientLoader.h"
#include "CCLabelBMFontLoader.h"
#include "CCLabelTTFLoader.h"
#include "CCSpriteLoader.h"
#include "CCScale9SpriteLoader.h"
#include "CCBFileLoader.h"
#include "CCMenuLoader.h"
#include "CCMenuItemLoader.h"
#include "CCMenuItemImageLoader.h"
#include "CCControlButtonLoader.h"
#include "CCParticleSystemQuadLoader.h"
using namespace cocos2d;
using namespace cocos2d::extension;
CCNodeLoaderLibrary::CCNodeLoaderLibrary() {
}
CCNodeLoaderLibrary::~CCNodeLoaderLibrary() {
this->purge(true);
}
void CCNodeLoaderLibrary::registerDefaultCCNodeLoaders() {
this->registerCCNodeLoader("CCNode", CCNodeLoader::loader());
this->registerCCNodeLoader("CCLayer", CCLayerLoader::loader());
this->registerCCNodeLoader("CCLayerColor", CCLayerColorLoader::loader());
this->registerCCNodeLoader("CCLayerGradient", CCLayerGradientLoader::loader());
this->registerCCNodeLoader("CCSprite", CCSpriteLoader::loader());
this->registerCCNodeLoader("CCLabelBMFont", CCLabelBMFontLoader::loader());
this->registerCCNodeLoader("CCLabelTTF", CCLabelTTFLoader::loader());
this->registerCCNodeLoader("CCScale9Sprite", CCScale9SpriteLoader::loader());
this->registerCCNodeLoader("CCBFile", CCBFileLoader::loader());
this->registerCCNodeLoader("CCMenu", CCMenuLoader::loader());
this->registerCCNodeLoader("CCMenuItemImage", CCMenuItemImageLoader::loader());
this->registerCCNodeLoader("CCControlButton", CCControlButtonLoader::loader());
this->registerCCNodeLoader("CCParticleSystemQuad", CCParticleSystemQuadLoader::loader());
}
void CCNodeLoaderLibrary::registerCCNodeLoader(const char * pClassName, CCNodeLoader * pCCNodeLoader) {
this->mCCNodeLoaders.insert(std::pair<const char *, CCNodeLoader *>(pClassName, pCCNodeLoader));
pCCNodeLoader->retain();
}
void CCNodeLoaderLibrary::unregisterCCNodeLoader(const char * pClassName) {
std::map<std::string, CCNodeLoader *>::iterator ccNodeLoadersIterator = this->mCCNodeLoaders.find(pClassName);
assert(ccNodeLoadersIterator != this->mCCNodeLoaders.end());
ccNodeLoadersIterator->second->release();
}
CCNodeLoader * CCNodeLoaderLibrary::getCCNodeLoader(const char * pClassName) {
std::map<std::string, CCNodeLoader *>::iterator ccNodeLoadersIterator = this->mCCNodeLoaders.find(pClassName);
assert(ccNodeLoadersIterator != this->mCCNodeLoaders.end());
return ccNodeLoadersIterator->second;
}
void CCNodeLoaderLibrary::purge(bool pDelete) {
if(pDelete) {
for(std::map<std::string, CCNodeLoader *>::iterator it = this->mCCNodeLoaders.begin(); it != this->mCCNodeLoaders.end(); it++) {
it->second->release();
}
}
this->mCCNodeLoaders.clear();
}
static CCNodeLoaderLibrary * sSharedCCNodeLoaderLibrary = NULL;
CCNodeLoaderLibrary * CCNodeLoaderLibrary::sharedCCNodeLoaderLibrary() {
if(sSharedCCNodeLoaderLibrary == NULL) {
sSharedCCNodeLoaderLibrary = new CCNodeLoaderLibrary();
sSharedCCNodeLoaderLibrary->registerDefaultCCNodeLoaders();
}
return sSharedCCNodeLoaderLibrary;
}
CCNodeLoaderLibrary * CCNodeLoaderLibrary::newDefaultCCNodeLoaderLibrary() {
CCNodeLoaderLibrary * ccNodeLoaderLibrary = CCNodeLoaderLibrary::library();
ccNodeLoaderLibrary->registerDefaultCCNodeLoaders();
return ccNodeLoaderLibrary;
}

View File

@ -0,0 +1,32 @@
#ifndef _CCNODE_LOADER_LIBRARY_H_
#define _CCNODE_LOADER_LIBRARY_H_
#include "cocos2d.h"
#include "CCBReader.h"
NS_CC_EXT_BEGIN
class CC_DLL CCNodeLoaderLibrary : public CCObject {
private:
std::map<std::string, CCNodeLoader *> mCCNodeLoaders;
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCNodeLoaderLibrary, library);
CCNodeLoaderLibrary();
~CCNodeLoaderLibrary();
void registerDefaultCCNodeLoaders();
void registerCCNodeLoader(const char * pClassName, CCNodeLoader * pCCNodeLoader);
void unregisterCCNodeLoader(const char * pClassName);
CCNodeLoader * getCCNodeLoader(const char * pClassName);
void purge(bool pDelete);
public:
static CCNodeLoaderLibrary * sharedCCNodeLoaderLibrary();
static CCNodeLoaderLibrary * newDefaultCCNodeLoaderLibrary();
};
NS_CC_EXT_END
#endif

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCParticleSystemQuadLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCParticleSystemQuadLoader, loader);
protected:
virtual CCParticleSystemQuad * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCScale9SpriteLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCScale9SpriteLoader, loader);
protected:
virtual CCScale9Sprite * createCCNode(CCNode *, CCBReader *);

View File

@ -9,6 +9,9 @@ NS_CC_EXT_BEGIN
class CCBReader;
class CCSpriteLoader : public CCNodeLoader {
public:
STATIC_NEW_AUTORELEASE_OBJECT_METHOD(CCSpriteLoader, loader);
protected:
virtual CCSprite * createCCNode(CCNode *, CCBReader *);