|
|
@@ -23,29 +23,37 @@
|
|
|
|
|
|
#include <Atomic/IO/Log.h>
|
|
|
#include <Atomic/IO/FileSystem.h>
|
|
|
+#include <Atomic/Resource/JSONFile.h>
|
|
|
|
|
|
#include "../Subprocess/SubprocessSystem.h"
|
|
|
#include "../Project/Project.h"
|
|
|
#include "../ToolEnvironment.h"
|
|
|
+#include "../Assets/Asset.h"
|
|
|
+#include "../Assets/AssetDatabase.h"
|
|
|
|
|
|
#include "BuildSystem.h"
|
|
|
#include "BuildEvents.h"
|
|
|
#include "BuildBase.h"
|
|
|
#include "ResourcePackager.h"
|
|
|
+#include "AssetBuildConfig.h"
|
|
|
|
|
|
namespace ToolCore
|
|
|
{
|
|
|
|
|
|
BuildBase::BuildBase(Context * context, Project* project, PlatformID platform) : Object(context),
|
|
|
platformID_(platform),
|
|
|
+ project_(project),
|
|
|
containsMDL_(false),
|
|
|
- buildFailed_(false)
|
|
|
+ buildFailed_(false),
|
|
|
+ assetBuildTag_(String::EMPTY),
|
|
|
+ fileIncludedResourcesLog_(nullptr)
|
|
|
{
|
|
|
if (UseResourcePackager())
|
|
|
resourcePackager_ = new ResourcePackager(context, this);
|
|
|
|
|
|
- project_ = project;
|
|
|
+ fileIncludedResourcesLog_ = new File(context_, "BuildIncludedResources.log", Atomic::FILE_WRITE);
|
|
|
|
|
|
+ ReadAssetBuildConfig();
|
|
|
}
|
|
|
|
|
|
BuildBase::~BuildBase()
|
|
|
@@ -54,6 +62,9 @@ BuildBase::~BuildBase()
|
|
|
{
|
|
|
delete resourceEntries_[i];
|
|
|
}
|
|
|
+
|
|
|
+ fileIncludedResourcesLog_->Close();
|
|
|
+ delete fileIncludedResourcesLog_;
|
|
|
}
|
|
|
|
|
|
#ifdef ATOMIC_PLATFORM_WINDOWS
|
|
|
@@ -277,10 +288,8 @@ void BuildBase::FailBuild(const String& message)
|
|
|
|
|
|
BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
|
|
|
buildSystem->BuildComplete(platformID_, buildPath_, false, message);
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
void BuildBase::HandleSubprocessOutputEvent(StringHash eventType, VariantMap& eventData)
|
|
|
{
|
|
|
// E_SUBPROCESSOUTPUT
|
|
|
@@ -307,67 +316,279 @@ String BuildBase::GetSettingsDirectory()
|
|
|
return project_->GetProjectPath() + "/Settings";
|
|
|
}
|
|
|
|
|
|
-void BuildBase::ScanResourceDirectory(const String& resourceDir)
|
|
|
+void BuildBase::BuildDefaultResourceEntries()
|
|
|
{
|
|
|
- Vector<String> fileNames;
|
|
|
+ String buildLogOutput(String::EMPTY);
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < resourceDirs_.Size(); i++)
|
|
|
+ {
|
|
|
+ String resourceDir = resourceDirs_[i];
|
|
|
+ fileIncludedResourcesLog_->WriteLine("\nBuildBase::BuildDefaultResourceEntries - Default resources being included from: " + resourceDir);
|
|
|
+
|
|
|
+ Vector<String> fileNames;
|
|
|
+ FileSystem* fileSystem = GetSubsystem<FileSystem>();
|
|
|
+ fileSystem->ScanDir(fileNames, resourceDir, "*.*", SCAN_FILES, true);
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < fileNames.Size(); i++)
|
|
|
+ {
|
|
|
+ const String& filename = fileNames[i];
|
|
|
+
|
|
|
+ AddToResourcePackager(filename, resourceDir);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void BuildBase::BuildProjectResourceEntries()
|
|
|
+{
|
|
|
+ String buildLogOutput(String::EMPTY);
|
|
|
+
|
|
|
+ if (AssetBuildConfig::IsLoaded())
|
|
|
+ {
|
|
|
+ buildLogOutput += "\nBaseBuild::BuildProjectResourceEntries - ./Settings/AssetBuildConfig.json found. ";
|
|
|
+ if (!assetBuildTag_.Empty())
|
|
|
+ {
|
|
|
+ buildLogOutput += "Using build-tag parameter : " + assetBuildTag_;
|
|
|
+ fileIncludedResourcesLog_->WriteLine(buildLogOutput);
|
|
|
+
|
|
|
+ BuildFilteredProjectResourceEntries();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ buildLogOutput += "No build-tag parameter used.";
|
|
|
+ }
|
|
|
+ buildLogOutput += "\nBaseBuild::BuildProjectResourceEntries - No custom asset include configuration being used - ";
|
|
|
+ buildLogOutput += "AssetBuildConfig.json not loaded, OR no build-tag parameter used.";
|
|
|
+ fileIncludedResourcesLog_->WriteLine(buildLogOutput);
|
|
|
+
|
|
|
+ BuildAllProjectResourceEntries();
|
|
|
+}
|
|
|
+
|
|
|
+void BuildBase::BuildAllProjectResourceEntries()
|
|
|
+{
|
|
|
+ for (unsigned i = 0; i < projectResourceDir_.Size(); i++)
|
|
|
+ {
|
|
|
+ String projectResourceDir = projectResourceDir_[i];
|
|
|
+ fileIncludedResourcesLog_->WriteLine("\nBuildBase::BuildAllProjectResourceEntries - Project resources being included from: " + projectResourceDir);
|
|
|
+
|
|
|
+ Vector<String> fileNamesInProject;
|
|
|
+ FileSystem* fileSystem = GetSubsystem<FileSystem>();
|
|
|
+ fileSystem->ScanDir(fileNamesInProject, projectResourceDir, "*.*", SCAN_FILES, true);
|
|
|
+
|
|
|
+ for (unsigned i = 0; i < fileNamesInProject.Size(); i++)
|
|
|
+ {
|
|
|
+ AddToResourcePackager(fileNamesInProject[i], projectResourceDir);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void BuildBase::BuildFilteredProjectResourceEntries()
|
|
|
+{
|
|
|
+ // Loading up the AssetBuildConfig.json,
|
|
|
+ // obtaining a list of files to include in the build.
|
|
|
+ VariantMap resourceTags;
|
|
|
+ AssetBuildConfig::ApplyConfig(resourceTags);
|
|
|
+ Vector<String> assetBuildConfigFiles;
|
|
|
+ VariantMap::ConstIterator itr = resourceTags.Begin();
|
|
|
+
|
|
|
+ while (itr != resourceTags.End())
|
|
|
+ {
|
|
|
+ if (itr->first_ == assetBuildTag_)
|
|
|
+ {
|
|
|
+ assetBuildConfigFiles = itr->second_.GetStringVector();
|
|
|
+ for (unsigned i = 0; i < assetBuildConfigFiles.Size(); ++i)
|
|
|
+ {
|
|
|
+ // remove case sensitivity
|
|
|
+ assetBuildConfigFiles[i] = assetBuildConfigFiles[i].ToLower();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ itr++;
|
|
|
+ if (itr == resourceTags.End())
|
|
|
+ {
|
|
|
+ LOGERRORF("BuildBase::BuildFilteredProjectResourceEntries - Asset build-tag \"%s\" not defined in ./Settings/AssetBuildConfig.json", assetBuildTag_.CString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // find any folders defined in assetbuildconfig.json, and add the non-".asset" files in them.
|
|
|
FileSystem* fileSystem = GetSubsystem<FileSystem>();
|
|
|
- fileSystem->ScanDir(fileNames, resourceDir, "*.*", SCAN_FILES, true);
|
|
|
+ Vector<String> filesInFolderToAdd;
|
|
|
|
|
|
- for (unsigned i = 0; i < fileNames.Size(); i++)
|
|
|
+ for (unsigned i = 0; i < assetBuildConfigFiles.Size(); ++i)
|
|
|
{
|
|
|
- const String& filename = fileNames[i];
|
|
|
+ String &filename = assetBuildConfigFiles[i];
|
|
|
|
|
|
- for (unsigned j = 0; j < resourceEntries_.Size(); j++)
|
|
|
+ if (GetExtension(filename) == String::EMPTY &&
|
|
|
+ fileSystem->DirExists(project_->GetResourcePath() + filename))
|
|
|
{
|
|
|
- const BuildResourceEntry* entry = resourceEntries_[j];
|
|
|
+ // rename 'filename' to 'folder' for context
|
|
|
+ String folder(filename);
|
|
|
|
|
|
- if (entry->packagePath_ == filename)
|
|
|
+ // add a trailing slash if not defined
|
|
|
+ if (folder.Back() != '/')
|
|
|
+ folder = AddTrailingSlash(folder);
|
|
|
+
|
|
|
+ Vector<String> filesInFolder;
|
|
|
+ fileSystem->ScanDir(filesInFolder, project_->GetResourcePath() + folder, "*.*", SCAN_FILES, true);
|
|
|
+ for (unsigned j = 0; j < filesInFolder.Size(); ++j)
|
|
|
{
|
|
|
- BuildWarn(ToString("Resource Path: %s already exists", filename.CString()));
|
|
|
- continue;
|
|
|
+ String path = filesInFolder[j];
|
|
|
+
|
|
|
+ // not interested in .asset files for now, will be included later.
|
|
|
+ if (GetExtension(path) != ".asset")
|
|
|
+ {
|
|
|
+ filesInFolderToAdd.Push(folder + path.ToLower());
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+ // add the files defined using a folder in AssetBuildConfig.json
|
|
|
+ for (unsigned i = 0; i < filesInFolderToAdd.Size(); ++i)
|
|
|
+ {
|
|
|
+ assetBuildConfigFiles.Push(filesInFolderToAdd[i]);
|
|
|
+ }
|
|
|
|
|
|
- if (!CheckIncludeResourceFile(resourceDir, filename))
|
|
|
- continue;
|
|
|
+ // check if the files in AssetBuildConfig.json exist,
|
|
|
+ // as well as their corresponding .asset file
|
|
|
+ Vector<String> filesInResourceFolder;
|
|
|
+ Vector<String> resourceFilesToInclude;
|
|
|
+ fileSystem->ScanDir(filesInResourceFolder, project_->GetResourcePath(), "*.*", SCAN_FILES, true);
|
|
|
+ for (unsigned j = 0; j < filesInResourceFolder.Size(); ++j)
|
|
|
+ {
|
|
|
+ // don't want to checks to be case sensitive
|
|
|
+ filesInResourceFolder[j] = filesInResourceFolder[j].ToLower();
|
|
|
+ }
|
|
|
|
|
|
- BuildResourceEntry* newEntry = new BuildResourceEntry;
|
|
|
+ for (unsigned i = 0; i < assetBuildConfigFiles.Size(); ++i)
|
|
|
+ {
|
|
|
+ // .asset file is of primary importance since we used it to identify the associated cached file.
|
|
|
+ // without the .asset file the resource is removed from being included in the build.
|
|
|
|
|
|
-// BEGIN LICENSE MANAGEMENT
|
|
|
- if (GetExtension(filename) == ".mdl")
|
|
|
+ // don't want checks to be case sensitive
|
|
|
+ String &filename = assetBuildConfigFiles[i];
|
|
|
+ if (filesInResourceFolder.Contains(filename) &&
|
|
|
+ filesInResourceFolder.Contains(filename + ".asset"))
|
|
|
{
|
|
|
- containsMDL_ = true;
|
|
|
+ resourceFilesToInclude.Push(filename);
|
|
|
+ resourceFilesToInclude.Push(filename + ".asset");
|
|
|
+ continue;
|
|
|
}
|
|
|
-// END LICENSE MANAGEMENT
|
|
|
+ fileIncludedResourcesLog_->WriteLine("File " + filename + " ignored since it does not have an associated .asset file");
|
|
|
+ }
|
|
|
|
|
|
- newEntry->absolutePath_ = resourceDir + filename;
|
|
|
- newEntry->resourceDir_ = resourceDir;
|
|
|
+ // add valid files included from the AssetBuildConfig.json
|
|
|
+ for (StringVector::ConstIterator it = resourceFilesToInclude.Begin(); it != resourceFilesToInclude.End(); ++it)
|
|
|
+ {
|
|
|
+ AddToResourcePackager(*it, project_->GetResourcePath());
|
|
|
+ }
|
|
|
|
|
|
- newEntry->packagePath_ = filename;
|
|
|
+ // Get associated cache GUID from the asset file
|
|
|
+ Vector<String> filesWithGUIDtoInclude;
|
|
|
+
|
|
|
+ for (StringVector::Iterator it = resourceFilesToInclude.Begin(); it != resourceFilesToInclude.End(); ++it)
|
|
|
+ {
|
|
|
+ String &filename = *it;
|
|
|
+ if (GetExtension(*it) == ".asset")
|
|
|
+ {
|
|
|
+ SharedPtr<File> file(new File(context_, project_->GetResourcePath() + *it));
|
|
|
+ SharedPtr<JSONFile> json(new JSONFile(context_));
|
|
|
+ json->Load(*file);
|
|
|
+ file->Close();
|
|
|
|
|
|
- resourceEntries_.Push(newEntry);
|
|
|
+ JSONValue root = json->GetRoot();
|
|
|
+ int test = root.Get("version").GetInt();
|
|
|
+ assert(root.Get("version").GetInt() == ASSET_VERSION);
|
|
|
|
|
|
- //LOGINFOF("Adding resource: %s : %s", newEntry->absolutePath_.CString(), newEntry->packagePath_.CString());
|
|
|
+ String guid = root.Get("guid").GetString();
|
|
|
+ filesWithGUIDtoInclude.Push(guid);
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-void BuildBase::BuildResourceEntries()
|
|
|
-{
|
|
|
- for (unsigned i = 0; i < resourceDirs_.Size(); i++)
|
|
|
+ // Obtain files in cache folder,
|
|
|
+ // Check if the file contains the guid, and add it to the cacheFilesToInclude
|
|
|
+ Vector<String> filesInCacheFolder;
|
|
|
+ Vector<String> cacheFilesToInclude;
|
|
|
+ AssetDatabase* db = GetSubsystem<AssetDatabase>();
|
|
|
+ String cachePath = db->GetCachePath();
|
|
|
+ fileSystem->ScanDir(filesInCacheFolder, cachePath, "*.*", SCAN_FILES, false);
|
|
|
+ for (unsigned i = 0; i < filesWithGUIDtoInclude.Size(); ++i)
|
|
|
{
|
|
|
- ScanResourceDirectory(resourceDirs_[i]);
|
|
|
+ String &guid = filesWithGUIDtoInclude[i];
|
|
|
+ for (unsigned j = 0; j < filesInCacheFolder.Size(); ++j)
|
|
|
+ {
|
|
|
+ const String &filename = GetFileName(filesInCacheFolder[j]);
|
|
|
+ String &filenamePath = filesInCacheFolder[j];
|
|
|
+ if (filename.Contains(guid))
|
|
|
+ {
|
|
|
+ cacheFilesToInclude.Push(filesInCacheFolder[j]);
|
|
|
+ // do not continue...
|
|
|
+ // there might be multiple files with the same guid having an guid_animaiton extention.
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (resourcePackager_.NotNull())
|
|
|
+ // include a texture file's cached .dds file when building in windows
|
|
|
+#ifdef ATOMIC_PLATFORM_DESKTOP
|
|
|
+ for (StringVector::ConstIterator it = resourceFilesToInclude.Begin(); it != resourceFilesToInclude.End(); ++it)
|
|
|
{
|
|
|
- for (unsigned i = 0; i < resourceEntries_.Size(); i++)
|
|
|
+ if (!CheckIncludeResourceFile(project_->GetResourcePath(), *it))
|
|
|
{
|
|
|
- BuildResourceEntry* entry = resourceEntries_[i];
|
|
|
- resourcePackager_->AddResourceEntry(entry);
|
|
|
+ FileSystem* fileSystem = GetSubsystem<FileSystem>();
|
|
|
+ String associatedDDSpath = "DDS/" + *it + ".dds";
|
|
|
+ String compressedPath = cachePath + associatedDDSpath;
|
|
|
+ if (fileSystem->FileExists(compressedPath))
|
|
|
+ {
|
|
|
+ cacheFilesToInclude.Push(associatedDDSpath);
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
+ // Add the cache files to the resource packager
|
|
|
+ for (StringVector::ConstIterator it = cacheFilesToInclude.Begin(); it != cacheFilesToInclude.End(); ++it)
|
|
|
+ {
|
|
|
+ AddToResourcePackager(*it, cachePath);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
+void BuildBase::AddToResourcePackager(const String& filename, const String& resourceDir)
|
|
|
+{
|
|
|
+ // Check if the file is already included in the resourceEntries_ list
|
|
|
+ for (unsigned j = 0; j < resourceEntries_.Size(); j++)
|
|
|
+ {
|
|
|
+ const BuildResourceEntry* entry = resourceEntries_[j];
|
|
|
+
|
|
|
+ if (entry->packagePath_ == filename)
|
|
|
+ {
|
|
|
+ BuildWarn(ToString("Resource Path: %s already exists", filename.CString()));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!CheckIncludeResourceFile(resourceDir, filename))
|
|
|
+ {
|
|
|
+ fileIncludedResourcesLog_->WriteLine(resourceDir + filename + " skipped because of file extention: " + GetExtension(filename));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ BuildResourceEntry* newEntry = new BuildResourceEntry;
|
|
|
+
|
|
|
+ // BEGIN LICENSE MANAGEMENT
|
|
|
+ if (GetExtension(filename) == ".mdl")
|
|
|
+ {
|
|
|
+ containsMDL_ = true;
|
|
|
+ }
|
|
|
+ // END LICENSE MANAGEMENT
|
|
|
+
|
|
|
+ newEntry->absolutePath_ = resourceDir + filename;
|
|
|
+ newEntry->resourceDir_ = resourceDir;
|
|
|
+ newEntry->packagePath_ = filename;
|
|
|
+
|
|
|
+ resourceEntries_.Push(newEntry);
|
|
|
+
|
|
|
+ assert(resourcePackager_.NotNull());
|
|
|
+ resourcePackager_->AddResourceEntry(newEntry);
|
|
|
+
|
|
|
+ fileIncludedResourcesLog_->WriteLine(newEntry->absolutePath_);
|
|
|
}
|
|
|
|
|
|
void BuildBase::GenerateResourcePackage(const String& resourcePackagePath)
|
|
|
@@ -381,5 +602,29 @@ void BuildBase::AddResourceDir(const String& dir)
|
|
|
resourceDirs_.Push(dir);
|
|
|
}
|
|
|
|
|
|
+void BuildBase::AddProjectResourceDir(const String& dir)
|
|
|
+{
|
|
|
+ assert(!projectResourceDir_.Contains(dir));
|
|
|
+ projectResourceDir_.Push(dir);
|
|
|
+}
|
|
|
+
|
|
|
+void BuildBase::ReadAssetBuildConfig()
|
|
|
+{
|
|
|
+ String projectPath = project_->GetProjectPath();
|
|
|
+ projectPath = RemoveTrailingSlash(projectPath);
|
|
|
+
|
|
|
+ String filename = projectPath + "Settings/AssetBuildConfig.json";
|
|
|
+
|
|
|
+ FileSystem* fileSystem = GetSubsystem<FileSystem>();
|
|
|
+ if (!fileSystem->FileExists(filename))
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (AssetBuildConfig::LoadFromFile(context_, filename))
|
|
|
+ {
|
|
|
+ VariantMap assetBuildConfig;
|
|
|
+ AssetBuildConfig::ApplyConfig(assetBuildConfig);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
}
|