main.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Memory/AllocatorManager.h>
  9. #include <AzToolsFramework/Application/ToolsApplication.h>
  10. #include <AzCore/Asset/AssetManagerBus.h>
  11. #include <AzCore/IO/FileIO.h>
  12. #include <AzCore/Serialization/ObjectStream.h>
  13. #include <AzCore/Serialization/Utils.h>
  14. #include <AzFramework/Asset/AssetBundleManifest.h>
  15. #include <AzFramework/CommandLine/CommandLine.h>
  16. #include <AzFramework/StringFunc/StringFunc.h>
  17. #include <AzToolsFramework/Archive/ArchiveAPI.h>
  18. #include <AzToolsFramework/AssetBundle/AssetBundleAPI.h>
  19. const char* appWindowName = "DeltaCataloger";
  20. enum class DeltaCatalogerResult : AZ::u8
  21. {
  22. Success = 0,
  23. InvalidArg = 1,
  24. FailedToCreateDeltaCatalog,
  25. FailedToInjectFile,
  26. };
  27. struct DeltaCatalogerParams
  28. {
  29. AZStd::string sourceCatalogPath;
  30. AZStd::vector<AZStd::string> sourcePaks;
  31. AZStd::string workingDirectory;
  32. bool verbose = false;
  33. bool regenerateExistingDeltas = false;
  34. };
  35. DeltaCatalogerResult DeltaCataloger(DeltaCatalogerParams& params)
  36. {
  37. using AssetCatalogRequestBus = AZ::Data::AssetCatalogRequestBus;
  38. using AssetBundleCommandsBus = AzToolsFramework::AssetBundleCommands::Bus;
  39. // update all relative paths given to be relative to the working directory
  40. if (params.workingDirectory.length())
  41. {
  42. AzFramework::StringFunc::Path::Join(params.workingDirectory.c_str(), params.sourceCatalogPath.c_str(), params.sourceCatalogPath);
  43. for (AZ::u32 index = 0; index < params.sourcePaks.size(); ++index)
  44. {
  45. AzFramework::StringFunc::Path::Join(params.workingDirectory.c_str(), params.sourcePaks[index].c_str(), params.sourcePaks[index]);
  46. }
  47. }
  48. // validate params
  49. AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
  50. if (!fileIO->Exists(params.sourceCatalogPath.c_str()))
  51. {
  52. AZ_Error(appWindowName, false, "Invalid Arg: Source Asset Catalog does not exist at \"%s\".", params.sourceCatalogPath.c_str());
  53. return DeltaCatalogerResult::InvalidArg;
  54. }
  55. if (params.sourcePaks.empty())
  56. {
  57. AZ_Error(appWindowName, false, "Failed to read source pak files arg list. Should start from second argument.");
  58. return DeltaCatalogerResult::InvalidArg;
  59. }
  60. for (const AZStd::string& sourcePakPath : params.sourcePaks)
  61. {
  62. if (!fileIO->Exists(sourcePakPath.c_str()))
  63. {
  64. AZ_Error(appWindowName, false, "Invalid Arg: Source Pak does not exist at \"%s\".", sourcePakPath.c_str());
  65. return DeltaCatalogerResult::InvalidArg;
  66. }
  67. }
  68. // Load the source catalog
  69. if (params.verbose)
  70. {
  71. AZ_TracePrintf(appWindowName, "Loading source asset catalog \"%s\".\n", params.sourceCatalogPath.c_str())
  72. }
  73. AssetCatalogRequestBus::Broadcast(&AssetCatalogRequestBus::Events::ClearCatalog);
  74. bool result = false;
  75. AssetCatalogRequestBus::BroadcastResult(result, &AssetCatalogRequestBus::Events::LoadCatalog, params.sourceCatalogPath.c_str());
  76. if (result)
  77. {
  78. for (const AZStd::string& sourcePakPath : params.sourcePaks)
  79. {
  80. bool catalogCreated = false;
  81. AssetBundleCommandsBus::BroadcastResult(catalogCreated, &AssetBundleCommandsBus::Events::CreateDeltaCatalog, sourcePakPath, params.regenerateExistingDeltas);
  82. if (!catalogCreated)
  83. {
  84. AZ_Error(appWindowName, false, "Failed to make or inject delta asset catalog for \"%s\".", sourcePakPath.c_str());
  85. return DeltaCatalogerResult::FailedToCreateDeltaCatalog;
  86. }
  87. }
  88. }
  89. else
  90. {
  91. AZStd::string error = AZStd::string::format("Failed to load source asset catalog \"%s\".", params.sourceCatalogPath.c_str());
  92. AZ_Error(appWindowName, false, error.c_str());
  93. return DeltaCatalogerResult::FailedToCreateDeltaCatalog;
  94. }
  95. return DeltaCatalogerResult::Success;
  96. }
  97. DeltaCatalogerResult ParseArgs(const AzFramework::CommandLine* parser, DeltaCatalogerParams& params)
  98. {
  99. // AzFramework CommandLine consumes the first arg (the executable itself), so positional or switch args start at 0
  100. const AZ::u8 sourceCatalogPathIndex = 0;
  101. const AZ::u8 sourceCatalogStartIndex = 1;
  102. params.sourceCatalogPath = parser->GetMiscValue(sourceCatalogPathIndex);
  103. AZ::u64 numPositionalArgs = parser->GetNumMiscValues();
  104. for (AZ::u64 index = sourceCatalogStartIndex; index < numPositionalArgs; ++index)
  105. {
  106. params.sourcePaks.push_back(parser->GetMiscValue(index));
  107. }
  108. params.verbose = parser->HasSwitch("verbose");
  109. params.regenerateExistingDeltas = parser->HasSwitch("regenerate");
  110. params.workingDirectory = parser->GetSwitchValue("working-dir", 0);
  111. return DeltaCatalogerResult::Success;
  112. }
  113. int main(int argc, char** argv)
  114. {
  115. const AZ::Debug::Trace tracer;
  116. DeltaCatalogerResult exitCode = DeltaCatalogerResult::Success;
  117. const AZ::u8 minimumArgCount = 3; // 0 = exe, 1 = source catalog path, 2 = source pak path, from raw commandline input
  118. if (argc < minimumArgCount)
  119. {
  120. AZ_Error(appWindowName, false, "Must specify source catalog, and at least one source pak file.");
  121. return static_cast<int>(DeltaCatalogerResult::InvalidArg);
  122. }
  123. AzToolsFramework::ToolsApplication app(&argc, &argv);
  124. // can deal with starting the app with a different working directory if needed later (use lmbr cli main.cpp as a reference)
  125. AzFramework::Application::StartupParameters startParam;
  126. app.Start(AzFramework::Application::Descriptor());
  127. {
  128. DeltaCatalogerParams params;
  129. exitCode = ParseArgs(app.GetCommandLine(), params);
  130. if (exitCode != DeltaCatalogerResult::Success)
  131. {
  132. return static_cast<int>(exitCode);
  133. }
  134. exitCode = DeltaCataloger(params);
  135. // Tick until everything is ready for shutdown
  136. app.Tick();
  137. }
  138. app.Stop();
  139. return static_cast<int>(exitCode);
  140. }