初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,414 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 __AssetsManagerEx__
#define __AssetsManagerEx__
#include <string>
#include <unordered_map>
#include <vector>
#include "platform/CCFileUtils.h"
#include "network/CCDownloader.h"
#include "CCEventAssetsManagerEx.h"
#include "Manifest.h"
#include "extensions/ExtensionMacros.h"
#include "extensions/ExtensionExport.h"
#include "json/document-wrapper.h"
NS_CC_EXT_BEGIN
/**
* @brief This class is used to auto update resources, such as pictures or scripts.
*/
class CC_EX_DLL AssetsManagerEx : public Ref
{
public:
//! Update states
enum class State
{
UNINITED,
UNCHECKED,
PREDOWNLOAD_VERSION,
DOWNLOADING_VERSION,
VERSION_LOADED,
PREDOWNLOAD_MANIFEST,
DOWNLOADING_MANIFEST,
MANIFEST_LOADED,
NEED_UPDATE,
READY_TO_UPDATE,
UPDATING,
UNZIPPING,
UP_TO_DATE,
FAIL_TO_UPDATE
};
const static std::string VERSION_ID;
const static std::string MANIFEST_ID;
typedef std::function<int(const std::string& versionA, const std::string& versionB)> VersionCompareHandle;
typedef std::function<bool(const std::string& path, Manifest::Asset asset)> VerifyCallback;
typedef std::function<void(EventAssetsManagerEx *event)> EventCallback;
/** @brief Create function for creating a new AssetsManagerEx
@param manifestUrl The url for the local manifest file
@param storagePath The storage path for downloaded assets
@warning The cached manifest in your storage path have higher priority and will be searched first,
only if it doesn't exist, AssetsManagerEx will use the given manifestUrl.
*/
static AssetsManagerEx* create(const std::string &manifestUrl, const std::string &storagePath);
/** @brief Check out if there is a new version of manifest.
* You may use this method before updating, then let user determine whether
* he wants to update resources.
*/
void checkUpdate();
/** @brief Prepare the update process, this will cleanup download process flags, fill up download units with temporary manifest or remote manifest
*/
void prepareUpdate();
/** @brief Update with the current local manifest.
*/
void update();
/** @brief Reupdate all failed assets under the current AssetsManagerEx context
*/
void downloadFailedAssets();
/** @brief Gets the current update state.
*/
State getState() const;
/** @brief Gets storage path.
*/
const std::string& getStoragePath() const;
/** @brief Function for retrieving the local manifest object
*/
const Manifest* getLocalManifest() const;
/** @brief Load a custom local manifest object, the local manifest must be loaded already.
* You can only manually load local manifest when the update state is UNCHECKED, it will fail once the update process is began.
* This API will do the following things:
* 1. Reset storage path
* 2. Set local storage
* 3. Search for cached manifest and compare with the local manifest
* 4. Init temporary manifest and remote manifest
* If successfully load the given local manifest and inited other manifests, it will return true, otherwise it will return false
* @param localManifest The local manifest object to be set
* @param storagePath The local storage path
*/
bool loadLocalManifest(Manifest* localManifest, const std::string& storagePath);
/** @brief Load a local manifest from url.
* You can only manually load local manifest when the update state is UNCHECKED, it will fail once the update process is began.
* This API will do the following things:
* 1. Reset storage path
* 2. Set local storage
* 3. Search for cached manifest and compare with the local manifest
* 4. Init temporary manifest and remote manifest
* If successfully load the given local manifest and inited other manifests, it will return true, otherwise it will return false
* @param manifestUrl The local manifest url
*/
bool loadLocalManifest(const std::string& manifestUrl);
/** @brief Function for retrieving the remote manifest object
*/
const Manifest* getRemoteManifest() const;
/** @brief Load a custom remote manifest object, the manifest must be loaded already.
* You can only manually load remote manifest when the update state is UNCHECKED and local manifest is already inited, it will fail once the update process is began.
* @param remoteManifest The remote manifest object to be set
*/
bool loadRemoteManifest(Manifest* remoteManifest);
/** @brief Gets whether the current download is resuming previous unfinished job, this will only be available after READY_TO_UPDATE state, under unknown states it will return false by default.
*/
bool isResuming() const {return _downloadResumed;};
/** @brief Gets the total byte size to be downloaded of the update, this will only be available after READY_TO_UPDATE state, under unknown states it will return 0 by default.
*/
double getTotalBytes() const {return _totalSize;};
/** @brief Gets the current downloaded byte size of the update, this will only be available after READY_TO_UPDATE state, under unknown states it will return 0 by default.
*/
double getDownloadedBytes() const {return _totalDownloaded;};
/** @brief Gets the total files count to be downloaded of the update, this will only be available after READY_TO_UPDATE state, under unknown states it will return 0 by default.
*/
int getTotalFiles() const {return _totalToDownload;};
/** @brief Gets the current downloaded files count of the update, this will only be available after READY_TO_UPDATE state, under unknown states it will return 0 by default.
*/
int getDownloadedFiles() const {return _totalToDownload - _totalWaitToDownload;};
/** @brief Function for retrieving the max concurrent task count
*/
const int getMaxConcurrentTask() const {return _maxConcurrentTask;};
/** @brief Function for setting the max concurrent task count
*/
void setMaxConcurrentTask(const int max) {_maxConcurrentTask = max;};
/** @brief Set the handle function for comparing manifests versions
* @param handle The compare function
*/
void setVersionCompareHandle(const VersionCompareHandle& handle) {_versionCompareHandle = handle;};
/** @brief Set the verification function for checking whether downloaded asset is correct, e.g. using md5 verification
* @param callback The verify callback function
*/
void setVerifyCallback(const VerifyCallback& callback) {_verifyCallback = callback;};
/** @brief Set the event callback for receiving update process events
* @param callback The event callback function
*/
void setEventCallback(const EventCallback& callback) {_eventCallback = callback;};
/** @brief Cancel update
*/
void cancelUpdate();
CC_CONSTRUCTOR_ACCESS:
AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath);
AssetsManagerEx(const std::string& manifestUrl, const std::string& storagePath, const VersionCompareHandle& handle);
virtual ~AssetsManagerEx();
protected:
void init(const std::string& manifestUrl, const std::string& storagePath);
std::string basename(const std::string& path) const;
std::string get(const std::string& key) const;
void initManifests();
void prepareLocalManifest();
void setStoragePath(const std::string& storagePath);
void adjustPath(std::string &path);
void dispatchUpdateEvent(EventAssetsManagerEx::EventCode code, const std::string &message = "", const std::string &assetId = "", int curle_code = 0, int curlm_code = 0);
void downloadVersion();
void parseVersion();
void downloadManifest();
void parseManifest();
void startUpdate();
void updateSucceed();
bool decompress(const std::string &filename);
void decompressDownloadedZip(const std::string &customId, const std::string &storagePath);
/** @brief Update a list of assets under the current AssetsManagerEx context
*/
void updateAssets(const DownloadUnits& assets);
/** @brief Retrieve all failed assets during the last update
*/
const DownloadUnits& getFailedAssets() const;
/** @brief Function for destroying the downloaded version file and manifest file
*/
void destroyDownloadedVersion();
/** @brief Download items in queue with max concurrency setting
*/
void queueDowload();
void fileError(const std::string& identifier, const std::string& errorStr, int errorCode = 0, int errorCodeInternal = 0);
void fileSuccess(const std::string &customId, const std::string &storagePath);
/** @brief Call back function for error handling,
the error will then be reported to user's listener registed in addUpdateEventListener
@param error The error object contains ErrorCode, message, asset url, asset key
@warning AssetsManagerEx internal use only
* @js NA
* @lua NA
*/
virtual void onError(const network::DownloadTask& task,
int errorCode,
int errorCodeInternal,
const std::string& errorStr);
/** @brief Call back function for recording downloading percent of the current asset,
the progression will then be reported to user's listener registed in addUpdateProgressEventListener
@param total Total size to download for this asset
@param downloaded Total size already downloaded for this asset
@param url The url of this asset
@param customId The key of this asset
@warning AssetsManagerEx internal use only
* @js NA
* @lua NA
*/
virtual void onProgress(double total, double downloaded, const std::string &url, const std::string &customId);
/** @brief Call back function for success of the current asset
the success event will then be send to user's listener registed in addUpdateEventListener
@param srcUrl The url of this asset
@param customId The key of this asset
@warning AssetsManagerEx internal use only
* @js NA
* @lua NA
*/
virtual void onSuccess(const std::string &srcUrl, const std::string &storagePath, const std::string &customId);
private:
void batchDownload();
// Called when one DownloadUnits finished
void onDownloadUnitsFinished();
//! The event of the current AssetsManagerEx in event dispatcher
std::string _eventName;
//! Reference to the global event dispatcher
// EventDispatcher *_eventDispatcher;
//! Reference to the global file utils
FileUtils *_fileUtils;
//! State of update
State _updateState;
//! Downloader
std::shared_ptr<network::Downloader> _downloader;
//! The reference to the local assets
const std::unordered_map<std::string, Manifest::Asset> *_assets;
//! The path to store successfully downloaded version.
std::string _storagePath;
//! The path to store downloading version.
std::string _tempStoragePath;
//! The local path of cached temporary version file
std::string _tempVersionPath;
//! The local path of cached manifest file
std::string _cacheManifestPath;
//! The local path of cached temporary manifest file
std::string _tempManifestPath;
//! The path of local manifest file
std::string _manifestUrl;
//! Local manifest
Manifest *_localManifest;
//! Local temporary manifest for download resuming
Manifest *_tempManifest;
//! Remote manifest
Manifest *_remoteManifest;
//! Whether user have requested to update
enum class UpdateEntry : char
{
NONE,
CHECK_UPDATE,
DO_UPDATE
};
UpdateEntry _updateEntry;
//! All assets unit to download
DownloadUnits _downloadUnits;
//! All failed units
DownloadUnits _failedUnits;
//! Download queue
std::vector<std::string> _queue;
bool _downloadResumed;
//! Max concurrent task count for downloading
int _maxConcurrentTask;
//! Current concurrent task count
int _currConcurrentTask;
//! Download percent
float _percent;
//! Download percent by file
float _percentByFile;
//! Indicate whether the total size should be enabled
int _totalEnabled;
//! Indicate the number of file whose total size have been collected
int _sizeCollected;
//! Total file size need to be downloaded (sum of all files)
double _totalSize;
//! Total downloaded file size (sum of all downloaded files)
double _totalDownloaded;
//! Downloaded size for each file
std::unordered_map<std::string, double> _downloadedSize;
//! Total number of assets to download
int _totalToDownload;
//! Total number of assets still waiting to be downloaded
int _totalWaitToDownload;
//! Next target percent for saving the manifest file
float _nextSavePoint;
//! Handle function to compare versions between different manifests
VersionCompareHandle _versionCompareHandle;
//! Callback function to verify the downloaded assets
VerifyCallback _verifyCallback;
//! Callback function to dispatch events
EventCallback _eventCallback;
//! Marker for whether the assets manager is inited
bool _inited;
//! Marker for whether the update is canceled
bool _canceled;
//! Downloading task container
std::unordered_map<std::string, std::shared_ptr<const network::DownloadTask>> _downloadingTask;
};
NS_CC_EXT_END
#endif /* defined(__AssetsManagerEx__) */

View File

@@ -0,0 +1,56 @@
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 "CCAsyncTaskPool.h"
NS_CC_BEGIN
AsyncTaskPool* AsyncTaskPool::s_asyncTaskPool = nullptr;
AsyncTaskPool* AsyncTaskPool::getInstance()
{
if (s_asyncTaskPool == nullptr)
{
s_asyncTaskPool = new (std::nothrow) AsyncTaskPool();
}
return s_asyncTaskPool;
}
void AsyncTaskPool::destroyInstance()
{
delete s_asyncTaskPool;
s_asyncTaskPool = nullptr;
}
AsyncTaskPool::AsyncTaskPool()
{
}
AsyncTaskPool::~AsyncTaskPool()
{
}
NS_CC_END

View File

@@ -0,0 +1,221 @@
/****************************************************************************
Copyright (c) 2013-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 __CCSYNC_TASK_POOL_H_
#define __CCSYNC_TASK_POOL_H_
#include "CCPlatformDefine.h"
#include "platform/CCApplication.h"
#include "base/CCScheduler.h"
#include <vector>
#include <queue>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <functional>
#include <stdexcept>
/**
* @addtogroup base
* @{
*/
NS_CC_BEGIN
/**
* @class AsyncTaskPool
* @brief This class allows to perform background operations without having to manipulate threads.
* @js NA
*/
class CC_DLL AsyncTaskPool
{
public:
typedef std::function<void(void*)> TaskCallBack;
enum class TaskType
{
TASK_IO,
TASK_NETWORK,
TASK_OTHER,
TASK_MAX_TYPE,
};
/**
* Returns the shared instance of the async task pool.
*/
static AsyncTaskPool* getInstance();
/**
* Destroys the async task pool.
*/
static void destroyInstance();
/**
* Stop tasks.
*
* @param type Task type you want to stop.
*/
void stopTasks(TaskType type);
/**
* Enqueue a asynchronous task.
*
* @param type task type is io task, network task or others, each type of task has a thread to deal with it.
* @param callback callback when the task is finished. The callback is called in the main thread instead of task thread.
* @param callbackParam parameter used by the callback.
* @param f task can be lambda function.
* @lua NA
*/
template<class F>
inline void enqueue(TaskType type, const TaskCallBack& callback, void* callbackParam, F&& f);
CC_CONSTRUCTOR_ACCESS:
AsyncTaskPool();
~AsyncTaskPool();
protected:
// thread tasks internally used
class ThreadTasks {
struct AsyncTaskCallBack
{
TaskCallBack callback;
void* callbackParam;
};
public:
ThreadTasks()
: _stop(false)
{
_thread = std::thread(
[this]
{
for(;;)
{
std::function<void()> task;
AsyncTaskCallBack callback;
{
std::unique_lock<std::mutex> lock(this->_queueMutex);
this->_condition.wait(lock,
[this]{ return this->_stop || !this->_tasks.empty(); });
if(this->_stop && this->_tasks.empty())
return;
task = std::move(this->_tasks.front());
callback = std::move(this->_taskCallBacks.front());
this->_tasks.pop();
this->_taskCallBacks.pop();
}
task();
Application::getInstance()->getScheduler()->performFunctionInCocosThread([&, callback]{ callback.callback(callback.callbackParam); });
}
}
);
}
~ThreadTasks()
{
{
std::unique_lock<std::mutex> lock(_queueMutex);
_stop = true;
while(_tasks.size())
_tasks.pop();
while (_taskCallBacks.size())
_taskCallBacks.pop();
}
_condition.notify_all();
_thread.join();
}
void clear()
{
std::unique_lock<std::mutex> lock(_queueMutex);
while(_tasks.size())
_tasks.pop();
while (_taskCallBacks.size())
_taskCallBacks.pop();
}
template<class F>
void enqueue(const TaskCallBack& callback, void* callbackParam, F&& f)
{
auto task = f;//std::bind(std::forward<F>(f), std::forward<Args>(args)...);
{
std::unique_lock<std::mutex> lock(_queueMutex);
// don't allow enqueueing after stopping the pool
if(_stop)
{
CC_ASSERT(0 && "already stop");
return;
}
AsyncTaskCallBack taskCallBack;
taskCallBack.callback = callback;
taskCallBack.callbackParam = callbackParam;
_tasks.emplace([task](){ task(); });
_taskCallBacks.emplace(taskCallBack);
}
_condition.notify_one();
}
private:
// need to keep track of thread so we can join them
std::thread _thread;
// the task queue
std::queue< std::function<void()> > _tasks;
std::queue<AsyncTaskCallBack> _taskCallBacks;
// synchronization
std::mutex _queueMutex;
std::condition_variable _condition;
bool _stop;
};
//tasks
ThreadTasks _threadTasks[int(TaskType::TASK_MAX_TYPE)];
static AsyncTaskPool* s_asyncTaskPool;
};
inline void AsyncTaskPool::stopTasks(TaskType type)
{
auto& threadTask = _threadTasks[(int)type];
threadTask.clear();
}
template<class F>
inline void AsyncTaskPool::enqueue(AsyncTaskPool::TaskType type, const TaskCallBack& callback, void* callbackParam, F&& f)
{
auto& threadTask = _threadTasks[(int)type];
threadTask.enqueue(callback, callbackParam, f);
}
NS_CC_END
// end group
/// @}
#endif //__CCSYNC_TASK_POOL_H_

View File

@@ -0,0 +1,79 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 "CCEventAssetsManagerEx.h"
#include "base/ccMacros.h"
#include <functional>
#include "AssetsManagerEx.h"
NS_CC_EXT_BEGIN
EventAssetsManagerEx::EventAssetsManagerEx(const std::string& eventName, cocos2d::extension::AssetsManagerEx *manager, const EventCode &code, const std::string& assetId/* = "" */, const std::string& message/* = "" */, int curle_code/* = CURLE_OK*/, int curlm_code/* = CURLM_OK*/)
: _code(code)
, _manager(manager)
, _message(message)
, _assetId(assetId)
, _curle_code(curle_code)
, _curlm_code(curlm_code)
{
}
bool EventAssetsManagerEx::isResuming() const
{
return _manager->isResuming();
}
float EventAssetsManagerEx::getPercent() const
{
return _manager->getDownloadedBytes() / _manager->getTotalBytes();
}
float EventAssetsManagerEx::getPercentByFile() const
{
return (float)(_manager->getDownloadedFiles()) / _manager->getTotalFiles();
}
double EventAssetsManagerEx::getDownloadedBytes() const
{
return _manager->getDownloadedBytes();
}
double EventAssetsManagerEx::getTotalBytes() const
{
return _manager->getTotalBytes();
}
int EventAssetsManagerEx::getDownloadedFiles() const
{
return _manager->getDownloadedFiles();
}
int EventAssetsManagerEx::getTotalFiles() const
{
return _manager->getTotalFiles();
}
NS_CC_EXT_END

View File

@@ -0,0 +1,105 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 __cocos2d_libs__CCEventAssetsManagerEx__
#define __cocos2d_libs__CCEventAssetsManagerEx__
#include <string>
#include "base/CCRef.h"
#include "extensions/ExtensionMacros.h"
#include "extensions/ExtensionExport.h"
NS_CC_EXT_BEGIN
class AssetsManagerEx;
class CC_EX_DLL EventAssetsManagerEx : public cocos2d::Ref
{
public:
//! Update events code
enum class EventCode
{
ERROR_NO_LOCAL_MANIFEST,
ERROR_DOWNLOAD_MANIFEST,
ERROR_PARSE_MANIFEST,
NEW_VERSION_FOUND,
ALREADY_UP_TO_DATE,
UPDATE_PROGRESSION,
ASSET_UPDATED,
ERROR_UPDATING,
UPDATE_FINISHED,
UPDATE_FAILED,
ERROR_DECOMPRESS
};
inline EventCode getEventCode() const { return _code; };
inline int getCURLECode() const { return _curle_code; };
inline int getCURLMCode() const { return _curlm_code; };
inline std::string getMessage() const { return _message; };
inline std::string getAssetId() const { return _assetId; };
inline cocos2d::extension::AssetsManagerEx *getAssetsManagerEx() const { return _manager; };
bool isResuming() const;
float getPercent() const;
float getPercentByFile() const;
double getDownloadedBytes() const;
double getTotalBytes() const;
int getDownloadedFiles() const;
int getTotalFiles() const;
public:
/** Constructor */
EventAssetsManagerEx(const std::string& eventName, cocos2d::extension::AssetsManagerEx *manager, const EventCode &code, const std::string& assetId = "", const std::string& message = "", int curle_code = 0, int curlm_code = 0);
private:
virtual ~EventAssetsManagerEx() {}
EventCode _code;
cocos2d::extension::AssetsManagerEx *_manager;
std::string _message;
std::string _assetId;
int _curle_code;
int _curlm_code;
};
NS_CC_EXT_END
#endif /* defined(__cocos2d_libs__CCEventAssetsManagerEx__) */

View File

@@ -0,0 +1,637 @@
/****************************************************************************
Copyright (c) 2014 cocos2d-x.org
Copyright (c) 2015-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 "Manifest.h"
#include "json/prettywriter.h"
#include "json/stringbuffer.h"
#include <fstream>
#include <stdio.h>
#define KEY_VERSION "version"
#define KEY_PACKAGE_URL "packageUrl"
#define KEY_MANIFEST_URL "remoteManifestUrl"
#define KEY_VERSION_URL "remoteVersionUrl"
#define KEY_GROUP_VERSIONS "groupVersions"
#define KEY_ENGINE_VERSION "engineVersion"
#define KEY_UPDATING "updating"
#define KEY_ASSETS "assets"
#define KEY_COMPRESSED_FILES "compressedFiles"
#define KEY_SEARCH_PATHS "searchPaths"
#define KEY_PATH "path"
#define KEY_MD5 "md5"
#define KEY_GROUP "group"
#define KEY_COMPRESSED "compressed"
#define KEY_SIZE "size"
#define KEY_COMPRESSED_FILE "compressedFile"
#define KEY_DOWNLOAD_STATE "downloadState"
NS_CC_EXT_BEGIN
static int cmpVersion(const std::string& v1, const std::string& v2)
{
int i;
int oct_v1[4] = {0}, oct_v2[4] = {0};
int filled1 = std::sscanf(v1.c_str(), "%d.%d.%d.%d", &oct_v1[0], &oct_v1[1], &oct_v1[2], &oct_v1[3]);
int filled2 = std::sscanf(v2.c_str(), "%d.%d.%d.%d", &oct_v2[0], &oct_v2[1], &oct_v2[2], &oct_v2[3]);
if (filled1 == 0 || filled2 == 0)
{
return strcmp(v1.c_str(), v2.c_str());
}
for (i = 0; i < 4; i++)
{
if (oct_v1[i] > oct_v2[i])
return 1;
else if (oct_v1[i] < oct_v2[i])
return -1;
}
return 0;
}
Manifest::Manifest(const std::string& manifestUrl/* = ""*/)
: _versionLoaded(false)
, _loaded(false)
, _updating(false)
, _manifestRoot("")
, _remoteManifestUrl("")
, _remoteVersionUrl("")
, _version("")
, _engineVer("")
{
// Init variables
_fileUtils = FileUtils::getInstance();
if (manifestUrl.size() > 0)
parseFile(manifestUrl);
}
Manifest::Manifest(const std::string& content, const std::string& manifestRoot)
: _versionLoaded(false)
, _loaded(false)
, _updating(false)
, _manifestRoot("")
, _remoteManifestUrl("")
, _remoteVersionUrl("")
, _version("")
, _engineVer("")
{
// Init variables
_fileUtils = FileUtils::getInstance();
if (content.size() > 0)
parseJSONString(content, manifestRoot);
}
void Manifest::loadJson(const std::string& url)
{
clear();
std::string content;
if (_fileUtils->isFileExist(url))
{
// Load file content
content = _fileUtils->getStringFromFile(url);
if (content.size() == 0)
{
CCLOG("Fail to retrieve local file content: %s\n", url.c_str());
}
else
{
loadJsonFromString(content);
}
}
}
void Manifest::loadJsonFromString(const std::string& content)
{
if (content.size() == 0)
{
CCLOG("Fail to parse empty json content.");
}
else
{
// Parse file with rapid json
_json.Parse<0>(content.c_str());
// Print error
if (_json.HasParseError()) {
size_t offset = _json.GetErrorOffset();
if (offset > 0)
offset--;
std::string errorSnippet = content.substr(offset, 10);
CCLOG("File parse error %d at <%s>\n", _json.GetParseError(), errorSnippet.c_str());
}
}
}
void Manifest::parseVersion(const std::string& versionUrl)
{
loadJson(versionUrl);
if (_json.IsObject())
{
loadVersion(_json);
}
}
void Manifest::parseFile(const std::string& manifestUrl)
{
loadJson(manifestUrl);
if (!_json.HasParseError() && _json.IsObject())
{
// Register the local manifest root
size_t found = manifestUrl.find_last_of("/\\");
if (found != std::string::npos)
{
_manifestRoot = manifestUrl.substr(0, found+1);
}
loadManifest(_json);
}
}
void Manifest::parseJSONString(const std::string& content, const std::string& manifestRoot)
{
loadJsonFromString(content);
if (!_json.HasParseError() && _json.IsObject())
{
// Register the local manifest root
_manifestRoot = manifestRoot;
loadManifest(_json);
}
}
bool Manifest::isVersionLoaded() const
{
return _versionLoaded;
}
bool Manifest::isLoaded() const
{
return _loaded;
}
void Manifest::setUpdating(bool updating)
{
if (_loaded && _json.IsObject())
{
if (_json.HasMember(KEY_UPDATING) && _json[KEY_UPDATING].IsBool())
{
_json[KEY_UPDATING].SetBool(updating);
}
else
{
_json.AddMember<bool>(KEY_UPDATING, updating, _json.GetAllocator());
}
_updating = updating;
}
}
bool Manifest::versionEquals(const Manifest *b) const
{
// Check manifest version
if (_version != b->getVersion())
{
return false;
}
// Check group versions
else
{
std::vector<std::string> bGroups = b->getGroups();
std::unordered_map<std::string, std::string> bGroupVer = b->getGroupVerions();
// Check group size
if (bGroups.size() != _groups.size())
return false;
// Check groups version
for (unsigned int i = 0; i < _groups.size(); ++i) {
std::string gid =_groups[i];
// Check group name
if (gid != bGroups[i])
return false;
// Check group version
if (_groupVer.at(gid) != bGroupVer.at(gid))
return false;
}
}
return true;
}
bool Manifest::versionGreaterOrEquals(const Manifest *b, const std::function<int(const std::string& versionA, const std::string& versionB)>& handle) const
{
std::string localVersion = getVersion();
std::string bVersion = b->getVersion();
bool greater;
if (handle)
{
greater = handle(localVersion, bVersion) >= 0;
}
else
{
greater = cmpVersion(localVersion, bVersion) >= 0;
}
return greater;
}
bool Manifest::versionGreater(const Manifest *b, const std::function<int(const std::string& versionA, const std::string& versionB)>& handle) const
{
std::string localVersion = getVersion();
std::string bVersion = b->getVersion();
bool greater;
if (handle)
{
greater = handle(localVersion, bVersion) > 0;
}
else
{
greater = cmpVersion(localVersion, bVersion) > 0;
}
return greater;
}
std::unordered_map<std::string, Manifest::AssetDiff> Manifest::genDiff(const Manifest *b) const
{
std::unordered_map<std::string, AssetDiff> diff_map;
const std::unordered_map<std::string, Asset> &bAssets = b->getAssets();
std::string key;
Asset valueA;
Asset valueB;
std::unordered_map<std::string, Asset>::const_iterator valueIt, it;
for (it = _assets.begin(); it != _assets.end(); ++it)
{
key = it->first;
valueA = it->second;
// Deleted
valueIt = bAssets.find(key);
if (valueIt == bAssets.cend()) {
AssetDiff diff;
diff.asset = valueA;
diff.type = DiffType::DELETED;
diff_map.emplace(key, diff);
continue;
}
// Modified
valueB = valueIt->second;
if (valueA.md5 != valueB.md5) {
AssetDiff diff;
diff.asset = valueB;
diff.type = DiffType::MODIFIED;
diff_map.emplace(key, diff);
}
}
for (it = bAssets.begin(); it != bAssets.end(); ++it)
{
key = it->first;
valueB = it->second;
// Added
valueIt = _assets.find(key);
if (valueIt == _assets.cend()) {
AssetDiff diff;
diff.asset = valueB;
diff.type = DiffType::ADDED;
diff_map.emplace(key, diff);
}
}
return diff_map;
}
void Manifest::genResumeAssetsList(DownloadUnits *units) const
{
for (auto it = _assets.begin(); it != _assets.end(); ++it)
{
Asset asset = it->second;
if (asset.downloadState != DownloadState::SUCCESSED && asset.downloadState != DownloadState::UNMARKED)
{
DownloadUnit unit;
unit.customId = it->first;
unit.srcUrl = _packageUrl + asset.path;
unit.storagePath = _manifestRoot + asset.path;
unit.size = asset.size;
units->emplace(unit.customId, unit);
}
}
}
std::vector<std::string> Manifest::getSearchPaths() const
{
std::vector<std::string> searchPaths;
searchPaths.push_back(_manifestRoot);
for (int i = (int)_searchPaths.size()-1; i >= 0; i--)
{
std::string path = _searchPaths[i];
if (path.size() > 0 && path[path.size() - 1] != '/')
path.append("/");
path = _manifestRoot + path;
searchPaths.push_back(path);
}
return searchPaths;
}
void Manifest::prependSearchPaths()
{
std::vector<std::string> searchPaths = FileUtils::getInstance()->getSearchPaths();
std::vector<std::string>::iterator iter = searchPaths.begin();
bool needChangeSearchPaths = false;
if (std::find(searchPaths.begin(), searchPaths.end(), _manifestRoot) == searchPaths.end())
{
searchPaths.insert(iter, _manifestRoot);
needChangeSearchPaths = true;
}
for (int i = (int)_searchPaths.size()-1; i >= 0; i--)
{
std::string path = _searchPaths[i];
if (path.size() > 0 && path[path.size() - 1] != '/')
path.append("/");
path = _manifestRoot + path;
iter = searchPaths.begin();
searchPaths.insert(iter, path);
needChangeSearchPaths = true;
}
if (needChangeSearchPaths)
{
FileUtils::getInstance()->setSearchPaths(searchPaths);
}
}
const std::string& Manifest::getPackageUrl() const
{
return _packageUrl;
}
const std::string& Manifest::getManifestFileUrl() const
{
return _remoteManifestUrl;
}
const std::string& Manifest::getVersionFileUrl() const
{
return _remoteVersionUrl;
}
const std::string& Manifest::getVersion() const
{
return _version;
}
const std::vector<std::string>& Manifest::getGroups() const
{
return _groups;
}
const std::unordered_map<std::string, std::string>& Manifest::getGroupVerions() const
{
return _groupVer;
}
const std::string& Manifest::getGroupVersion(const std::string &group) const
{
return _groupVer.at(group);
}
const std::unordered_map<std::string, Manifest::Asset>& Manifest::getAssets() const
{
return _assets;
}
void Manifest::setAssetDownloadState(const std::string &key, const Manifest::DownloadState &state)
{
auto valueIt = _assets.find(key);
if (valueIt != _assets.end())
{
valueIt->second.downloadState = state;
// Update json object
if(_json.IsObject())
{
if ( _json.HasMember(KEY_ASSETS) )
{
rapidjson::Value &assets = _json[KEY_ASSETS];
if (assets.IsObject())
{
if (assets.HasMember(key.c_str()))
{
rapidjson::Value &entry = assets[key.c_str()];
if (entry.HasMember(KEY_DOWNLOAD_STATE) && entry[KEY_DOWNLOAD_STATE].IsInt())
{
entry[KEY_DOWNLOAD_STATE].SetInt((int) state);
}
else
{
entry.AddMember<int>(KEY_DOWNLOAD_STATE, (int)state, _json.GetAllocator());
}
}
}
}
}
}
}
void Manifest::clear()
{
if (_versionLoaded || _loaded)
{
_groups.clear();
_groupVer.clear();
_remoteManifestUrl = "";
_remoteVersionUrl = "";
_version = "";
_engineVer = "";
_versionLoaded = false;
}
if (_loaded)
{
_assets.clear();
_searchPaths.clear();
_loaded = false;
}
}
Manifest::Asset Manifest::parseAsset(const std::string &path, const rapidjson::Value &json)
{
Asset asset;
asset.path = path;
if ( json.HasMember(KEY_MD5) && json[KEY_MD5].IsString() )
{
asset.md5 = json[KEY_MD5].GetString();
}
else asset.md5 = "";
if ( json.HasMember(KEY_PATH) && json[KEY_PATH].IsString() )
{
asset.path = json[KEY_PATH].GetString();
}
if ( json.HasMember(KEY_COMPRESSED) && json[KEY_COMPRESSED].IsBool() )
{
asset.compressed = json[KEY_COMPRESSED].GetBool();
}
else asset.compressed = false;
if ( json.HasMember(KEY_SIZE) && json[KEY_SIZE].IsInt() )
{
asset.size = json[KEY_SIZE].GetInt();
}
else asset.size = 0;
if ( json.HasMember(KEY_DOWNLOAD_STATE) && json[KEY_DOWNLOAD_STATE].IsInt() )
{
asset.downloadState = (json[KEY_DOWNLOAD_STATE].GetInt());
}
else asset.downloadState = DownloadState::UNMARKED;
return asset;
}
void Manifest::loadVersion(const rapidjson::Document &json)
{
// Retrieve remote manifest url
if ( json.HasMember(KEY_MANIFEST_URL) && json[KEY_MANIFEST_URL].IsString() )
{
_remoteManifestUrl = json[KEY_MANIFEST_URL].GetString();
}
// Retrieve remote version url
if ( json.HasMember(KEY_VERSION_URL) && json[KEY_VERSION_URL].IsString() )
{
_remoteVersionUrl = json[KEY_VERSION_URL].GetString();
}
// Retrieve local version
if ( json.HasMember(KEY_VERSION) && json[KEY_VERSION].IsString() )
{
_version = json[KEY_VERSION].GetString();
}
// Retrieve local group version
if ( json.HasMember(KEY_GROUP_VERSIONS) )
{
const rapidjson::Value& groupVers = json[KEY_GROUP_VERSIONS];
if (groupVers.IsObject())
{
for (rapidjson::Value::ConstMemberIterator itr = groupVers.MemberBegin(); itr != groupVers.MemberEnd(); ++itr)
{
std::string group = itr->name.GetString();
std::string version = "0";
if (itr->value.IsString())
{
version = itr->value.GetString();
}
_groups.push_back(group);
_groupVer.emplace(group, version);
}
}
}
// Retrieve local engine version
if ( json.HasMember(KEY_ENGINE_VERSION) && json[KEY_ENGINE_VERSION].IsString() )
{
_engineVer = json[KEY_ENGINE_VERSION].GetString();
}
// Retrieve updating flag
if ( json.HasMember(KEY_UPDATING) && json[KEY_UPDATING].IsBool() )
{
_updating = json[KEY_UPDATING].GetBool();
}
_versionLoaded = true;
}
void Manifest::loadManifest(const rapidjson::Document &json)
{
loadVersion(json);
// Retrieve package url
if ( json.HasMember(KEY_PACKAGE_URL) && json[KEY_PACKAGE_URL].IsString() )
{
_packageUrl = json[KEY_PACKAGE_URL].GetString();
// Append automatically "/"
if (_packageUrl.size() > 0 && _packageUrl[_packageUrl.size() - 1] != '/')
{
_packageUrl.append("/");
}
}
// Retrieve all assets
if ( json.HasMember(KEY_ASSETS) )
{
const rapidjson::Value& assets = json[KEY_ASSETS];
if (assets.IsObject())
{
for (rapidjson::Value::ConstMemberIterator itr = assets.MemberBegin(); itr != assets.MemberEnd(); ++itr)
{
std::string key = itr->name.GetString();
Asset asset = parseAsset(key, itr->value);
_assets.emplace(key, asset);
}
}
}
// Retrieve all search paths
if ( json.HasMember(KEY_SEARCH_PATHS) )
{
const rapidjson::Value& paths = json[KEY_SEARCH_PATHS];
if (paths.IsArray())
{
for (rapidjson::SizeType i = 0; i < paths.Size(); ++i)
{
if (paths[i].IsString()) {
_searchPaths.push_back(paths[i].GetString());
}
}
}
}
_loaded = true;
}
void Manifest::saveToFile(const std::string &filepath)
{
rapidjson::StringBuffer buffer;
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
_json.Accept(writer);
std::ofstream output(FileUtils::getInstance()->getSuitableFOpen(filepath), std::ofstream::out);
if(!output.bad())
output << buffer.GetString() << std::endl;
}
NS_CC_EXT_END

View File

@@ -0,0 +1,290 @@
/****************************************************************************
Copyright (c) 2013 cocos2d-x.org
Copyright (c) 2014-2016 Chukong Technologies Inc.
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
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 __Manifest__
#define __Manifest__
#include <string>
#include <unordered_map>
#include <vector>
#include "extensions/ExtensionMacros.h"
#include "extensions/ExtensionExport.h"
#include "network/CCDownloader.h"
#include "platform/CCFileUtils.h"
#include "json/document-wrapper.h"
NS_CC_EXT_BEGIN
struct DownloadUnit
{
std::string srcUrl;
std::string storagePath;
std::string customId;
float size;
};
struct ManifestAsset {
std::string md5;
std::string path;
bool compressed;
float size;
int downloadState;
};
typedef std::unordered_map<std::string, DownloadUnit> DownloadUnits;
class CC_EX_DLL Manifest : public Ref
{
public:
friend class AssetsManagerEx;
//! The type of difference
enum class DiffType {
ADDED,
DELETED,
MODIFIED
};
enum DownloadState {
UNSTARTED,
DOWNLOADING,
SUCCESSED,
UNMARKED
};
//! Asset object
typedef ManifestAsset Asset;
//! Object indicate the difference between two Assets
struct AssetDiff {
Asset asset;
DiffType type;
};
/** @brief Check whether the version informations have been fully loaded
*/
bool isVersionLoaded() const;
/** @brief Check whether the manifest have been fully loaded
*/
bool isLoaded() const;
/** @brief Gets remote package url.
*/
const std::string& getPackageUrl() const;
/** @brief Gets remote manifest file url.
*/
const std::string& getManifestFileUrl() const;
/** @brief Gets remote version file url.
*/
const std::string& getVersionFileUrl() const;
/** @brief Gets manifest version.
*/
const std::string& getVersion() const;
/** @brief Get the search paths list related to the Manifest.
*/
std::vector<std::string> getSearchPaths() const;
/** @brief Get the manifest root path, normally it should also be the local storage path.
*/
const std::string& getManifestRoot() const { return _manifestRoot; };
/** @brief Constructor for Manifest class, create manifest by parsing a json file
* @param manifestUrl Url of the local manifest
*/
Manifest(const std::string& manifestUrl = "");
/** @brief Constructor for Manifest class, create manifest by parsing a json string
* @param content Json string content
* @param manifestRoot The root path of the manifest file (It should be local path, so that we can find assets path relative to the root path)
*/
Manifest(const std::string& content, const std::string& manifestRoot);
/** @brief Parse the manifest file information into this manifest
* @param manifestUrl Url of the local manifest
*/
void parseFile(const std::string& manifestUrl);
/** @brief Parse the manifest from json string into this manifest
* @param content Json string content
* @param manifestRoot The root path of the manifest file (It should be local path, so that we can find assets path relative to the root path)
*/
void parseJSONString(const std::string& content, const std::string& manifestRoot);
/** @brief Get whether the manifest is being updating
* @return Updating or not
*/
bool isUpdating() const { return _updating; };
/** @brief Set whether the manifest is being updating
* @param updating Updating or not
*/
void setUpdating(bool updating);
protected:
/** @brief Load the json file into local json object
* @param url Url of the json file
*/
void loadJson(const std::string& url);
/** @brief Load the json from a string into local json object
* @param content The json content string
*/
void loadJsonFromString(const std::string& content);
/** @brief Parse the version file information into this manifest
* @param versionUrl Url of the local version file
*/
void parseVersion(const std::string& versionUrl);
/** @brief Check whether the version of this manifest equals to another.
* @param b The other manifest
* @return Equal or not
*/
bool versionEquals(const Manifest *b) const;
/** @brief Check whether the version of this manifest is greater or equals than another.
* @param b The other manifest
* @param [handle] Customized comparasion handle function
* @return Greater or not
*/
bool versionGreaterOrEquals(const Manifest *b, const std::function<int(const std::string& versionA, const std::string& versionB)>& handle) const;
/** @brief Check whether the version of this manifest is greater or equals than another.
* @param b The other manifest
* @param [handle] Customized comparasion handle function
* @return Greater or not
*/
bool versionGreater(const Manifest *b, const std::function<int(const std::string& versionA, const std::string& versionB)>& handle) const;
/** @brief Generate difference between this Manifest and another.
* @param b The other manifest
*/
std::unordered_map<std::string, AssetDiff> genDiff(const Manifest *b) const;
/** @brief Generate resuming download assets list
* @param units The download units reference to be modified by the generation result
*/
void genResumeAssetsList(DownloadUnits *units) const;
/** @brief Prepend all search paths to the FileUtils.
*/
void prependSearchPaths();
void loadVersion(const rapidjson::Document &json);
void loadManifest(const rapidjson::Document &json);
void saveToFile(const std::string &filepath);
Asset parseAsset(const std::string &path, const rapidjson::Value &json);
void clear();
/** @brief Gets all groups.
*/
const std::vector<std::string>& getGroups() const;
/** @brief Gets all groups version.
*/
const std::unordered_map<std::string, std::string>& getGroupVerions() const;
/** @brief Gets version for the given group.
* @param group Key of the requested group
*/
const std::string& getGroupVersion(const std::string &group) const;
/**
* @brief Gets assets.
* @lua NA
*/
const std::unordered_map<std::string, Asset>& getAssets() const;
/** @brief Set the download state for an asset
* @param key Key of the asset to set
* @param state The current download state of the asset
*/
void setAssetDownloadState(const std::string &key, const DownloadState &state);
void setManifestRoot(const std::string &root) {_manifestRoot = root;};
private:
//! Indicate whether the version informations have been fully loaded
bool _versionLoaded;
//! Indicate whether the manifest have been fully loaded
bool _loaded;
//! Indicate whether the manifest is updating and can be resumed in the future
bool _updating;
//! Reference to the global file utils
FileUtils *_fileUtils;
//! The local manifest root
std::string _manifestRoot;
//! The remote package url
std::string _packageUrl;
//! The remote path of manifest file
std::string _remoteManifestUrl;
//! The remote path of version file [Optional]
std::string _remoteVersionUrl;
//! The version of local manifest
std::string _version;
//! All groups exist in manifest [Optional]
std::vector<std::string> _groups;
//! The versions of all local group [Optional]
std::unordered_map<std::string, std::string> _groupVer;
//! The version of local engine
std::string _engineVer;
//! Full assets list
std::unordered_map<std::string, Asset> _assets;
//! All search paths
std::vector<std::string> _searchPaths;
rapidjson::Document _json;
};
NS_CC_EXT_END
#endif /* defined(__Manifest__) */