// // AniResourceUtilities.cpp // SteveMaggieCpp // // Created by Katarzyna Kalinowska-Górska on 23.06.2017. // // #include #include "AniResourceUtilities.h" #include "AniJSONParseUtils.h" #include "AniValueStorage.h" //#include "ResourceDownloader_cpp.h" #include "AniResourcesConfig.h" #define RESOURCES_LOAD_FROM_ASSETS //#define FORCE_REDOWNLOAD_RESOURCES std::string AniResourceUtilities::getDownloadedResourcesPath(bool deviceDependentFiles) { #ifdef RESOURCES_LOAD_FROM_ASSETS return ""; #endif // std::string resDownloadDir = ResourceDownloader_getResourceDownloadDirectoryPath(); // // if(deviceDependentFiles){ // return resDownloadDir + "/" + this->getDeviceSpecificFolderName(); // } // // return resDownloadDir + "/" + AniResourcesConfig::UNIVERSAL_RESOURCES_FOLDER_NAME; } std::string AniResourceUtilities::getFullPathForDownloadedFile(const std::string& path, bool isDeviceDependent) { #ifdef RESOURCES_LOAD_FROM_ASSETS return path; #endif // std::string resDownloadDir = this->getDownloadedResourcesPath(isDeviceDependent); // return resDownloadDir + "/" + path; } std::vector< std::string> AniResourceUtilities::getFullPathsForDownloadedFiles(const std::vector< std::string>& paths, bool areDeviceDependent) { std::vector< std::string> fullPaths; fullPaths.reserve(paths.size()); for(const auto& path : paths){ fullPaths.push_back(this->getFullPathForDownloadedFile(path, areDeviceDependent)); } return fullPaths; } /* std::vector AniResourceUtilities::getFullPathsForDownloadedFiles(const std::vector& paths, bool areDeviceDependent) { std::vector fullPaths; fullPaths.reserve(paths.size()); for(const auto& path : paths){ fullPaths.push_back(this->getFullPathForDownloadedFile(path, areDeviceDependent)); } return fullPaths; } */ std::vector AniResourceUtilities::extractAllImagePathsFromJSONFile(std::string layoutJSONFilePath, std::string givenResourceFolderPath, std::string givenAltResourceFolderPath, std::string givenObjLayoutsFolderPath) { std::string fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(this->getFullPathForDownloadedFile(layoutJSONFilePath)); auto layoutString = cocos2d::FileUtils::getInstance()->getStringFromFile(fullPath); return AniResourceUtilities::extractAllImagePathsFromLayoutString(layoutString, givenResourceFolderPath, givenAltResourceFolderPath, givenObjLayoutsFolderPath); } std::vector AniResourceUtilities::extractAllImagePathsFromLayoutString(std::string layoutJSONString, std::string givenResourceFolderPath, std::string givenAltResourceFolderPath, std::string givenObjLayoutsFolderPath) { rapidjson::Document document; document.Parse(layoutJSONString.c_str()); std::string resFolderPath = givenResourceFolderPath, altResFolderPath = givenAltResourceFolderPath, objLayoutsFolderPath = givenObjLayoutsFolderPath; if(AniJSONParseUtils::hasMemberObject(document, "resFolder")){ const auto& resFolder = document["resFolder"]; if(AniJSONParseUtils::hasMemberString(resFolder, "path")){ resFolderPath = this->getFullPathForDownloadedFile(resFolder["path"].GetString()); } if(AniJSONParseUtils::hasMemberString(resFolder, "alternativePath")){ altResFolderPath = this->getFullPathForDownloadedFile(resFolder["alternativePath"].GetString()); } if(AniJSONParseUtils::hasMemberString(resFolder, "objectLayoutsPath")){ objLayoutsFolderPath = this->getFullPathForDownloadedFile(resFolder["objectLayoutsPath"].GetString()); } } return AniResourceUtilities::extractAllImagePaths(document, resFolderPath, altResFolderPath, objLayoutsFolderPath); } //!! TODO //"loadObjectFromFile" : "buttons/horizontalButtonPanel.obl", std::vector AniResourceUtilities::extractAllImagePaths(const rapidjson::Value& value, std::string resourceFolderPath, std::string altResourceFolderPath, std::string objLayoutsFolderPath) { std::vector allImagePaths; if(value.IsArray()){ for(const auto& element : value.GetArray()){ if(element.IsObject() || element.IsArray()){ auto imagePaths = this->extractAllImagePaths(element, resourceFolderPath, altResourceFolderPath, objLayoutsFolderPath); allImagePaths.insert(allImagePaths.end(), imagePaths.begin(), imagePaths.end()); } } } else if(value.IsObject()){ std::string resourceFolderString = resourceFolderPath; if(AniJSONParseUtils::checkMemberBool(value, "useAlternativePath", true)){ resourceFolderString = altResourceFolderPath; } for(const auto& pair : value.GetObject()){ std::string key = pair.name.GetString(); if(key.find("imagePath") != std::string::npos || key.find("ImagePath") != std::string::npos){ if(pair.value.IsString()){ allImagePaths.push_back(resourceFolderString + pair.value.GetString()); } else if(pair.value.IsArray()){ for(const auto& element : pair.value.GetArray()){ if(element.IsString()){ allImagePaths.push_back(resourceFolderString + element.GetString()); } } } } else if(key.find("filePath") != std::string::npos || key.find("FilePath") != std::string::npos){ if(pair.value.IsString()){ auto imagePaths = this->extractAllImagePathsFromJSONFile(resourceFolderString + pair.value.GetString()); allImagePaths.insert(allImagePaths.end(), imagePaths.begin(), imagePaths.end()); // cocos2d::log("extracted %d image paths from file %s", (int)imagePaths.size(), pair.value.GetString()); } } else if(key.find("loadObjectFromFile") != std::string::npos){ if(pair.value.IsString()){ auto filePath = objLayoutsFolderPath + pair.value.GetString(); auto imagePaths = this->extractAllImagePathsFromJSONFile(filePath, resourceFolderPath, altResourceFolderPath, objLayoutsFolderPath); allImagePaths.insert(allImagePaths.end(), imagePaths.begin(), imagePaths.end()); // cocos2d::log("extracted %d image paths from file %s", (int)imagePaths.size(), filePath.c_str()); } } else if(pair.value.IsObject() || pair.value.IsArray()){ auto imagePaths = this->extractAllImagePaths(pair.value, resourceFolderPath, altResourceFolderPath, objLayoutsFolderPath); allImagePaths.insert(allImagePaths.end(), imagePaths.begin(), imagePaths.end()); } } } // cocos2d::log("extractAllImagePaths: IN TOTAL %d IMAGE PATHS", (int)allImagePaths.size()); return allImagePaths; } void AniResourceUtilities::preloadResourcesForFile(std::string layoutJSONFilePath, std::function)> callback) { //TODO fail callback? auto allImageFiles = extractAllImagePathsFromJSONFile(layoutJSONFilePath); if(allImageFiles.size() == 0){ callback(allImageFiles); } else { preloadFiles(allImageFiles, callback); } } void AniResourceUtilities::preloadFiles(std::vector files, std::function)> callback){ auto textureCache = cocos2d::Director::getInstance()->getTextureCache(); float counterF = files.size(); AniSimpleValue counter(counterF); auto counterKey = AniValueStorage::getInstance().storeAniSimpleValue(counter); auto callbackKey = AniValueStorage::getInstance().storeFunction(std::bind(callback, files)); for(auto imagePath : files){ // cocos2d::log("loading texture: %s", imagePath.c_str()); textureCache->addImageAsync(imagePath, std::bind([&](cocos2d::Texture2D* loadedTexture, std::string pCounterKey, std::string pCallbackKey){ // if(loadedTexture){ // cocos2d::log("texture loaded successfully: %s", imagePath.c_str()); // } else { // cocos2d::log("failed to load texture: %s", imagePath.c_str()); // } // AniSimpleValue* counter = AniValueStorage::getInstance().getStoredAniSimpleValue(pCounterKey); counter->setNumberValue(counter->getNumberValue()-1); if(counter->getNumberValue() <= 0){ AniValueStorage::getInstance().removeStoredValue(pCounterKey); AniValueStorage::getInstance().runAndRemoveStoredFunction(pCallbackKey); } }, std::placeholders::_1, counterKey, callbackKey)); } }