Merge pull request #3548 from nakosung/multi_assets

exposed AssetsManager to javascript and added multiple-assetsManager support
This commit is contained in:
minggo 2013-09-09 19:01:53 -07:00
commit 2a5c3ff7e4
6 changed files with 144 additions and 35 deletions

View File

@ -34,8 +34,10 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#endif
#include "support/zip_support/unzip.h"
using namespace cocos2d;
@ -81,6 +83,7 @@ AssetsManager::AssetsManager(const char* packageUrl/* =NULL */, const char* vers
, _connectionTimeout(0)
, _delegate(NULL)
, _isDownloading(false)
, _shouldDeleteDelegateWhenExit(false)
{
checkStoragePath();
_schedule = new Helper();
@ -92,6 +95,10 @@ AssetsManager::~AssetsManager()
{
_schedule->release();
}
if (_shouldDeleteDelegateWhenExit)
{
delete _delegate;
}
}
void AssetsManager::checkStoragePath()
@ -102,6 +109,26 @@ void AssetsManager::checkStoragePath()
}
}
// Multiple key names
static std::string keyWithHash( const char* prefix, const std::string& url )
{
char buf[256];
sprintf(buf,"%s%zd",prefix,std::hash<std::string>()(url));
return buf;
}
// hashed version
std::string AssetsManager::keyOfVersion() const
{
return keyWithHash(KEY_OF_VERSION,_packageUrl);
}
// hashed version
std::string AssetsManager::keyOfDownloadedVersion() const
{
return keyWithHash(KEY_OF_DOWNLOADED_VERSION,_packageUrl);
}
static size_t getVersionCode(void *ptr, size_t size, size_t nmemb, void *userdata)
{
string *version = (string*)userdata;
@ -140,7 +167,7 @@ bool AssetsManager::checkUpdate()
return false;
}
string recordedVersion = UserDefault::getInstance()->getStringForKey(KEY_OF_VERSION);
string recordedVersion = UserDefault::getInstance()->getStringForKey(keyOfVersion().c_str());
if (recordedVersion == _version)
{
sendErrorMessage(ErrorCode::NO_NEW_VERSION);
@ -212,7 +239,7 @@ void AssetsManager::update()
}
// Is package already downloaded?
_downloadedVersion = UserDefault::getInstance()->getStringForKey(KEY_OF_DOWNLOADED_VERSION);
_downloadedVersion = UserDefault::getInstance()->getStringForKey(keyOfDownloadedVersion().c_str());
auto t = std::thread(&AssetsManager::downloadAndUncompress, this);
t.detach();
@ -469,12 +496,12 @@ void AssetsManager::setVersionFileUrl(const char *versionFileUrl)
string AssetsManager::getVersion()
{
return UserDefault::getInstance()->getStringForKey(KEY_OF_VERSION);
return UserDefault::getInstance()->getStringForKey(keyOfVersion().c_str());
}
void AssetsManager::deleteVersion()
{
UserDefault::getInstance()->setStringForKey(KEY_OF_VERSION, "");
UserDefault::getInstance()->setStringForKey(keyOfVersion().c_str(), "");
}
void AssetsManager::setDelegate(AssetsManagerDelegateProtocol *delegate)
@ -549,7 +576,7 @@ void AssetsManager::Helper::update(float dt)
break;
case ASSETSMANAGER_MESSAGE_RECORD_DOWNLOADED_VERSION:
UserDefault::getInstance()->setStringForKey(KEY_OF_DOWNLOADED_VERSION,
UserDefault::getInstance()->setStringForKey(((AssetsManager*)msg->obj)->keyOfDownloadedVersion().c_str(),
((AssetsManager*)msg->obj)->_version.c_str());
UserDefault::getInstance()->flush();
@ -585,10 +612,10 @@ void AssetsManager::Helper::handleUpdateSucceed(Message *msg)
AssetsManager* manager = (AssetsManager*)msg->obj;
// Record new version code.
UserDefault::getInstance()->setStringForKey(KEY_OF_VERSION, manager->_version.c_str());
UserDefault::getInstance()->setStringForKey(manager->keyOfVersion().c_str(), manager->_version.c_str());
// Unrecord downloaded version code.
UserDefault::getInstance()->setStringForKey(KEY_OF_DOWNLOADED_VERSION, "");
UserDefault::getInstance()->setStringForKey(manager->keyOfDownloadedVersion().c_str(), "");
UserDefault::getInstance()->flush();
// Set resource search path.
@ -604,4 +631,69 @@ void AssetsManager::Helper::handleUpdateSucceed(Message *msg)
if (manager) manager->_delegate->onSuccess();
}
AssetsManager* AssetsManager::create(const char* packageUrl, const char* versionFileUrl, const char* storagePath, ErrorCallback errorCallback, ProgressCallback progressCallback, SuccessCallback successCallback )
{
class DelegateProtocolImpl : public AssetsManagerDelegateProtocol
{
public :
DelegateProtocolImpl(ErrorCallback errorCallback, ProgressCallback progressCallback, SuccessCallback successCallback)
: errorCallback(errorCallback), progressCallback(progressCallback), successCallback(successCallback)
{}
virtual void onError(AssetsManager::ErrorCode errorCode) { errorCallback(int(errorCode)); }
virtual void onProgress(int percent) { progressCallback(percent); }
virtual void onSuccess() { successCallback(); }
private :
ErrorCallback errorCallback;
ProgressCallback progressCallback;
SuccessCallback successCallback;
};
auto* manager = new AssetsManager(packageUrl,versionFileUrl,storagePath);
auto* delegate = new DelegateProtocolImpl(errorCallback,progressCallback,successCallback);
manager->setDelegate(delegate);
manager->_shouldDeleteDelegateWhenExit = true;
manager->autorelease();
return manager;
}
void AssetsManager::createStoragePath()
{
// Remove downloaded files
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
DIR *dir = NULL;
dir = opendir (_storagePath.c_str());
if (!dir)
{
mkdir(_storagePath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
}
#else
if ((GetFileAttributesA(_storagePath.c_str())) == INVALID_FILE_ATTRIBUTES)
{
CreateDirectoryA(_storagePath.c_str(), 0);
}
#endif
}
void AssetsManager::destroyStoragePath()
{
// Delete recorded version codes.
deleteVersion();
// Remove downloaded files
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
string command = "rm -r ";
// Path may include space.
command += "\"" + _storagePath + "\"";
system(command.c_str());
#else
string command = "rd /s /q ";
// Path may include space.
command += "\"" + _storagePath + "\"";
system(command.c_str());
#endif
}
NS_CC_EXT_END;

View File

@ -26,7 +26,7 @@
#define __AssetsManager__
#include <string>
#include <curl/curl.h>
#include <mutex>
#include "cocos2d.h"
@ -41,7 +41,7 @@ class AssetsManagerDelegateProtocol;
* The updated package should be a zip file. And there should be a file named
* version in the server, which contains version code.
*/
class AssetsManager
class AssetsManager : public Node
{
public:
enum class ErrorCode
@ -77,6 +77,14 @@ public:
virtual ~AssetsManager();
typedef std::function<void(int)> ErrorCallback;
typedef std::function<void(int)> ProgressCallback;
typedef std::function<void(void)> SuccessCallback;
/* @brief To access within scripting environment
*/
static AssetsManager* create(const char* packageUrl, const char* versionFileUrl, const char* storagePath, ErrorCallback errorCallback, ProgressCallback progressCallback, SuccessCallback successCallback );
/* @brief Check out if there is a new version resource.
* You may use this method before updating, then let user determine whether
* he wants to update resources.
@ -138,7 +146,7 @@ public:
/* downloadAndUncompress is the entry of a new thread
*/
friend int assetsManagerProgressFunc(void *, double, double, double, double);
protected:
bool downLoad();
void checkStoragePath();
@ -172,6 +180,15 @@ private:
std::list<Message*> *_messageQueue;
std::mutex _messageQueueMutex;
};
private:
/** @brief Initializes storage path.
*/
void createStoragePath();
/** @brief Destroys storage path.
*/
void destroyStoragePath();
private:
//! The path to store downloaded resources.
@ -185,13 +202,18 @@ private:
std::string _downloadedVersion;
CURL *_curl;
void *_curl;
Helper *_schedule;
unsigned int _connectionTimeout;
AssetsManagerDelegateProtocol *_delegate; // weak reference
AssetsManagerDelegateProtocol *_delegate;
bool _isDownloading;
bool _shouldDeleteDelegateWhenExit;
std::string keyOfVersion() const;
std::string keyOfDownloadedVersion() const;
};
class AssetsManagerDelegateProtocol

View File

@ -56,4 +56,6 @@
#include "CCDeprecated-ext.h"
#include "AssetsManager/AssetsManager.h"
#endif /* __COCOS2D_EXT_H__ */

View File

@ -85,8 +85,6 @@ UpdateLayer::UpdateLayer()
UpdateLayer::~UpdateLayer()
{
AssetsManager *pAssetsManager = getAssetsManager();
CC_SAFE_DELETE(pAssetsManager);
}
void UpdateLayer::update(cocos2d::Object *pSender)
@ -94,7 +92,7 @@ void UpdateLayer::update(cocos2d::Object *pSender)
pProgressLabel->setString("");
// update resources
getAssetsManager()->update();
pAssetsManager->update();
isUpdateItemClicked = true;
}
@ -116,7 +114,7 @@ void UpdateLayer::reset(cocos2d::Object *pSender)
system(command.c_str());
#endif
// Delete recorded version codes.
getAssetsManager()->deleteVersion();
pAssetsManager->deleteVersion();
createDownloadedDir();
}
@ -141,6 +139,15 @@ bool UpdateLayer::init()
{
Layer::init();
/** Creates assets manager */
pAssetsManager = new AssetsManager("https://raw.github.com/minggo/AssetsManagerTest/master/package.zip",
"https://raw.github.com/minggo/AssetsManagerTest/master/version",
pathToSave.c_str());
pAssetsManager->setDelegate(this);
pAssetsManager->setConnectionTimeout(3);
addChild(pAssetsManager);
pAssetsManager->release();
createDownloadedDir();
auto size = Director::getInstance()->getWinSize();
@ -164,22 +171,6 @@ bool UpdateLayer::init()
return true;
}
AssetsManager* UpdateLayer::getAssetsManager()
{
static AssetsManager *pAssetsManager = NULL;
if (! pAssetsManager)
{
pAssetsManager = new AssetsManager("https://raw.github.com/minggo/AssetsManagerTest/master/package.zip",
"https://raw.github.com/minggo/AssetsManagerTest/master/version",
pathToSave.c_str());
pAssetsManager->setDelegate(this);
pAssetsManager->setConnectionTimeout(3);
}
return pAssetsManager;
}
void UpdateLayer::createDownloadedDir()
{
pathToSave = FileUtils::getInstance()->getWritablePath();

View File

@ -60,7 +60,7 @@ public:
virtual void onSuccess();
private:
cocos2d::extension::AssetsManager* getAssetsManager();
cocos2d::extension::AssetsManager* pAssetsManager;
void createDownloadedDir();
cocos2d::MenuItemFont *pItemEnter;

View File

@ -13,7 +13,7 @@ android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_flags = -nostdinc -x c++ -std=c++11
cocos_headers = -I%(cocosdir)s/cocos2dx/include -I%(cocosdir)s/cocos2dx/platform -I%(cocosdir)s/cocos2dx/platform/android -I%(cocosdir)s/cocos2dx -I%(cocosdir)s/cocos2dx/kazmath/include -I%(cocosdir)s/extensions
cocos_headers = -I%(cocosdir)s/cocos2dx/include -I%(cocosdir)s/cocos2dx/platform -I%(cocosdir)s/cocos2dx/platform/android -I%(cocosdir)s/cocos2dx -I%(cocosdir)s/cocos2dx/kazmath/include -I%(cocosdir)s/extensions
cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT
cxxgenerator_headers = -I%(cxxgeneratordir)s/targets/spidermonkey/common
@ -26,7 +26,7 @@ headers = %(cocosdir)s/extensions/cocos-ext.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = CCBReader.* CCBAnimationManager.* Scale9Sprite Control.* ControlButton.* ScrollView$ TableView$ TableViewCell$ EditBox$
classes = AssetsManager.* CCBReader.* CCBAnimationManager.* Scale9Sprite Control.* ControlButton.* ScrollView$ TableView$ TableViewCell$ EditBox$
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
@ -43,6 +43,8 @@ skip = CCBReader::[^CCBReader$ addOwnerCallbackName isJSControlled readByte getC
*::[^visit$ copyWith.* onEnter.* onExit.* ^description$ getObjectType .*HSV],
EditBox::[(g|s)etDelegate ^keyboard.* touchDownAction getScriptEditBoxHandler registerScriptEditBoxHandler unregisterScriptEditBoxHandler],
TableView::[create (g|s)etDataSource$ (g|s)etDelegate],
AssetsManager::[setDelegate],
AssetsManagerDelegateProtocol::[*],
Control::[removeHandleOfControlEvent addHandleOfControlEvent],
ControlUtils::[*],
ControlSwitchSprite::[*]