Performance improvements in FileUtils / TextureCache

Added common "apple" platform to avoid duplicate files in FileUtils and other common files
Improves performance in fetching files.
This commit is contained in:
Ricardo Quesada 2013-09-06 15:33:28 -07:00
parent 76a1b36191
commit b78382d5e5
16 changed files with 90 additions and 582 deletions

View File

@ -1 +1 @@
fd0dee451420604712c1327679395cd1faca91b6 0bd142a09d7aacd3dbff8f23c7a14966430e9c01

View File

@ -861,7 +861,7 @@ void Director::createStatsLabel()
CC_SAFE_RELEASE_NULL(_FPSLabel); CC_SAFE_RELEASE_NULL(_FPSLabel);
CC_SAFE_RELEASE_NULL(_SPFLabel); CC_SAFE_RELEASE_NULL(_SPFLabel);
CC_SAFE_RELEASE_NULL(_drawsLabel); CC_SAFE_RELEASE_NULL(_drawsLabel);
textureCache->removeTextureForKey("cc_fps_images"); textureCache->removeTextureForKey("/cc_fps_images");
FileUtils::getInstance()->purgeCachedEntries(); FileUtils::getInstance()->purgeCachedEntries();
} }
@ -878,7 +878,7 @@ void Director::createStatsLabel()
return; return;
} }
texture = textureCache->addUIImage(image, "cc_fps_images"); texture = textureCache->addImage(image, "/cc_fps_images");
CC_SAFE_RELEASE(image); CC_SAFE_RELEASE(image);
/* /*

View File

@ -449,7 +449,7 @@ static tinyxml2::XMLElement* generateElementForArray(cocos2d::Array *array, tiny
#else #else
NS_CC_BEGIN NS_CC_BEGIN
/* The subclass FileUtilsIOS and FileUtilsMac should override these two method. */ /* The subclass FileUtilsApple should override these two method. */
Dictionary* FileUtils::createDictionaryWithContentsOfFile(const std::string& filename) {return NULL;} Dictionary* FileUtils::createDictionaryWithContentsOfFile(const std::string& filename) {return NULL;}
bool FileUtils::writeToFile(cocos2d::Dictionary *dict, const std::string &fullPath) {return NULL;} bool FileUtils::writeToFile(cocos2d::Dictionary *dict, const std::string &fullPath) {return NULL;}
Array* FileUtils::createArrayWithContentsOfFile(const std::string& filename) {return NULL;} Array* FileUtils::createArrayWithContentsOfFile(const std::string& filename) {return NULL;}
@ -459,23 +459,12 @@ Array* FileUtils::createArrayWithContentsOfFile(const std::string& filename) {re
FileUtils* FileUtils::s_sharedFileUtils = NULL; FileUtils* FileUtils::s_sharedFileUtils = NULL;
// XXX: deprecated
FileUtils* FileUtils::sharedFileUtils()
{
return FileUtils::getInstance();
}
void FileUtils::destroyInstance() void FileUtils::destroyInstance()
{ {
CC_SAFE_DELETE(s_sharedFileUtils); CC_SAFE_DELETE(s_sharedFileUtils);
} }
// XXX: deprecated
void FileUtils::purgeFileUtils()
{
FileUtils::destroyInstance();
}
FileUtils::FileUtils() FileUtils::FileUtils()
: _filenameLookupDict(NULL) : _filenameLookupDict(NULL)
{ {
@ -572,17 +561,17 @@ unsigned char* FileUtils::getFileDataFromZip(const char* pszZipFilePath, const c
std::string FileUtils::getNewFilename(const char* filename) std::string FileUtils::getNewFilename(const char* filename)
{ {
const char* pszNewFileName = NULL; const char* newFileName = NULL;
// in Lookup Filename dictionary ? // in Lookup Filename dictionary ?
String* fileNameFound = _filenameLookupDict ? (String*)_filenameLookupDict->objectForKey(filename) : NULL; String* fileNameFound = _filenameLookupDict ? (String*)_filenameLookupDict->objectForKey(filename) : NULL;
if( NULL == fileNameFound || fileNameFound->length() == 0) { if( NULL == fileNameFound || fileNameFound->length() == 0) {
pszNewFileName = filename; newFileName = filename;
} }
else { else {
pszNewFileName = fileNameFound->getCString(); newFileName = fileNameFound->getCString();
//CCLOG("FOUND NEW FILE NAME: %s.", pszNewFileName);
} }
return pszNewFileName; return newFileName;
} }
std::string FileUtils::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) std::string FileUtils::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath)
@ -615,15 +604,13 @@ std::string FileUtils::fullPathForFilename(const char* filename)
std::string strFileName = filename; std::string strFileName = filename;
if (isAbsolutePath(filename)) if (isAbsolutePath(filename))
{ {
//CCLOG("Return absolute path( %s ) directly.", filename);
return filename; return filename;
} }
// Already Cached ? // Already Cached ?
std::map<std::string, std::string>::iterator cacheIter = _fullPathCache.find(filename); auto cacheIter = _fullPathCache.find(filename);
if (cacheIter != _fullPathCache.end()) if (cacheIter != _fullPathCache.end())
{ {
//CCLOG("Return full path from cache: %s", cacheIter->second.c_str());
return cacheIter->second; return cacheIter->second;
} }
@ -632,27 +619,23 @@ std::string FileUtils::fullPathForFilename(const char* filename)
string fullpath = ""; string fullpath = "";
for (auto searchPathsIter = _searchPathArray.begin(); for (auto searchIt = _searchPathArray.begin(); searchIt != _searchPathArray.end(); ++searchIt) {
searchPathsIter != _searchPathArray.end(); ++searchPathsIter) { for (auto resolutionIt = _searchResolutionsOrderArray.begin(); resolutionIt != _searchResolutionsOrderArray.end(); ++resolutionIt) {
for (auto resOrderIter = _searchResolutionsOrderArray.begin();
resOrderIter != _searchResolutionsOrderArray.end(); ++resOrderIter) {
// CCLOG("SEARCHING: %s\n", std::string(*searchPathsIter + *resOrderIter + newFilename).c_str() ); fullpath = this->getPathForFilename(newFilename, *resolutionIt, *searchIt);
fullpath = this->getPathForFilename(newFilename, *resOrderIter, *searchPathsIter);
if (fullpath.length() > 0) if (fullpath.length() > 0)
{ {
// Using the filename passed in as key. // Using the filename passed in as key.
_fullPathCache.insert(std::pair<std::string, std::string>(filename, fullpath)); _fullPathCache.insert(std::pair<std::string, std::string>(filename, fullpath));
// CCLOG("Returning path: %s\n", fullpath.c_str());
return fullpath; return fullpath;
} }
} }
} }
// CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", filename); CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", filename);
// XXX: Should it return nullptr ? or an empty string ?
// The file wasn't found, return the file name passed in. // The file wasn't found, return the file name passed in.
return filename; return filename;
} }

View File

@ -57,10 +57,10 @@ public:
static void destroyInstance(); static void destroyInstance();
/** @deprecated Use getInstance() instead */ /** @deprecated Use getInstance() instead */
CC_DEPRECATED_ATTRIBUTE static FileUtils* sharedFileUtils(); CC_DEPRECATED_ATTRIBUTE static FileUtils* sharedFileUtils() { return getInstance(); }
/** @deprecated Use destroyInstance() instead */ /** @deprecated Use destroyInstance() instead */
CC_DEPRECATED_ATTRIBUTE static void purgeFileUtils(); CC_DEPRECATED_ATTRIBUTE static void purgeFileUtils() { destroyInstance(); }
/** /**
* The destructor of FileUtils. * The destructor of FileUtils.
@ -308,6 +308,7 @@ protected:
/** /**
* Gets the new filename from the filename lookup dictionary. * Gets the new filename from the filename lookup dictionary.
* It is possible to have a override names.
* @param filename The original filename. * @param filename The original filename.
* @return The new filename after searching in the filename lookup dictionary. * @return The new filename after searching in the filename lookup dictionary.
* If the original filename wasn't in the dictionary, it will return the original filename. * If the original filename wasn't in the dictionary, it will return the original filename.

View File

@ -21,8 +21,8 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#ifndef __CC_FILEUTILSMAC_H__ #ifndef __CC_FILEUTILS_APPLE_H__
#define __CC_FILEUTILSMAC_H__ #define __CC_FILEUTILS_APPLE_H__
#include "CCFileUtils.h" #include "CCFileUtils.h"
#include <string> #include <string>
@ -31,26 +31,25 @@
#include "ccTypes.h" #include "ccTypes.h"
NS_CC_BEGIN NS_CC_BEGIN
/** /**
* @addtogroup platform * @addtogroup platform
* @{ * @{
*/ */
//! @brief Helper class to handle file operations //! @brief Helper class to handle file operations
class CC_DLL FileUtilsMac : public FileUtils class CC_DLL FileUtilsApple : public FileUtils
{ {
public: public:
/* override funtions */ /* override funtions */
virtual std::string getWritablePath(); virtual std::string getWritablePath();
virtual bool isFileExist(const std::string& strFilePath); virtual bool isFileExist(const std::string& strFilePath);
virtual bool isAbsolutePath(const std::string& strPath);
virtual std::string getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename); virtual std::string getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename);
virtual Dictionary* createDictionaryWithContentsOfFile(const std::string& filename); virtual Dictionary* createDictionaryWithContentsOfFile(const std::string& filename);
virtual bool writeToFile(Dictionary *dict, const std::string& fullPath); virtual bool writeToFile(Dictionary *dict, const std::string& fullPath);
virtual Array* createArrayWithContentsOfFile(const std::string& filename); virtual Array* createArrayWithContentsOfFile(const std::string& filename);
}; };
// end of platform group // end of platform group
@ -58,5 +57,5 @@ public:
NS_CC_END NS_CC_END
#endif // __CC_FILEUTILSMAC_H__ #endif // __CC_FILEUTILS_APPLE_H__

View File

@ -23,7 +23,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <UIKit/UIDevice.h>
#include <string> #include <string>
#include <stack> #include <stack>
@ -34,7 +33,7 @@ THE SOFTWARE.
#include "CCDictionary.h" #include "CCDictionary.h"
#include "support/zip_support/unzip.h" #include "support/zip_support/unzip.h"
#include "CCFileUtilsIOS.h" #include "CCFileUtilsApple.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -210,25 +209,28 @@ static void addObjectToNSDict(const char * key, Object* object, NSMutableDiction
} }
} }
#pragma mark - FileUtils
static NSFileManager* s_fileManager = [NSFileManager defaultManager];
FileUtils* FileUtils::getInstance() FileUtils* FileUtils::getInstance()
{ {
if (s_sharedFileUtils == NULL) if (s_sharedFileUtils == NULL)
{ {
s_sharedFileUtils = new FileUtilsIOS(); s_sharedFileUtils = new FileUtilsApple();
if(!s_sharedFileUtils->init()) if(!s_sharedFileUtils->init())
{ {
delete s_sharedFileUtils; delete s_sharedFileUtils;
s_sharedFileUtils = NULL; s_sharedFileUtils = NULL;
CCLOG("ERROR: Could not init CCFileUtilsIOS"); CCLOG("ERROR: Could not init CCFileUtilsApple");
} }
} }
return s_sharedFileUtils; return s_sharedFileUtils;
} }
static NSFileManager* s_fileManager = [NSFileManager defaultManager]; std::string FileUtilsApple::getWritablePath()
std::string FileUtilsIOS::getWritablePath()
{ {
// save to document folder // save to document folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
@ -238,9 +240,9 @@ std::string FileUtilsIOS::getWritablePath()
return strRet; return strRet;
} }
bool FileUtilsIOS::isFileExist(const std::string& strFilePath) bool FileUtilsApple::isFileExist(const std::string& strFilePath)
{ {
if (0 == strFilePath.length()) if(strFilePath.length() == 0)
{ {
return false; return false;
} }
@ -280,7 +282,7 @@ bool FileUtilsIOS::isFileExist(const std::string& strFilePath)
return bRet; return bRet;
} }
std::string FileUtilsIOS::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) std::string FileUtilsApple::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename)
{ {
if (strDirectory[0] != '/') if (strDirectory[0] != '/')
{ {
@ -302,13 +304,7 @@ std::string FileUtilsIOS::getFullPathForDirectoryAndFilename(const std::string&
return ""; return "";
} }
bool FileUtilsIOS::isAbsolutePath(const std::string& strPath) Dictionary* FileUtilsApple::createDictionaryWithContentsOfFile(const std::string& filename)
{
NSString* path = [NSString stringWithUTF8String:strPath.c_str()];
return [path isAbsolutePath] ? true : false;
}
Dictionary* FileUtilsIOS::createDictionaryWithContentsOfFile(const std::string& filename)
{ {
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename.c_str()); std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename.c_str());
NSString* pPath = [NSString stringWithUTF8String:fullPath.c_str()]; NSString* pPath = [NSString stringWithUTF8String:fullPath.c_str()];
@ -330,7 +326,7 @@ Dictionary* FileUtilsIOS::createDictionaryWithContentsOfFile(const std::string&
} }
} }
bool FileUtilsIOS::writeToFile(Dictionary *dict, const std::string &fullPath) bool FileUtilsApple::writeToFile(Dictionary *dict, const std::string &fullPath)
{ {
//CCLOG("iOS||Mac Dictionary %d write to file %s", dict->_ID, fullPath.c_str()); //CCLOG("iOS||Mac Dictionary %d write to file %s", dict->_ID, fullPath.c_str());
NSMutableDictionary *nsDict = [NSMutableDictionary dictionary]; NSMutableDictionary *nsDict = [NSMutableDictionary dictionary];
@ -348,7 +344,7 @@ bool FileUtilsIOS::writeToFile(Dictionary *dict, const std::string &fullPath)
return true; return true;
} }
Array* FileUtilsIOS::createArrayWithContentsOfFile(const std::string& filename) Array* FileUtilsApple::createArrayWithContentsOfFile(const std::string& filename)
{ {
// NSString* pPath = [NSString stringWithUTF8String:pFileName]; // NSString* pPath = [NSString stringWithUTF8String:pFileName];
// NSString* pathExtension= [pPath pathExtension]; // NSString* pathExtension= [pPath pathExtension];

View File

@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
****************************************************************************/ ****************************************************************************/
//#import <UIKit/UIKit.h>
#include "CCThread.h" #include "CCThread.h"
NS_CC_BEGIN NS_CC_BEGIN

View File

@ -1,62 +0,0 @@
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_FILEUTILS_IOS_H__
#define __CC_FILEUTILS_IOS_H__
#include "CCFileUtils.h"
#include <string>
#include <vector>
#include "CCPlatformMacros.h"
#include "ccTypes.h"
NS_CC_BEGIN
/**
* @addtogroup platform
* @{
*/
//! @brief Helper class to handle file operations
class CC_DLL FileUtilsIOS : public FileUtils
{
public:
/* override funtions */
virtual std::string getWritablePath();
virtual bool isFileExist(const std::string& strFilePath);
virtual bool isAbsolutePath(const std::string& strPath);
virtual std::string getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename);
virtual Dictionary* createDictionaryWithContentsOfFile(const std::string& filename);
virtual bool writeToFile(Dictionary *dict, const std::string& fullPath);
virtual Array* createArrayWithContentsOfFile(const std::string& filename);
};
// end of platform group
/// @}
NS_CC_END
#endif // __CC_FILEUTILS_IOS_H__

View File

@ -1,39 +0,0 @@
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#import <UIKit/UIKit.h>
#include "CCThread.h"
NS_CC_BEGIN
Thread::~Thread()
{
[(id)_autoReleasePool release];
}
void Thread::createAutoreleasePool()
{
_autoReleasePool = [[NSAutoreleasePool alloc] init];
}
NS_CC_END

View File

@ -1,354 +0,0 @@
/****************************************************************************
Copyright (c) 2010-2012 cocos2d-x.org
Copyright (c) 2011 Zynga Inc.
http://www.cocos2d-x.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#include "CCFileUtilsMac.h"
#import <Foundation/Foundation.h>
#include <string>
#include <stack>
#include "cocoa/CCString.h"
#include "CCFileUtils.h"
#include "CCDirector.h"
#include "CCSAXParser.h"
#include "CCDictionary.h"
#include "support/zip_support/unzip.h"
NS_CC_BEGIN
static void addValueToDict(id key, id value, Dictionary* pDict);
static void addObjectToNSDict(const char*key, Object* object, NSMutableDictionary *dict);
static void addItemToArray(id item, Array *array)
{
// add string value into array
if ([item isKindOfClass:[NSString class]]) {
String* pValue = new String([item UTF8String]);
array->addObject(pValue);
pValue->release();
return;
}
// add number value into array(such as int, float, bool and so on)
if ([item isKindOfClass:[NSNumber class]]) {
NSString* pStr = [item stringValue];
String* pValue = new String([pStr UTF8String]);
array->addObject(pValue);
pValue->release();
return;
}
// add dictionary value into array
if ([item isKindOfClass:[NSDictionary class]]) {
Dictionary* pDictItem = new Dictionary();
pDictItem->init();
for (id subKey in [item allKeys]) {
id subValue = [item objectForKey:subKey];
addValueToDict(subKey, subValue, pDictItem);
}
array->addObject(pDictItem);
pDictItem->release();
return;
}
// add array value into array
if ([item isKindOfClass:[NSArray class]]) {
Array *arrayItem = new Array();
arrayItem->initWithCapacity( [item count] );
for (id subItem in item) {
addItemToArray(subItem, arrayItem);
}
array->addObject(arrayItem);
arrayItem->release();
return;
}
}
static void addObjectToNSArray(Object *object, NSMutableArray *array)
{
// add string into array
if (String *ccString = dynamic_cast<String *>(object)) {
NSString *strElement = [NSString stringWithCString:ccString->getCString() encoding:NSUTF8StringEncoding];
[array addObject:strElement];
return;
}
// add array into array
if (Array *ccArray = dynamic_cast<Array *>(object)) {
NSMutableArray *arrElement = [NSMutableArray array];
Object *element = NULL;
CCARRAY_FOREACH(ccArray, element)
{
addObjectToNSArray(element, arrElement);
}
[array addObject:arrElement];
return;
}
// add dictionary value into array
if (Dictionary *ccDict = dynamic_cast<Dictionary *>(object)) {
NSMutableDictionary *dictElement = [NSMutableDictionary dictionary];
DictElement *element = NULL;
CCDICT_FOREACH(ccDict, element)
{
addObjectToNSDict(element->getStrKey(), element->getObject(), dictElement);
}
[array addObject:dictElement];
}
}
static void addValueToDict(id key, id value, Dictionary* pDict)
{
// the key must be a string
CCASSERT([key isKindOfClass:[NSString class]], "The key should be a string!");
std::string pKey = [key UTF8String];
// the value is a new dictionary
if ([value isKindOfClass:[NSDictionary class]]) {
Dictionary* pSubDict = new Dictionary();
for (id subKey in [value allKeys]) {
id subValue = [value objectForKey:subKey];
addValueToDict(subKey, subValue, pSubDict);
}
pDict->setObject(pSubDict, pKey.c_str());
pSubDict->release();
return;
}
// the value is a string
if ([value isKindOfClass:[NSString class]]) {
String* pValue = new String([value UTF8String]);
pDict->setObject(pValue, pKey.c_str());
pValue->release();
return;
}
// the value is a number
if ([value isKindOfClass:[NSNumber class]]) {
NSString* pStr = [value stringValue];
String* pValue = new String([pStr UTF8String]);
pDict->setObject(pValue, pKey.c_str());
pValue->release();
return;
}
// the value is a array
if ([value isKindOfClass:[NSArray class]]) {
Array *array = new Array();
array->initWithCapacity([value count]);
for (id item in value) {
addItemToArray(item, array);
}
pDict->setObject(array, pKey.c_str());
array->release();
return;
}
}
static void addObjectToNSDict(const char * key, Object* object, NSMutableDictionary *dict)
{
NSString *NSkey = [NSString stringWithCString:key encoding:NSUTF8StringEncoding];
// the object is a Dictionary
if (Dictionary *ccDict = dynamic_cast<Dictionary *>(object)) {
NSMutableDictionary *dictElement = [NSMutableDictionary dictionary];
DictElement *element = NULL;
CCDICT_FOREACH(ccDict, element)
{
addObjectToNSDict(element->getStrKey(), element->getObject(), dictElement);
}
[dict setObject:dictElement forKey:NSkey];
return;
}
// the object is a String
if (String *element = dynamic_cast<String *>(object)) {
NSString *strElement = [NSString stringWithCString:element->getCString() encoding:NSUTF8StringEncoding];
[dict setObject:strElement forKey:NSkey];
return;
}
// the object is a Array
if (Array *ccArray = dynamic_cast<Array *>(object)) {
NSMutableArray *arrElement = [NSMutableArray array];
Object *element = NULL;
CCARRAY_FOREACH(ccArray, element)
{
addObjectToNSArray(element, arrElement);
}
[dict setObject:arrElement forKey:NSkey];
return;
}
}
FileUtils* FileUtils::getInstance()
{
if (s_sharedFileUtils == NULL)
{
s_sharedFileUtils = new FileUtilsMac();
if(!s_sharedFileUtils->init())
{
delete s_sharedFileUtils;
s_sharedFileUtils = NULL;
CCLOG("ERROR: Could not init CCFileUtilsMac");
}
}
return s_sharedFileUtils;
}
static NSFileManager* s_fileManager = [NSFileManager defaultManager];
std::string FileUtilsMac::getWritablePath()
{
// save to document folder
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
std::string strRet = [documentsDirectory UTF8String];
strRet.append("/");
return strRet;
}
bool FileUtilsMac::isFileExist(const std::string& strFilePath)
{
if (0 == strFilePath.length())
{
return false;
}
bool bRet = false;
if (strFilePath[0] != '/')
{
std::string path = strFilePath;
std::string file;
size_t pos = path.find_last_of("/");
if (pos != std::string::npos)
{
file = path.substr(pos+1);
path = path.substr(0, pos+1);
NSString* fullpath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:file.c_str()]
ofType:nil
inDirectory:[NSString stringWithUTF8String:path.c_str()]];
if (fullpath != nil) {
bRet = true;
}
}
}
else
{
// Search path is an absolute path.
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:strFilePath.c_str()]]) {
bRet = true;
}
}
return bRet;
}
std::string FileUtilsMac::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename)
{
if (strDirectory[0] != '/')
{
NSString* fullpath = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:strFilename.c_str()]
ofType:nil
inDirectory:[NSString stringWithUTF8String:strDirectory.c_str()]];
if (fullpath != nil) {
return [fullpath UTF8String];
}
}
else
{
std::string fullPath = strDirectory+strFilename;
// Search path is an absolute path.
if ([s_fileManager fileExistsAtPath:[NSString stringWithUTF8String:fullPath.c_str()]]) {
return fullPath;
}
}
return "";
}
bool FileUtilsMac::isAbsolutePath(const std::string& strPath)
{
NSString* path = [NSString stringWithUTF8String:strPath.c_str()];
return [path isAbsolutePath] ? true : false;
}
Dictionary* FileUtilsMac::createDictionaryWithContentsOfFile(const std::string& filename)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename.c_str());
NSString* pPath = [NSString stringWithUTF8String:fullPath.c_str()];
NSDictionary* pDict = [NSDictionary dictionaryWithContentsOfFile:pPath];
Dictionary* pRet = Dictionary::create();
for (id key in [pDict allKeys]) {
id value = [pDict objectForKey:key];
addValueToDict(key, value, pRet);
}
return pRet;
}
bool FileUtilsMac::writeToFile(Dictionary *dict, const std::string &fullPath)
{
CCLOG("iOS||Mac Dictionary %d write to file %s", dict->_ID, fullPath.c_str());
NSMutableDictionary *nsDict = [NSMutableDictionary dictionary];
DictElement *element = NULL;
CCDICT_FOREACH(dict, element)
{
addObjectToNSDict(element->getStrKey(), element->getObject(), nsDict);
}
NSString *file = [NSString stringWithUTF8String:fullPath.c_str()];
// do it atomically
return [nsDict writeToFile:file atomically:YES];
}
Array* FileUtilsMac::createArrayWithContentsOfFile(const std::string& filename)
{
// NSString* pPath = [NSString stringWithUTF8String:pFileName];
// NSString* pathExtension= [pPath pathExtension];
// pPath = [pPath stringByDeletingPathExtension];
// pPath = [[NSBundle mainBundle] pathForResource:pPath ofType:pathExtension];
// fixing cannot read data using Array::createWithContentsOfFile
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename.c_str());
NSString* pPath = [NSString stringWithUTF8String:fullPath.c_str()];
NSArray* array = [NSArray arrayWithContentsOfFile:pPath];
Array* ret = Array::createWithCapacity( [array count] );
for (id value in array) {
addItemToArray(value, ret);
}
return ret;
}
NS_CC_END

View File

@ -1089,7 +1089,7 @@ static unsigned char cc_2x2_white_image[] = {
0xFF, 0xFF, 0xFF, 0xFF 0xFF, 0xFF, 0xFF, 0xFF
}; };
#define CC_2x2_WHITE_IMAGE_KEY "cc_2x2_white_image" #define CC_2x2_WHITE_IMAGE_KEY "/cc_2x2_white_image"
void Sprite::setTexture(Texture2D *texture) void Sprite::setTexture(Texture2D *texture)
{ {
@ -1110,7 +1110,7 @@ void Sprite::setTexture(Texture2D *texture)
bool isOK = image->initWithRawData(cc_2x2_white_image, sizeof(cc_2x2_white_image), 2, 2, 8); bool isOK = image->initWithRawData(cc_2x2_white_image, sizeof(cc_2x2_white_image), 2, 2, 8);
CCASSERT(isOK, "The 2x2 empty texture was created unsuccessfully."); CCASSERT(isOK, "The 2x2 empty texture was created unsuccessfully.");
texture = TextureCache::getInstance()->addUIImage(image, CC_2x2_WHITE_IMAGE_KEY); texture = TextureCache::getInstance()->addImage(image, CC_2x2_WHITE_IMAGE_KEY);
CC_SAFE_RELEASE(image); CC_SAFE_RELEASE(image);
} }
} }

View File

@ -178,7 +178,7 @@ void TextureCache::addImageAsync(const char *path, Object *target, SEL_CallFuncO
void TextureCache::loadImage() void TextureCache::loadImage()
{ {
AsyncStruct *pAsyncStruct = nullptr; AsyncStruct *asyncStruct = nullptr;
while (true) while (true)
{ {
@ -202,30 +202,30 @@ void TextureCache::loadImage()
} }
else else
{ {
pAsyncStruct = pQueue->front(); asyncStruct = pQueue->front();
pQueue->pop(); pQueue->pop();
_asyncStructQueueMutex.unlock(); _asyncStructQueueMutex.unlock();
} }
const char *filename = pAsyncStruct->filename.c_str(); const char *filename = asyncStruct->filename.c_str();
// generate image // generate image
Image *pImage = new Image(); Image *image = new Image();
if (pImage && !pImage->initWithImageFileThreadSafe(filename)) if (image && !image->initWithImageFileThreadSafe(filename))
{ {
CC_SAFE_RELEASE(pImage); CC_SAFE_RELEASE(image);
CCLOG("can not load %s", filename); CCLOG("can not load %s", filename);
continue; continue;
} }
// generate image info // generate image info
ImageInfo *pImageInfo = new ImageInfo(); ImageInfo *imageInfo = new ImageInfo();
pImageInfo->asyncStruct = pAsyncStruct; imageInfo->asyncStruct = asyncStruct;
pImageInfo->image = pImage; imageInfo->image = image;
// put the image info into the queue // put the image info into the queue
_imageInfoMutex.lock(); _imageInfoMutex.lock();
_imageInfoQueue->push(pImageInfo); _imageInfoQueue->push(imageInfo);
_imageInfoMutex.unlock(); _imageInfoMutex.unlock();
} }
@ -250,21 +250,21 @@ void TextureCache::addImageAsyncCallBack(float dt)
} }
else else
{ {
ImageInfo *pImageInfo = imagesQueue->front(); ImageInfo *imageInfo = imagesQueue->front();
imagesQueue->pop(); imagesQueue->pop();
_imageInfoMutex.unlock(); _imageInfoMutex.unlock();
AsyncStruct *pAsyncStruct = pImageInfo->asyncStruct; AsyncStruct *asyncStruct = imageInfo->asyncStruct;
Image *pImage = pImageInfo->image; Image *image = imageInfo->image;
Object *target = pAsyncStruct->target; Object *target = asyncStruct->target;
SEL_CallFuncO selector = pAsyncStruct->selector; SEL_CallFuncO selector = asyncStruct->selector;
const char* filename = pAsyncStruct->filename.c_str(); const char* filename = asyncStruct->filename.c_str();
// generate texture in render thread // generate texture in render thread
Texture2D *texture = new Texture2D(); Texture2D *texture = new Texture2D();
texture->initWithImage(pImage); texture->initWithImage(image);
#if CC_ENABLE_CACHE_TEXTURE_DATA #if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture file name // cache the texture file name
@ -280,9 +280,9 @@ void TextureCache::addImageAsyncCallBack(float dt)
target->release(); target->release();
} }
pImage->release(); image->release();
delete pAsyncStruct; delete asyncStruct;
delete pImageInfo; delete imageInfo;
--_asyncRefCount; --_asyncRefCount;
if (0 == _asyncRefCount) if (0 == _asyncRefCount)
@ -297,47 +297,39 @@ Texture2D * TextureCache::addImage(const char * path)
CCASSERT(path != NULL, "TextureCache: fileimage MUST not be NULL"); CCASSERT(path != NULL, "TextureCache: fileimage MUST not be NULL");
Texture2D * texture = NULL; Texture2D * texture = NULL;
Image* pImage = NULL; Image* image = NULL;
// Split up directory and filename // Split up directory and filename
// MUTEX: // MUTEX:
// Needed since addImageAsync calls this method from a different thread // Needed since addImageAsync calls this method from a different thread
std::string pathKey = path; std::string pathKey = FileUtils::getInstance()->fullPathForFilename(path);
pathKey = FileUtils::getInstance()->fullPathForFilename(pathKey.c_str());
if (pathKey.size() == 0) if (pathKey.size() == 0)
{ {
return NULL; return NULL;
} }
texture = static_cast<Texture2D*>(_textures->objectForKey(pathKey.c_str())); texture = static_cast<Texture2D*>(_textures->objectForKey(pathKey));
std::string fullpath = pathKey; std::string fullpath(pathKey);
if (! texture) if (! texture)
{ {
std::string lowerCase(pathKey);
for (unsigned int i = 0; i < lowerCase.length(); ++i)
{
lowerCase[i] = tolower(lowerCase[i]);
}
// all images are handled by UIImage except PVR extension that is handled by our own handler // all images are handled by UIImage except PVR extension that is handled by our own handler
do do
{ {
pImage = new Image(); image = new Image();
CC_BREAK_IF(NULL == pImage); CC_BREAK_IF(NULL == image);
bool bRet = pImage->initWithImageFile(fullpath.c_str()); bool bRet = image->initWithImageFile(fullpath.c_str());
CC_BREAK_IF(!bRet); CC_BREAK_IF(!bRet);
texture = new Texture2D(); texture = new Texture2D();
if( texture && if( texture && texture->initWithImage(image) )
texture->initWithImage(pImage) )
{ {
#if CC_ENABLE_CACHE_TEXTURE_DATA #if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture file name // cache the texture file name
VolatileTexture::addImageTexture(texture, fullpath.c_str()); VolatileTexture::addImageTexture(texture, fullpath.c_str());
#endif #endif
_textures->setObject(texture, pathKey.c_str()); _textures->setObject(texture, pathKey);
texture->release(); texture->release();
} }
else else
@ -347,30 +339,21 @@ Texture2D * TextureCache::addImage(const char * path)
} while (0); } while (0);
} }
CC_SAFE_RELEASE(pImage); CC_SAFE_RELEASE(image);
return texture; return texture;
} }
Texture2D* TextureCache::addUIImage(Image *image, const char *key) Texture2D* TextureCache::addImage(Image *image, const char *key)
{ {
CCASSERT(image != NULL, "TextureCache: image MUST not be nil"); CCASSERT(image != NULL, "TextureCache: image MUST not be nil");
Texture2D * texture = NULL; Texture2D * texture = NULL;
// textureForKey() use full path,so the key should be full path
std::string forKey;
if (key)
{
forKey = FileUtils::getInstance()->fullPathForFilename(key);
}
// Don't have to lock here, because addImageAsync() will not
// invoke opengl function in loading thread.
do do
{ {
// If key is nil, then create a new texture each time // If key is nil, then create a new texture each time
if(key && (texture = (Texture2D *)_textures->objectForKey(forKey.c_str()))) if(key && (texture = static_cast<Texture2D*>(_textures->objectForKey(key))) )
{ {
break; break;
} }
@ -381,7 +364,7 @@ Texture2D* TextureCache::addUIImage(Image *image, const char *key)
if(key && texture) if(key && texture)
{ {
_textures->setObject(texture, forKey.c_str()); _textures->setObject(texture, key);
texture->autorelease(); texture->autorelease();
} }
else else
@ -652,20 +635,20 @@ void VolatileTexture::reloadAllTextures()
{ {
case kImageFile: case kImageFile:
{ {
Image* pImage = new Image(); Image* image = new Image();
unsigned long nSize = 0; unsigned long nSize = 0;
unsigned char* pBuffer = FileUtils::getInstance()->getFileData(vt->_fileName.c_str(), "rb", &nSize); unsigned char* pBuffer = FileUtils::getInstance()->getFileData(vt->_fileName.c_str(), "rb", &nSize);
if (pImage && pImage->initWithImageData(pBuffer, nSize)) if (image && image->initWithImageData(pBuffer, nSize))
{ {
Texture2D::PixelFormat oldPixelFormat = Texture2D::getDefaultAlphaPixelFormat(); Texture2D::PixelFormat oldPixelFormat = Texture2D::getDefaultAlphaPixelFormat();
Texture2D::setDefaultAlphaPixelFormat(vt->_pixelFormat); Texture2D::setDefaultAlphaPixelFormat(vt->_pixelFormat);
vt->_texture->initWithImage(pImage); vt->_texture->initWithImage(image);
Texture2D::setDefaultAlphaPixelFormat(oldPixelFormat); Texture2D::setDefaultAlphaPixelFormat(oldPixelFormat);
} }
CC_SAFE_DELETE_ARRAY(pBuffer); CC_SAFE_DELETE_ARRAY(pBuffer);
CC_SAFE_RELEASE(pImage); CC_SAFE_RELEASE(image);
} }
break; break;
case kImageData: case kImageData:

View File

@ -85,8 +85,8 @@ public:
Dictionary* snapshotTextures(); Dictionary* snapshotTextures();
/** Returns a Texture2D object given an file image /** Returns a Texture2D object given an filename.
* If the file image was not previously loaded, it will create a new Texture2D * If the filename was not previously loaded, it will create a new Texture2D
* object and it will return it. It will use the filename as a key. * object and it will return it. It will use the filename as a key.
* Otherwise it will return a reference of a previously loaded image. * Otherwise it will return a reference of a previously loaded image.
* Supported image extensions: .png, .bmp, .tiff, .jpeg, .pvr, .gif * Supported image extensions: .png, .bmp, .tiff, .jpeg, .pvr, .gif
@ -102,13 +102,14 @@ public:
*/ */
virtual void addImageAsync(const char *path, Object *target, SEL_CallFuncO selector); virtual void addImageAsync(const char *path, Object *target, SEL_CallFuncO selector);
/** Returns a Texture2D object given an UIImage image /** Returns a Texture2D object given an Image.
* If the image was not previously loaded, it will create a new Texture2D object and it will return it. * If the image was not previously loaded, it will create a new Texture2D object and it will return it.
* Otherwise it will return a reference of a previously loaded image * Otherwise it will return a reference of a previously loaded image.
* The "key" parameter will be used as the "key" for the cache. * The "key" parameter will be used as the "key" for the cache.
* If "key" is nil, then a new texture will be created each time. * If "key" is nil, then a new texture will be created each time.
*/ */
Texture2D* addUIImage(Image *image, const char *key); Texture2D* addImage(Image *image, const char *key);
CC_DEPRECATED_ATTRIBUTE Texture2D* addUIImage(Image *image, const char *key) { return addImage(image,key); }
/** Returns an already created texture. Returns nil if the texture doesn't exist. /** Returns an already created texture. Returns nil if the texture doesn't exist.
@since v0.99.5 @since v0.99.5

View File

@ -280,7 +280,7 @@ void NodeDeallocTest::initWithQuantityOfNodes(unsigned int nNodes)
{ {
PerformceAllocScene::initWithQuantityOfNodes(nNodes); PerformceAllocScene::initWithQuantityOfNodes(nNodes);
printf("Size of Sprite: %lu\n", sizeof(Node)); printf("Size of Node: %lu\n", sizeof(Node));
scheduleUpdate(); scheduleUpdate();
} }
@ -333,7 +333,7 @@ void SpriteCreateEmptyTest::initWithQuantityOfNodes(unsigned int nNodes)
{ {
PerformceAllocScene::initWithQuantityOfNodes(nNodes); PerformceAllocScene::initWithQuantityOfNodes(nNodes);
printf("Size of Node: %lu\n", sizeof(Sprite)); printf("Size of Sprite: %lu\n", sizeof(Sprite));
scheduleUpdate(); scheduleUpdate();
} }
@ -383,7 +383,7 @@ void SpriteCreateTest::initWithQuantityOfNodes(unsigned int nNodes)
{ {
PerformceAllocScene::initWithQuantityOfNodes(nNodes); PerformceAllocScene::initWithQuantityOfNodes(nNodes);
printf("Size of Node: %lu\n", sizeof(Sprite)); printf("Size of Sprite: %lu\n", sizeof(Sprite));
scheduleUpdate(); scheduleUpdate();
} }
@ -406,7 +406,7 @@ void SpriteCreateTest::update(float dt)
std::string SpriteCreateTest::title() std::string SpriteCreateTest::title()
{ {
return "Create Sprite."; return "Create Sprite";
} }
std::string SpriteCreateTest::subtitle() std::string SpriteCreateTest::subtitle()
@ -433,7 +433,7 @@ void SpriteDeallocTest::initWithQuantityOfNodes(unsigned int nNodes)
{ {
PerformceAllocScene::initWithQuantityOfNodes(nNodes); PerformceAllocScene::initWithQuantityOfNodes(nNodes);
printf("Size of Node: %lu\n", sizeof(Sprite)); printf("Size of sprite: %lu\n", sizeof(Sprite));
scheduleUpdate(); scheduleUpdate();
} }