3
0

NodeUsageTreeItem.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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 <AzFramework/StringFunc/StringFunc.h>
  9. #include <AzToolsFramework/API/EditorAssetSystemAPI.h>
  10. #include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
  11. #include <Editor/View/Widgets/StatisticsDialog/NodeUsageTreeItem.h>
  12. #include <ScriptCanvas/Components/EditorGraph.h>
  13. namespace ScriptCanvasEditor
  14. {
  15. /////////////////////////////////
  16. // NodePaletteNodeUsageRootItem
  17. /////////////////////////////////
  18. NodePaletteNodeUsageRootItem::NodePaletteNodeUsageRootItem(const NodePaletteModel& nodePaletteModel)
  19. : GraphCanvas::NodePaletteTreeItem("root", ScriptCanvasEditor::AssetEditorId)
  20. , m_categorizer(nodePaletteModel)
  21. {
  22. }
  23. NodePaletteNodeUsageRootItem::~NodePaletteNodeUsageRootItem()
  24. {
  25. }
  26. GraphCanvas::NodePaletteTreeItem* NodePaletteNodeUsageRootItem::GetCategoryNode(const char* categoryPath, GraphCanvas::NodePaletteTreeItem* parentRoot)
  27. {
  28. if (parentRoot)
  29. {
  30. return static_cast<GraphCanvas::NodePaletteTreeItem*>(m_categorizer.GetCategoryNode(categoryPath, parentRoot));
  31. }
  32. else
  33. {
  34. return static_cast<GraphCanvas::NodePaletteTreeItem*>(m_categorizer.GetCategoryNode(categoryPath, this));
  35. }
  36. }
  37. void NodePaletteNodeUsageRootItem::PruneEmptyNodes()
  38. {
  39. m_categorizer.PruneEmptyNodes();
  40. }
  41. ////////////////////////////////////
  42. // NodePaletteNodeUsagePaletteItem
  43. ////////////////////////////////////
  44. NodePaletteNodeUsagePaletteItem::NodePaletteNodeUsagePaletteItem(const ScriptCanvas::NodeTypeIdentifier& nodeIdentifier, AZStd::string_view displayName)
  45. : GraphCanvas::IconDecoratedNodePaletteTreeItem(displayName, ScriptCanvasEditor::AssetEditorId)
  46. , m_nodeIdentifier(nodeIdentifier)
  47. {
  48. }
  49. NodePaletteNodeUsagePaletteItem::~NodePaletteNodeUsagePaletteItem()
  50. {
  51. }
  52. const ScriptCanvas::NodeTypeIdentifier& NodePaletteNodeUsagePaletteItem::GetNodeTypeIdentifier() const
  53. {
  54. return m_nodeIdentifier;
  55. }
  56. //////////////////////////////
  57. // ScriptCanvasAssetTreeItem
  58. //////////////////////////////
  59. ScriptCanvasAssetNodeUsageTreeItem::ScriptCanvasAssetNodeUsageTreeItem(AZStd::string_view assetName)
  60. : m_name(QString::fromUtf8(assetName.data(), static_cast<int>(assetName.size())))
  61. , m_icon(":/ScriptCanvasEditorResources/Resources/edit_icon.png")
  62. , m_activeIdentifier(0)
  63. {
  64. }
  65. int ScriptCanvasAssetNodeUsageTreeItem::GetColumnCount() const
  66. {
  67. return Column::Count;
  68. }
  69. QVariant ScriptCanvasAssetNodeUsageTreeItem::Data(const QModelIndex& index, int role) const
  70. {
  71. if (index.column() == Column::Name)
  72. {
  73. switch (role)
  74. {
  75. case Qt::DisplayRole:
  76. return GetName();
  77. case Qt::DecorationRole:
  78. break;
  79. default:
  80. break;
  81. }
  82. }
  83. else if (index.column() == Column::UsageCount && m_assetId.IsValid())
  84. {
  85. switch (role)
  86. {
  87. case Qt::DisplayRole:
  88. return GetNodeCount();
  89. default:
  90. break;
  91. }
  92. }
  93. else if (index.column() == Column::OpenIcon)
  94. {
  95. if (m_assetId.IsValid())
  96. {
  97. switch (role)
  98. {
  99. case Qt::DecorationRole:
  100. return m_icon;
  101. default:
  102. break;
  103. }
  104. }
  105. }
  106. return QVariant();
  107. }
  108. Qt::ItemFlags ScriptCanvasAssetNodeUsageTreeItem::Flags(const QModelIndex&) const
  109. {
  110. Qt::ItemFlags baseFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
  111. return baseFlags;
  112. }
  113. void ScriptCanvasAssetNodeUsageTreeItem::SetAssetId(const AZ::Data::AssetId& assetId, AZ::Data::AssetType assetType)
  114. {
  115. if (m_assetId != assetId)
  116. {
  117. if (AZ::Data::AssetBus::Handler::BusIsConnected())
  118. {
  119. AZ::Data::AssetBus::Handler::BusDisconnect();
  120. }
  121. m_assetId = assetId;
  122. AZ::Data::AssetBus::Handler::BusConnect(assetId);
  123. }
  124. m_assetType = assetType;
  125. }
  126. const AZ::Data::AssetId& ScriptCanvasAssetNodeUsageTreeItem::GetAssetId() const
  127. {
  128. return m_assetId;
  129. }
  130. const QString& ScriptCanvasAssetNodeUsageTreeItem::GetName() const
  131. {
  132. return m_name;
  133. }
  134. void ScriptCanvasAssetNodeUsageTreeItem::SetActiveNodeType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier)
  135. {
  136. if (m_activeIdentifier != nodeTypeIdentifier)
  137. {
  138. m_activeIdentifier = nodeTypeIdentifier;
  139. SignalDataChanged();
  140. }
  141. }
  142. int ScriptCanvasAssetNodeUsageTreeItem::GetNodeCount() const
  143. {
  144. auto nodeIter = m_statisticsHelper.m_nodeIdentifierCount.find(m_activeIdentifier);
  145. if (nodeIter == m_statisticsHelper.m_nodeIdentifierCount.end())
  146. {
  147. return 0;
  148. }
  149. return nodeIter->second;
  150. }
  151. /*
  152. void ScriptCanvasAssetNodeUsageTreeItem::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
  153. {
  154. ProcessAsset(asset);
  155. }
  156. void ScriptCanvasAssetNodeUsageTreeItem::OnAssetSaved(AZ::Data::Asset<AZ::Data::AssetData> asset, bool isSuccessful)
  157. {
  158. if (isSuccessful)
  159. {
  160. ProcessAsset(asset);
  161. }
  162. }
  163. void ScriptCanvasAssetNodeUsageTreeItem::OnAssetReloaded(AZ::Data::Asset<AZ::Data::AssetData> asset)
  164. {
  165. ProcessAsset(asset);
  166. }
  167. // #sc_editor_asset_redux fix graph use statistics
  168. void ScriptCanvasAssetNodeUsageTreeItem::ProcessAsset(const AZ::Data::Asset<LegacyScriptCanvasBaseAsset>& scriptCanvasAsset)
  169. {
  170. if (scriptCanvasAsset.IsReady())
  171. {
  172. AZ::Entity* scriptCanvasEntity = scriptCanvasAsset.Get()->GetScriptCanvasEntity();
  173. Graph* editorGraph = AZ::EntityUtils::FindFirstDerivedComponent<Graph>(scriptCanvasEntity);
  174. if (editorGraph)
  175. {
  176. m_statisticsHelper = editorGraph->GetNodeUsageStatistics();
  177. // Temporary measure to deal potentially unfilled out data.
  178. if (m_statisticsHelper.m_nodeIdentifierCount.empty())
  179. {
  180. m_statisticsHelper.PopulateStatisticData(editorGraph);
  181. }
  182. SignalDataChanged();
  183. }
  184. }
  185. }
  186. */
  187. ///////////////////////////////////////////
  188. // ScriptCanvasAssetNodeUsageTreeItemRoot
  189. ///////////////////////////////////////////
  190. ScriptCanvasAssetNodeUsageTreeItemRoot::ScriptCanvasAssetNodeUsageTreeItemRoot()
  191. : ScriptCanvasAssetNodeUsageTreeItem("root")
  192. , m_categorizer((*this))
  193. {
  194. }
  195. void ScriptCanvasAssetNodeUsageTreeItemRoot::RegisterAsset(const AZ::Data::AssetId& assetId, AZ::Data::AssetType assetType)
  196. {
  197. auto asset = AZ::Data::AssetManager::Instance().GetAsset(assetId, assetType, AZ::Data::AssetLoadBehavior::PreLoad);
  198. asset.BlockUntilLoadComplete();
  199. if (!asset.IsReady())
  200. {
  201. // The asset must be loaded before it an be registered. We will connect to the AssetBus and wait for it to be ready.
  202. AZ::Data::AssetBus::MultiHandler::BusConnect(assetId);
  203. return;
  204. }
  205. auto treeItem = GetAssetItem(assetId);
  206. if (treeItem == nullptr)
  207. {
  208. AZ::Data::AssetInfo assetInfo;
  209. const AZStd::string platformName = ""; // Empty for default
  210. AZStd::string rootFilePath;
  211. bool foundPath = false;
  212. AzToolsFramework::AssetSystemRequestBus::BroadcastResult(foundPath, &AzToolsFramework::AssetSystemRequestBus::Events::GetAssetInfoById, assetId, assetType, platformName, assetInfo, rootFilePath);
  213. if (foundPath)
  214. {
  215. AZStd::string relativePath = assetInfo.m_relativePath;
  216. AZStd::string fileName;
  217. if (AzFramework::StringFunc::Path::GetFileName(relativePath.c_str(), fileName))
  218. {
  219. AzFramework::StringFunc::Path::Normalize(relativePath);
  220. const bool stripLastComponent = true;
  221. if (AzFramework::StringFunc::Path::StripComponent(relativePath, stripLastComponent))
  222. {
  223. AzFramework::StringFunc::Replace(relativePath, AZ_CORRECT_FILESYSTEM_SEPARATOR, '/');
  224. GraphCanvas::GraphCanvasTreeItem* treeItem2 = m_categorizer.GetCategoryNode(relativePath.c_str(), this);
  225. if (treeItem2)
  226. {
  227. ScriptCanvasAssetNodeUsageTreeItem* usageTreeItem = treeItem2->CreateChildNode<ScriptCanvasAssetNodeUsageTreeItem>(fileName);
  228. usageTreeItem->SetAssetId(assetId, assetType);
  229. m_scriptCanvasAssetItems[assetId] = usageTreeItem;
  230. }
  231. }
  232. }
  233. }
  234. }
  235. else
  236. {
  237. treeItem->SetAssetId(assetId, assetType);
  238. }
  239. }
  240. void ScriptCanvasAssetNodeUsageTreeItemRoot::RemoveAsset(const AZ::Data::AssetId& assetId)
  241. {
  242. auto assetIter = m_scriptCanvasAssetItems.find(assetId);
  243. if (assetIter != m_scriptCanvasAssetItems.end())
  244. {
  245. assetIter->second->DetachItem();
  246. delete assetIter->second;
  247. m_categorizer.PruneEmptyNodes();
  248. }
  249. }
  250. ScriptCanvasAssetNodeUsageTreeItem* ScriptCanvasAssetNodeUsageTreeItemRoot::GetAssetItem(const AZ::Data::AssetId& assetId)
  251. {
  252. auto assetIter = m_scriptCanvasAssetItems.find(assetId);
  253. if (assetIter != m_scriptCanvasAssetItems.end())
  254. {
  255. return assetIter->second;
  256. }
  257. return nullptr;
  258. }
  259. GraphCanvas::GraphCanvasTreeItem* ScriptCanvasAssetNodeUsageTreeItemRoot::CreateCategoryNode(AZStd::string_view, AZStd::string_view categoryName, GraphCanvasTreeItem* parent) const
  260. {
  261. return parent->CreateChildNode<ScriptCanvasAssetNodeUsageTreeItem>(categoryName);
  262. }
  263. const ScriptCanvasAssetNodeUsageTreeItemRoot::ScriptCanvasAssetMap& ScriptCanvasAssetNodeUsageTreeItemRoot::GetAssetTreeItems() const
  264. {
  265. return m_scriptCanvasAssetItems;
  266. }
  267. void ScriptCanvasAssetNodeUsageTreeItemRoot::OnAssetReady(AZ::Data::Asset<AZ::Data::AssetData> asset)
  268. {
  269. AZ::Data::AssetBus::MultiHandler::BusDisconnect(*AZ::Data::AssetBus::GetCurrentBusId());
  270. RegisterAsset(asset.GetId(), asset.GetType());
  271. }
  272. }