3
0

GraphTemplateFileData.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 <AtomToolsFramework/Graph/GraphTemplateFileData.h>
  9. #include <AtomToolsFramework/Util/Util.h>
  10. #include <AzCore/Utils/Utils.h>
  11. #include <AzCore/IO/FileIO.h>
  12. namespace AtomToolsFramework
  13. {
  14. bool GraphTemplateFileData::Load(const AZStd::string& path)
  15. {
  16. m_path.clear();
  17. m_lines.clear();
  18. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "Loading template file: %s\n", path.c_str());
  19. // Attempt to load the template file to do symbol substitution and inject any code or data
  20. if (auto result = AZ::Utils::ReadFile(path))
  21. {
  22. m_path = path;
  23. m_lastModifiedTime = AZ::IO::FileIOBase::GetInstance()->ModificationTime(path.c_str());
  24. // Tokenize the entire template file into individual lines that can be evaluated, removed, replaced, and have
  25. // content injected between them
  26. m_lines.reserve(1000);
  27. AZ::StringFunc::Tokenize(result.GetValue(), m_lines, '\n', true, true);
  28. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "Loading template file succeeded: %s\n", path.c_str());
  29. return true;
  30. }
  31. AZ_Error("GraphTemplateFileData", false, "Loading template file failed: %s\n", path.c_str());
  32. return false;
  33. }
  34. bool GraphTemplateFileData::Save(const AZStd::string& path) const
  35. {
  36. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "Saving generated file: %s\n", path.c_str());
  37. AZStd::string templateOutputText;
  38. AZ::StringFunc::Join(templateOutputText, m_lines, '\n');
  39. templateOutputText += '\n';
  40. // Save the file generated from the template to the same folder as the graph.
  41. if (AZ::Utils::WriteFile(templateOutputText, path).IsSuccess())
  42. {
  43. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "Saving generated file succeeded: %s\n", path.c_str());
  44. return true;
  45. }
  46. AZ_Error("GraphTemplateFileData", false, "Saving generated file failed: %s\n", path.c_str());
  47. return false;
  48. }
  49. bool GraphTemplateFileData::IsReloadRequired() const
  50. {
  51. return !IsLoaded() || m_lastModifiedTime < AZ::IO::FileIOBase::GetInstance()->ModificationTime(m_path.c_str());
  52. }
  53. bool GraphTemplateFileData::IsLoaded() const
  54. {
  55. return !m_path.empty() && !m_lines.empty();
  56. }
  57. bool GraphTemplateFileData::IsLoggingEnabled() const
  58. {
  59. return GetSettingsValue("/O3DE/AtomToolsFramework/GraphCompiler/EnableLogging", false);
  60. }
  61. const AZStd::string& GraphTemplateFileData::GetPath() const
  62. {
  63. return m_path;
  64. }
  65. const AZStd::vector<AZStd::string>& GraphTemplateFileData::GetLines() const
  66. {
  67. return m_lines;
  68. }
  69. void GraphTemplateFileData::ReplaceSymbol(const AZStd::string& findText, const AZStd::string& replaceText)
  70. {
  71. ReplaceSymbolsInContainer(findText, replaceText, m_lines);
  72. }
  73. void GraphTemplateFileData::ReplaceLinesInBlock(
  74. const AZStd::string& blockBeginToken, const AZStd::string& blockEndToken, const LineGenerationFn& lineGenerationFn)
  75. {
  76. AZ_TracePrintf_IfTrue(
  77. "GraphTemplateFileData",
  78. IsLoggingEnabled(),
  79. "Inserting %s lines into template file: %s\n",
  80. blockBeginToken.c_str(),
  81. m_path.c_str());
  82. auto blockBeginItr = AZStd::find_if(
  83. m_lines.begin(),
  84. m_lines.end(),
  85. [&blockBeginToken](const AZStd::string& line)
  86. {
  87. return AZ::StringFunc::Contains(line, blockBeginToken);
  88. });
  89. while (blockBeginItr != m_lines.end())
  90. {
  91. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "*blockBegin: %s\n", (*blockBeginItr).c_str());
  92. // We have to insert one line at a time because AZStd::vector does not include a standard
  93. // range insert that returns an iterator
  94. const auto& linesToInsert = lineGenerationFn(*blockBeginItr);
  95. for (const auto& lineToInsert : linesToInsert)
  96. {
  97. ++blockBeginItr;
  98. blockBeginItr = m_lines.insert(blockBeginItr, lineToInsert);
  99. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "lineToInsert: %s\n", lineToInsert.c_str());
  100. }
  101. if (linesToInsert.empty())
  102. {
  103. AZ_TracePrintf_IfTrue(
  104. "GraphTemplateFileData", IsLoggingEnabled(), "Nothing was generated. This block will remain unmodified.\n");
  105. }
  106. ++blockBeginItr;
  107. // From the last line that was inserted, locate the end of the insertion block
  108. auto blockEndItr = AZStd::find_if(
  109. blockBeginItr,
  110. m_lines.end(),
  111. [&blockEndToken](const AZStd::string& line)
  112. {
  113. return AZ::StringFunc::Contains(line, blockEndToken);
  114. });
  115. AZ_TracePrintf_IfTrue("GraphTemplateFileData", IsLoggingEnabled(), "*blockEnd: %s\n", (*blockEndItr).c_str());
  116. if (!linesToInsert.empty())
  117. {
  118. // If any new lines were inserted, erase pre-existing lines the template might have had between the begin and end blocks
  119. blockEndItr = m_lines.erase(blockBeginItr, blockEndItr);
  120. }
  121. // Search for another insertion point
  122. blockBeginItr = AZStd::find_if(
  123. blockEndItr,
  124. m_lines.end(),
  125. [&blockBeginToken](const AZStd::string& line)
  126. {
  127. return AZ::StringFunc::Contains(line, blockBeginToken);
  128. });
  129. }
  130. }
  131. } // namespace AtomToolsFramework