mirror of https://github.com/axmolengine/axmol.git
issue 1489:add AssetsManager
This commit is contained in:
parent
1df0095993
commit
91f5972b42
|
@ -0,0 +1,396 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 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.
|
||||
****************************************************************************/
|
||||
|
||||
#include "AssetsManager.h"
|
||||
#include "cocos2d.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <curl/easy.h>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include "support/zip_support/unzip.h"
|
||||
|
||||
using namespace cocos2d;
|
||||
using namespace std;
|
||||
|
||||
#define KEY_OF_VERSION "current-version-code"
|
||||
#define KEY_OF_DOWNLOADED_VERSION "downloaded-version-code"
|
||||
#define TEMP_PACKAGE_FILE_NAME "cocos2dx-update-temp-package.zip"
|
||||
#define BUFFER_SIZE 8192
|
||||
#define MAX_FILENAME 512
|
||||
|
||||
AssetsManager::AssetsManager()
|
||||
: _packageUrl("")
|
||||
, _versionFileUrl("")
|
||||
, _version("")
|
||||
, _curl(NULL)
|
||||
, _delegate(NULL)
|
||||
{
|
||||
_storagePath = CCFileUtils::sharedFileUtils()->getWritablePath();
|
||||
checkStoragePath();
|
||||
}
|
||||
|
||||
AssetsManager::AssetsManager(const char* packageUrl, const char* versionFileUrl)
|
||||
: _packageUrl(packageUrl)
|
||||
, _version("")
|
||||
, _versionFileUrl(versionFileUrl)
|
||||
, _delegate(NULL)
|
||||
, _curl(NULL)
|
||||
{
|
||||
_storagePath = CCFileUtils::sharedFileUtils()->getWritablePath();
|
||||
checkStoragePath();
|
||||
}
|
||||
|
||||
AssetsManager::AssetsManager(const char* packageUrl, const char* versionFileUrl, const char* storagePath)
|
||||
: _packageUrl(packageUrl)
|
||||
, _version("")
|
||||
, _versionFileUrl(versionFileUrl)
|
||||
, _storagePath(storagePath)
|
||||
, _delegate(NULL)
|
||||
, _curl(NULL)
|
||||
{
|
||||
checkStoragePath();
|
||||
}
|
||||
|
||||
void AssetsManager::checkStoragePath()
|
||||
{
|
||||
if (_storagePath.size() > 0 && _storagePath[_storagePath.size() - 1] != '/')
|
||||
{
|
||||
_storagePath.append("/");
|
||||
}
|
||||
}
|
||||
|
||||
static size_t getVersionCode(void *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
string *version = (string*)userdata;
|
||||
version->append((char*)ptr, size * nmemb);
|
||||
|
||||
return (size * nmemb);
|
||||
}
|
||||
|
||||
bool AssetsManager::checkUpdate()
|
||||
{
|
||||
if (_versionFileUrl.size() == 0) return false;
|
||||
|
||||
_curl = curl_easy_init();
|
||||
if (! _curl)
|
||||
{
|
||||
CCLOG("can not init curl");
|
||||
return false;
|
||||
}
|
||||
|
||||
CURLcode res;
|
||||
curl_easy_setopt(_curl, CURLOPT_URL, _versionFileUrl.c_str());
|
||||
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, getVersionCode);
|
||||
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, &_version);
|
||||
res = curl_easy_perform(_curl);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
CCLOG("can not get version file content");
|
||||
curl_easy_cleanup(_curl);
|
||||
return false;
|
||||
}
|
||||
|
||||
string recordedVersion = CCUserDefault::sharedUserDefault()->getStringForKey(KEY_OF_VERSION);
|
||||
if (recordedVersion == _version)
|
||||
{
|
||||
CCLOG("there is not new version");
|
||||
// Set resource search path.
|
||||
setSearchPath();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssetsManager::update()
|
||||
{
|
||||
// 1. Urls of package and version should be valid;
|
||||
// 2. Package should be a zip file.
|
||||
if (_versionFileUrl.size() == 0 ||
|
||||
_packageUrl.size() == 0 ||
|
||||
std::string::npos == _packageUrl.find(".zip"))
|
||||
{
|
||||
CCLOG("no version file url, or no package url, or the package is not a zip file");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if there is a new version.
|
||||
if (! checkUpdate()) return;
|
||||
|
||||
// Is package already downloaded?
|
||||
string downloadedVersion = CCUserDefault::sharedUserDefault()->getStringForKey(KEY_OF_DOWNLOADED_VERSION);
|
||||
if (downloadedVersion != _version)
|
||||
{
|
||||
if (! downLoad()) return;
|
||||
|
||||
// Record downloaded version.
|
||||
CCUserDefault::sharedUserDefault()->setStringForKey(KEY_OF_DOWNLOADED_VERSION, _version.c_str());
|
||||
CCUserDefault::sharedUserDefault()->flush();
|
||||
}
|
||||
|
||||
// Uncompress zip file.
|
||||
if (! uncompress()) return;
|
||||
|
||||
// Record new version code.
|
||||
CCUserDefault::sharedUserDefault()->setStringForKey(KEY_OF_VERSION, _version.c_str());
|
||||
|
||||
// Unrecord downloaded version code.
|
||||
CCUserDefault::sharedUserDefault()->setStringForKey(KEY_OF_DOWNLOADED_VERSION, "");
|
||||
|
||||
CCUserDefault::sharedUserDefault()->flush();
|
||||
|
||||
// Set resource search path.
|
||||
setSearchPath();
|
||||
|
||||
// Delete unloaded zip file.
|
||||
string zipfileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
|
||||
if (remove(zipfileName.c_str()) != 0)
|
||||
{
|
||||
CCLOG("can not remove downloaded zip file");
|
||||
}
|
||||
}
|
||||
|
||||
bool AssetsManager::uncompress()
|
||||
{
|
||||
// Open the zip file
|
||||
string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
|
||||
unzFile zipfile = unzOpen(outFileName.c_str());
|
||||
if (! zipfile)
|
||||
{
|
||||
CCLOG("can not open downloaded zip file %s", outFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get info about the zip file
|
||||
unz_global_info global_info;
|
||||
if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
|
||||
{
|
||||
CCLOG("can not read file global info of %s", outFileName.c_str());
|
||||
unzClose(zipfile);
|
||||
}
|
||||
|
||||
// Buffer to hold data read from the zip file
|
||||
char readBuffer[BUFFER_SIZE];
|
||||
|
||||
// Loop to extract all files.
|
||||
uLong i;
|
||||
for (i = 0; i < global_info.number_entry; ++i)
|
||||
{
|
||||
// Get info about current file.
|
||||
unz_file_info fileInfo;
|
||||
char fileName[MAX_FILENAME];
|
||||
if (unzGetCurrentFileInfo(zipfile,
|
||||
&fileInfo,
|
||||
fileName,
|
||||
MAX_FILENAME,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0) != UNZ_OK)
|
||||
{
|
||||
CCLOG("can not read file info");
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
string fullPath = _storagePath + fileName;
|
||||
|
||||
// Check if this entry is a directory or a file.
|
||||
const size_t filenameLength = strlen(fileName);
|
||||
if (fileName[filenameLength-1] == '/')
|
||||
{
|
||||
// Entry is a direcotry, so create it.
|
||||
// If the directory exists, it will failed scilently.
|
||||
if (!createDirectory(fullPath.c_str()))
|
||||
{
|
||||
CCLOG("can not create directory %s", fullPath.c_str());
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Entry is a file, so extract it.
|
||||
|
||||
// Open current file.
|
||||
if (unzOpenCurrentFile(zipfile) != UNZ_OK)
|
||||
{
|
||||
CCLOG("can not open file %s", fileName);
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a file to store current file.
|
||||
FILE *out = fopen(fullPath.c_str(), "wb");
|
||||
if (! out)
|
||||
{
|
||||
CCLOG("can not open destination file %s", fullPath.c_str());
|
||||
unzCloseCurrentFile(zipfile);
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write current file content to destinate file.
|
||||
int error = UNZ_OK;
|
||||
do
|
||||
{
|
||||
error = unzReadCurrentFile(zipfile, readBuffer, BUFFER_SIZE);
|
||||
if (error < 0)
|
||||
{
|
||||
CCLOG("error when read zip file %s, error code is %d", fileName, error);
|
||||
unzCloseCurrentFile(zipfile);
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (error > 0)
|
||||
{
|
||||
fwrite(readBuffer, error, 1, out);
|
||||
}
|
||||
} while(error > 0);
|
||||
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
unzCloseCurrentFile(zipfile);
|
||||
|
||||
// Goto next entry listed in the zip file.
|
||||
if ((i+1) < global_info.number_entry)
|
||||
{
|
||||
if (unzGoToNextFile(zipfile) != UNZ_OK)
|
||||
{
|
||||
CCLOG("can not read next file");
|
||||
unzClose(zipfile);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a direcotry is platform depended.
|
||||
*/
|
||||
bool AssetsManager::createDirectory(const char *path)
|
||||
{
|
||||
#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
|
||||
mode_t processMask = umask(0);
|
||||
int ret = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
umask(processMask);
|
||||
if (ret != 0 && (errno != EEXIST))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
//@todo create a direcotry on win32
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AssetsManager::setSearchPath()
|
||||
{
|
||||
vector<string> searchPaths = CCFileUtils::sharedFileUtils()->getSearchPaths();
|
||||
vector<string>::iterator iter = searchPaths.begin();
|
||||
searchPaths.insert(iter, _storagePath);
|
||||
CCFileUtils::sharedFileUtils()->setSearchPaths(searchPaths);
|
||||
}
|
||||
|
||||
static size_t downLoadPackage(void *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
FILE *fp = (FILE*)userdata;
|
||||
size_t written = fwrite(ptr, size, nmemb, fp);
|
||||
return written;
|
||||
}
|
||||
|
||||
bool AssetsManager::downLoad()
|
||||
{
|
||||
// Create file to save package.
|
||||
string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
|
||||
FILE *fp = fopen(outFileName.c_str(), "wb");
|
||||
if (! fp)
|
||||
{
|
||||
CCLOG("can not create file %s", outFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// download pacakge
|
||||
CURLcode res;
|
||||
curl_easy_setopt(_curl, CURLOPT_URL, _packageUrl.c_str());
|
||||
curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, downLoadPackage);
|
||||
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, fp);
|
||||
res = curl_easy_perform(_curl);
|
||||
curl_easy_cleanup(_curl);
|
||||
if (res != 0)
|
||||
{
|
||||
CCLOG("error when download package");
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* AssetsManager::getPackageUrl() const
|
||||
{
|
||||
return _packageUrl.c_str();
|
||||
}
|
||||
|
||||
void AssetsManager::setPackageUrl(const char *packageUrl)
|
||||
{
|
||||
_packageUrl = packageUrl;
|
||||
}
|
||||
|
||||
const char* AssetsManager::getStoragePath() const
|
||||
{
|
||||
return _storagePath.c_str();
|
||||
}
|
||||
|
||||
void AssetsManager::setStoragePath(const char *storagePath)
|
||||
{
|
||||
_storagePath = storagePath;
|
||||
checkStoragePath();
|
||||
}
|
||||
|
||||
const char* AssetsManager::getVersionFileUrl() const
|
||||
{
|
||||
return _versionFileUrl.c_str();
|
||||
}
|
||||
|
||||
void AssetsManager::setVersionFileUrl(const char *versionFileUrl)
|
||||
{
|
||||
_versionFileUrl = versionFileUrl;
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2013 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 __AssetsManager__
|
||||
#define __AssetsManager__
|
||||
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
|
||||
class AssetsManagerProtocol;
|
||||
|
||||
/*
|
||||
* This class is used to auto update resources, such as pictures or scripts.
|
||||
* 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
|
||||
{
|
||||
public:
|
||||
enum ErrorCode
|
||||
{
|
||||
ServerNotAvailable, /** server address error or timeout */
|
||||
TimeOut,
|
||||
};
|
||||
|
||||
//! Default constructor. You should set server address later.
|
||||
AssetsManager();
|
||||
|
||||
/* @brief Creates a AssetsManager with new package url and version code url.
|
||||
* AssetsManager will use the value returned by CCFileUtils::getWritablePath() as storage path.
|
||||
*
|
||||
* @param packageUrl URL of new package, the package should be a zip file.
|
||||
* @param versionFileUrl URL of version file. It should contain version code of new package.
|
||||
*/
|
||||
AssetsManager(const char* packageUrl, const char* versionFileUrl);
|
||||
|
||||
/* @brief Creates a AssetsManager with new package url, version code url and storage path.
|
||||
*
|
||||
* @param packageUrl URL of new package, the package should be a zip file.
|
||||
* @param versionFileUrl URL of version file. It should contain version code of new package.
|
||||
* @param storagePath The path to store downloaded resources.
|
||||
*/
|
||||
AssetsManager(const char* packageUrl, const char* versionFileUrl, const char* storagePath);
|
||||
|
||||
/* @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.
|
||||
*/
|
||||
virtual bool checkUpdate();
|
||||
|
||||
virtual void update();
|
||||
|
||||
/* @brief Gets url of package.
|
||||
*/
|
||||
const char* getPackageUrl() const;
|
||||
|
||||
/* @brief Sets url of package.
|
||||
*
|
||||
* @param packageUrl Package url.
|
||||
*/
|
||||
void setPackageUrl(const char* packageUrl);
|
||||
|
||||
const char* getVersionFileUrl() const;
|
||||
void setVersionFileUrl(const char* versionFileUrl);
|
||||
|
||||
/* @brief Gets storage path.
|
||||
*/
|
||||
const char* getStoragePath() const;
|
||||
|
||||
/* @brief Sets storage path.
|
||||
*
|
||||
* @param storagePath The path to store downloaded resources.
|
||||
*/
|
||||
void setStoragePath(const char* storagePath);
|
||||
|
||||
protected:
|
||||
bool downLoad();
|
||||
void checkStoragePath();
|
||||
bool uncompress();
|
||||
bool createDirectory(const char *path);
|
||||
void setSearchPath();
|
||||
|
||||
private:
|
||||
//! The path to store downloaded resources.
|
||||
std::string _storagePath;
|
||||
|
||||
//! The version of downloaded resources.
|
||||
std::string _version;
|
||||
|
||||
std::string _packageUrl;
|
||||
std::string _versionFileUrl;
|
||||
|
||||
AssetsManagerProtocol* _delegate;
|
||||
|
||||
CURL *_curl;
|
||||
};
|
||||
|
||||
/* @brief This class is used as base class of the delegate of AssetsManager.
|
||||
*/
|
||||
class AssetsManagerProtocol
|
||||
{
|
||||
public:
|
||||
/* @brief When an error happens in updating resources, AssetsManager will invoke its delegate's onError().
|
||||
*
|
||||
* @param errorCode The pointer to record error code.
|
||||
* The value will be set by AssetsManager.
|
||||
*/
|
||||
virtual void onError(AssetsManager::ErrorCode* errorCode) = 0;
|
||||
|
||||
virtual void onUpdate(float* percent) = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif /* defined(__AssetsManager__) */
|
|
@ -0,0 +1,136 @@
|
|||
//
|
||||
// AssetsManagerTestAppDelegate.cpp
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
|
||||
#include "AppDelegate.h"
|
||||
|
||||
#include "cocos2d.h"
|
||||
#include "SimpleAudioEngine.h"
|
||||
#include "ScriptingCore.h"
|
||||
#include "generated/cocos2dx.hpp"
|
||||
#include "cocos2d_specifics.hpp"
|
||||
#include "js_bindings_chipmunk_registration.h"
|
||||
#include "js_bindings_system_registration.h"
|
||||
#include "js_bindings_ccbreader.h"
|
||||
|
||||
USING_NS_CC;
|
||||
using namespace CocosDenshion;
|
||||
|
||||
AppDelegate::AppDelegate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AppDelegate::~AppDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
bool AppDelegate::applicationDidFinishLaunching()
|
||||
{
|
||||
// initialize director
|
||||
CCDirector *pDirector = CCDirector::sharedDirector();
|
||||
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
|
||||
|
||||
// turn on display FPS
|
||||
//pDirector->setDisplayStats(true);
|
||||
|
||||
// set FPS. the default value is 1.0/60 if you don't call this
|
||||
pDirector->setAnimationInterval(1.0 / 60);
|
||||
|
||||
ScriptingCore* sc = ScriptingCore::getInstance();
|
||||
sc->addRegisterCallback(register_all_cocos2dx);
|
||||
sc->addRegisterCallback(register_cocos2dx_js_extensions);
|
||||
sc->addRegisterCallback(register_CCBuilderReader);
|
||||
sc->addRegisterCallback(jsb_register_chipmunk);
|
||||
sc->addRegisterCallback(jsb_register_system);
|
||||
|
||||
sc->start();
|
||||
|
||||
CCScene *scene = CCScene::create();
|
||||
UpdateLayer *updateLayer = new UpdateLayer();
|
||||
scene->addChild(updateLayer);
|
||||
updateLayer->release();
|
||||
|
||||
pDirector->runWithScene(scene);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
|
||||
void AppDelegate::applicationDidEnterBackground()
|
||||
{
|
||||
CCDirector::sharedDirector()->stopAnimation();
|
||||
SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
|
||||
SimpleAudioEngine::sharedEngine()->pauseAllEffects();
|
||||
}
|
||||
|
||||
// this function will be called when the app is active again
|
||||
void AppDelegate::applicationWillEnterForeground()
|
||||
{
|
||||
CCDirector::sharedDirector()->startAnimation();
|
||||
SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
|
||||
SimpleAudioEngine::sharedEngine()->resumeAllEffects();
|
||||
}
|
||||
|
||||
UpdateLayer::UpdateLayer()
|
||||
: pAssetManager(NULL)
|
||||
, pItemEnter(NULL)
|
||||
, pItemReset(NULL)
|
||||
, pItemUpdate(NULL)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
UpdateLayer::~UpdateLayer()
|
||||
{
|
||||
CC_SAFE_DELETE(pAssetManager);
|
||||
}
|
||||
|
||||
void UpdateLayer::update(cocos2d::CCObject *pSender)
|
||||
{
|
||||
// update resources
|
||||
pAssetManager = new AssetsManager("http://localhost/package.zip", "http://localhost/version");
|
||||
pAssetManager->update();
|
||||
delete pAssetManager;
|
||||
pAssetManager = NULL;
|
||||
|
||||
// Run new version
|
||||
CCScriptEngineProtocol *pEngine = ScriptingCore::getInstance();
|
||||
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
|
||||
ScriptingCore::getInstance()->runScript("main.js");
|
||||
}
|
||||
|
||||
void UpdateLayer::reset(cocos2d::CCObject *pSender)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UpdateLayer::enter(cocos2d::CCObject *pSender)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool UpdateLayer::init()
|
||||
{
|
||||
CCLayer::init();
|
||||
|
||||
CCSize size = CCDirector::sharedDirector()->getWinSize();
|
||||
|
||||
pItemReset = CCMenuItemFont::create("reset", this, menu_selector(UpdateLayer::reset));
|
||||
pItemEnter = CCMenuItemFont::create("enter", this, menu_selector(UpdateLayer::enter));
|
||||
pItemUpdate = CCMenuItemFont::create("update", this, menu_selector(UpdateLayer::update));
|
||||
|
||||
pItemEnter->setPosition(ccp(size.width/2, size.height/2 + 50));
|
||||
pItemReset->setPosition(ccp(size.width/2, size.height/2));
|
||||
pItemUpdate->setPosition(ccp(size.width/2, size.height/2 - 50));
|
||||
|
||||
CCMenu *menu = CCMenu::create(pItemUpdate, pItemEnter, pItemReset, NULL);
|
||||
menu->setPosition(ccp(0,0));
|
||||
addChild(menu);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// AssetsManagerTestAppDelegate.h
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _APP_DELEGATE_H_
|
||||
#define _APP_DELEGATE_H_
|
||||
|
||||
#include "CCApplication.h"
|
||||
#include "cocos2d.h"
|
||||
#include "cocos-ext.h"
|
||||
|
||||
/**
|
||||
@brief The cocos2d Application.
|
||||
|
||||
The reason to implement with private inheritance is to hide some interface details of CCDirector.
|
||||
*/
|
||||
class AppDelegate : private cocos2d::CCApplication
|
||||
{
|
||||
public:
|
||||
AppDelegate();
|
||||
virtual ~AppDelegate();
|
||||
|
||||
/**
|
||||
@brief Implement CCDirector and CCScene init code here.
|
||||
@return true Initialize success, app continue.
|
||||
@return false Initialize failed, app terminate.
|
||||
*/
|
||||
virtual bool applicationDidFinishLaunching();
|
||||
|
||||
/**
|
||||
@brief The function is called when the application enters the background
|
||||
@param the pointer of the application instance
|
||||
*/
|
||||
virtual void applicationDidEnterBackground();
|
||||
|
||||
/**
|
||||
@brief The function is called when the application enters the foreground
|
||||
@param the pointer of the application instance
|
||||
*/
|
||||
virtual void applicationWillEnterForeground();
|
||||
};
|
||||
|
||||
class UpdateLayer : public cocos2d::CCLayer
|
||||
{
|
||||
public:
|
||||
UpdateLayer();
|
||||
~UpdateLayer();
|
||||
virtual bool init();
|
||||
void enter(cocos2d::CCObject *pSender);
|
||||
void reset(cocos2d::CCObject *pSender);
|
||||
void update(cocos2d::CCObject *pSender);
|
||||
|
||||
private:
|
||||
AssetsManager *pAssetManager;
|
||||
cocos2d::CCMenuItemFont *pItemEnter;
|
||||
cocos2d::CCMenuItemFont *pItemReset;
|
||||
cocos2d::CCMenuItemFont *pItemUpdate;
|
||||
};
|
||||
|
||||
#endif // _APP_DELEGATE_H_
|
||||
|
|
@ -0,0 +1 @@
|
|||
5fe89fb5bd58cedf13b0363f97b20e3ea7ff255d
|
|
@ -0,0 +1,52 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 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.
|
||||
****************************************************************************/
|
||||
|
||||
// boot code needed for cocos2d + JS bindings.
|
||||
// Not needed by cocos2d-html5
|
||||
|
||||
require("jsb.js");
|
||||
|
||||
var appFiles = [
|
||||
'myApp.js'
|
||||
];
|
||||
|
||||
cc.dumpConfig();
|
||||
|
||||
for( var i=0; i < appFiles.length; i++) {
|
||||
require( appFiles[i] );
|
||||
}
|
||||
|
||||
var director = cc.Director.getInstance();
|
||||
director.setDisplayStats(true);
|
||||
|
||||
// set FPS. the default value is 1.0/60 if you don't call this
|
||||
director.setAnimationInterval(1.0 / 60);
|
||||
|
||||
// create a scene. it's an autorelease object
|
||||
var myScene = new MyScene();
|
||||
|
||||
// run
|
||||
director.replaceScene(myScene);
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/****************************************************************************
|
||||
Copyright (c) 2010-2012 cocos2d-x.org
|
||||
Copyright (c) 2008-2010 Ricardo Quesada
|
||||
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.
|
||||
****************************************************************************/
|
||||
|
||||
var MyLayer = cc.Layer.extend({
|
||||
isMouseDown:false,
|
||||
helloImg:null,
|
||||
helloLabel:null,
|
||||
circle:null,
|
||||
sprite:null,
|
||||
|
||||
ctor:function() {
|
||||
this._super();
|
||||
cc.associateWithNative( this, cc.Layer );
|
||||
},
|
||||
|
||||
init:function () {
|
||||
|
||||
//////////////////////////////
|
||||
// 1. super init first
|
||||
this._super();
|
||||
|
||||
/////////////////////////////
|
||||
// 2. add a menu item with "X" image, which is clicked to quit the program
|
||||
// you may modify it.
|
||||
// ask director the window size
|
||||
var size = cc.Director.getInstance().getWinSize();
|
||||
|
||||
// add a "close" icon to exit the progress. it's an autorelease object
|
||||
var closeItem = cc.MenuItemImage.create(
|
||||
"CloseNormal.png",
|
||||
"CloseSelected.png",
|
||||
function () {
|
||||
cc.log("close button was clicked.");
|
||||
},this);
|
||||
closeItem.setAnchorPoint(cc.p(0.5, 0.5));
|
||||
|
||||
var menu = cc.Menu.create(closeItem);
|
||||
menu.setPosition(cc.p(0, 0));
|
||||
this.addChild(menu, 1);
|
||||
closeItem.setPosition(cc.p(size.width - 20, 20));
|
||||
|
||||
/////////////////////////////
|
||||
// 3. add your codes below...
|
||||
// add a label shows "Hello World"
|
||||
// create and initialize a label
|
||||
this.helloLabel = cc.LabelTTF.create("Hello World", "Arial", 38);
|
||||
// position the label on the center of the screen
|
||||
this.helloLabel.setPosition(cc.p(size.width / 2, size.height - 40));
|
||||
// add the label as a child to this layer
|
||||
this.addChild(this.helloLabel, 5);
|
||||
|
||||
// add "Helloworld" splash screen"
|
||||
this.sprite = cc.Sprite.create("Background.png");
|
||||
this.sprite.setAnchorPoint(cc.p(0.5, 0.5));
|
||||
this.sprite.setPosition(cc.p(size.width / 2, size.height / 2));
|
||||
|
||||
this.addChild(this.sprite, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var MyScene = cc.Scene.extend({
|
||||
ctor:function() {
|
||||
this._super();
|
||||
cc.associateWithNative( this, cc.Scene );
|
||||
},
|
||||
|
||||
onEnter:function () {
|
||||
this._super();
|
||||
var layer = new MyLayer();
|
||||
this.addChild(layer);
|
||||
layer.init();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// AssetsManagerTestAppController.h
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
|
||||
@class RootViewController;
|
||||
|
||||
@interface AppController : NSObject <UIAccelerometerDelegate, UIAlertViewDelegate, UITextFieldDelegate,UIApplicationDelegate> {
|
||||
UIWindow *window;
|
||||
RootViewController *viewController;
|
||||
}
|
||||
|
||||
@property (nonatomic, retain) UIWindow *window;
|
||||
@property (nonatomic, retain) RootViewController *viewController;
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
//
|
||||
// AssetsManagerTestAppController.mm
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppController.h"
|
||||
#import "cocos2d.h"
|
||||
#import "EAGLView.h"
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "RootViewController.h"
|
||||
|
||||
@implementation AppController
|
||||
|
||||
@synthesize window;
|
||||
@synthesize viewController;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Application lifecycle
|
||||
|
||||
// cocos2d application instance
|
||||
static AppDelegate s_sharedApplication;
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
|
||||
// Override point for customization after application launch.
|
||||
|
||||
// Add the view controller's view to the window and display.
|
||||
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
|
||||
EAGLView *__glView = [EAGLView viewWithFrame: [window bounds]
|
||||
pixelFormat: kEAGLColorFormatRGBA8
|
||||
depthFormat: GL_DEPTH_COMPONENT16
|
||||
preserveBackbuffer: NO
|
||||
sharegroup: nil
|
||||
multiSampling: NO
|
||||
numberOfSamples:0 ];
|
||||
|
||||
// Use RootViewController manage EAGLView
|
||||
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
|
||||
viewController.wantsFullScreenLayout = YES;
|
||||
viewController.view = __glView;
|
||||
|
||||
// Set RootViewController to window
|
||||
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
|
||||
{
|
||||
// warning: addSubView doesn't work on iOS6
|
||||
[window addSubview: viewController.view];
|
||||
}
|
||||
else
|
||||
{
|
||||
// use this method on ios6
|
||||
[window setRootViewController:viewController];
|
||||
}
|
||||
|
||||
[window makeKeyAndVisible];
|
||||
|
||||
[[UIApplication sharedApplication] setStatusBarHidden: YES];
|
||||
|
||||
cocos2d::CCApplication::sharedApplication()->run();
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||
/*
|
||||
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
*/
|
||||
cocos2d::CCDirector::sharedDirector()->pause();
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
/*
|
||||
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
*/
|
||||
cocos2d::CCDirector::sharedDirector()->resume();
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
/*
|
||||
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
|
||||
*/
|
||||
cocos2d::CCApplication::sharedApplication()->applicationDidEnterBackground();
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||
/*
|
||||
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
|
||||
*/
|
||||
cocos2d::CCApplication::sharedApplication()->applicationWillEnterForeground();
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||
/*
|
||||
Called when the application is about to terminate.
|
||||
See also applicationDidEnterBackground:.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Memory management
|
||||
|
||||
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
|
||||
/*
|
||||
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
|
||||
*/
|
||||
cocos2d::CCDirector::sharedDirector()->purgeCachedData();
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1 @@
|
|||
b7ecc45522a1c4a589430ee428a083cdc9b06384
|
|
@ -0,0 +1,8 @@
|
|||
//
|
||||
// Prefix header for all source files of the 'AssetsManagerTest' target in the 'AssetsManagerTest' project
|
||||
//
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// AssetsManagerTestAppController.h
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
@interface RootViewController : UIViewController {
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,73 @@
|
|||
//
|
||||
// AssetsManagerTestAppController.h
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RootViewController.h"
|
||||
|
||||
|
||||
@implementation RootViewController
|
||||
|
||||
/*
|
||||
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
|
||||
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
|
||||
// Custom initialization
|
||||
}
|
||||
return self;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Implement loadView to create a view hierarchy programmatically, without using a nib.
|
||||
- (void)loadView {
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
}
|
||||
|
||||
*/
|
||||
// Override to allow orientations other than the default portrait orientation.
|
||||
// This method is deprecated on ios6
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
|
||||
return UIInterfaceOrientationIsLandscape( interfaceOrientation );
|
||||
}
|
||||
|
||||
// For ios6, use supportedInterfaceOrientations & shouldAutorotate instead
|
||||
- (NSUInteger) supportedInterfaceOrientations{
|
||||
#ifdef __IPHONE_6_0
|
||||
return UIInterfaceOrientationMaskLandscape;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL) shouldAutorotate {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
// Releases the view if it doesn't have a superview.
|
||||
[super didReceiveMemoryWarning];
|
||||
|
||||
// Release any cached data, images, etc that aren't in use.
|
||||
}
|
||||
|
||||
- (void)viewDidUnload {
|
||||
[super viewDidUnload];
|
||||
// Release any retained subviews of the main view.
|
||||
// e.g. self.myOutlet = nil;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
@end
|
Binary file not shown.
After Width: | Height: | Size: 60 KiB |
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// main.m
|
||||
// AssetsManagerTest
|
||||
//
|
||||
// Created by minggo on 2/5/13.
|
||||
// Copyright __MyCompanyName__ 2013. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
int retVal = UIApplicationMain(argc, argv, nil, @"AppController");
|
||||
[pool release];
|
||||
return retVal;
|
||||
}
|
Loading…
Reference in New Issue