Merge pull request #6345 from aws-lumberyard-dev/sc-editor-onto-rte-part4-6322
Sc editor onto rte part4 6322
This commit is contained in:
@@ -5073,13 +5073,26 @@ LUA_API const Node* lua_getDummyNode()
|
||||
// Check all constructors if they have use ScriptDataContext and if so choose this one
|
||||
if (!customConstructorMethod)
|
||||
{
|
||||
int overrideIndex = -1;
|
||||
AZ::AttributeReader(nullptr, FindAttribute
|
||||
( Script::Attributes::DefaultConstructorOverrideIndex, behaviorClass->m_attributes)).Read<int>(overrideIndex);
|
||||
|
||||
int methodIndex = 0;
|
||||
for (BehaviorMethod* method : behaviorClass->m_constructors)
|
||||
{
|
||||
if (methodIndex == overrideIndex)
|
||||
{
|
||||
customConstructorMethod = method;
|
||||
break;
|
||||
}
|
||||
|
||||
if (method->GetNumArguments() && method->GetArgument(method->GetNumArguments() - 1)->m_typeId == AZ::AzTypeInfo<ScriptDataContext>::Uuid())
|
||||
{
|
||||
customConstructorMethod = method;
|
||||
break;
|
||||
}
|
||||
|
||||
++methodIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace AZ
|
||||
static constexpr AZ::Crc32 ClassNameOverride = AZ_CRC_CE("ScriptClassNameOverride"); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name
|
||||
static constexpr AZ::Crc32 MethodOverride = AZ_CRC_CE("ScriptFunctionOverride"); ///< Use a custom function in the attribute instead of the function
|
||||
static constexpr AZ::Crc32 ConstructorOverride = AZ_CRC_CE("ConstructorOverride"); ///< You can provide a custom constructor to be called when created from Lua script
|
||||
static constexpr AZ::Crc32 DefaultConstructorOverrideIndex = AZ_CRC_CE("DefaultConstructorOverrideIndex"); ///< Use a different class constructor as the default constructor in Lua
|
||||
static constexpr AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals
|
||||
static constexpr AZ::Crc32 GenericConstructorOverride = AZ_CRC_CE("GenericConstructorOverride"); ///< You can provide a custom constructor to be called when creating a script
|
||||
static constexpr AZ::Crc32 ReaderWriterOverride = AZ_CRC_CE("ReaderWriterOverride"); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM
|
||||
|
||||
@@ -133,6 +133,8 @@ namespace AZ
|
||||
const static AZ::Crc32 AllowClearAsset = AZ_CRC("AllowClearAsset", 0x24827182);
|
||||
// Show the name of the asset that was produced from the source asset
|
||||
const static AZ::Crc32 ShowProductAssetFileName = AZ_CRC("ShowProductAssetFileName");
|
||||
//! Regular expression pattern filter for source files
|
||||
const static AZ::Crc32 SourceAssetFilterPattern = AZ_CRC_CE("SourceAssetFilterPattern");
|
||||
|
||||
//! Component icon attributes
|
||||
const static AZ::Crc32 Icon = AZ_CRC("Icon", 0x659429db);
|
||||
|
||||
@@ -204,6 +204,22 @@ namespace AZ
|
||||
// BaseJsonSerializer
|
||||
//
|
||||
|
||||
JsonSerializationResult::Result BaseJsonSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context)
|
||||
{
|
||||
JsonSerializationResult::ResultCode result(JsonSerializationResult::Tasks::ReadField);
|
||||
result.Combine(ContinueLoading(outputValue, outputValueTypeId, inputValue, context, ContinuationFlags::IgnoreTypeSerializer));
|
||||
return context.Report(result, "Ignoring custom serialization during load");
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result BaseJsonSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||
const Uuid& valueTypeId, JsonSerializerContext& context)
|
||||
{
|
||||
JsonSerializationResult::ResultCode result(JsonSerializationResult::Tasks::WriteValue);
|
||||
result.Combine(ContinueStoring(outputValue, inputValue, defaultValue, valueTypeId, context, ContinuationFlags::IgnoreTypeSerializer));
|
||||
return context.Report(result, "Ignoring custom serialization during store");
|
||||
}
|
||||
|
||||
BaseJsonSerializer::OperationFlags BaseJsonSerializer::GetOperationsFlags() const
|
||||
{
|
||||
return OperationFlags::None;
|
||||
|
||||
@@ -180,13 +180,16 @@ namespace AZ
|
||||
|
||||
//! Transforms the data from the rapidjson Value to outputValue, if the conversion is possible and supported.
|
||||
//! The serializer is responsible for casting to the proper type and safely writing to the outputValue memory.
|
||||
//! \note The default implementation is to load the object ignoring a custom serializers for the type, which allows for custom serializers
|
||||
//! to modify the object after all default loading has occurred.
|
||||
virtual JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
|
||||
JsonDeserializerContext& context) = 0;
|
||||
JsonDeserializerContext& context);
|
||||
|
||||
//! Write the input value to a rapidjson value if the default value is not null and doesn't match the input value, otherwise
|
||||
//! an error is returned and sets the rapidjson value to a null value.
|
||||
//! \note The default implementation is to store the object ignoring custom serializers.
|
||||
virtual JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
|
||||
const Uuid& valueTypeId, JsonSerializerContext& context) = 0;
|
||||
const Uuid& valueTypeId, JsonSerializerContext& context);
|
||||
|
||||
//! Returns the operation flags which tells the Json Serialization how this custom json serializer can be used.
|
||||
virtual OperationFlags GetOperationsFlags() const;
|
||||
|
||||
@@ -165,13 +165,12 @@ namespace AZ::Utils
|
||||
}
|
||||
|
||||
Container fileContent;
|
||||
fileContent.resize(length);
|
||||
fileContent.resize_no_construct(length);
|
||||
AZ::IO::SizeType bytesRead = file.Read(length, fileContent.data());
|
||||
file.Close();
|
||||
|
||||
// Resize again just in case bytesRead is less than length for some reason
|
||||
fileContent.resize(bytesRead);
|
||||
|
||||
fileContent.resize_no_construct(bytesRead);
|
||||
return AZ::Success(AZStd::move(fileContent));
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -99,6 +99,18 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
if (selection.GetSelectedAssetIds().empty())
|
||||
{
|
||||
for (auto& filePath : selection.GetSelectedFilePaths())
|
||||
{
|
||||
if (!filePath.empty())
|
||||
{
|
||||
selectedAsset = true;
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectFileAtPath(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedAsset)
|
||||
{
|
||||
m_ui->m_assetBrowserTreeViewWidget->SelectFolder(selection.GetDefaultDirectory());
|
||||
|
||||
+60
-9
@@ -10,18 +10,24 @@
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/EBusFindAssetTypeByName.h>
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option")
|
||||
#include <QRegExp>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
#endif
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
namespace AssetBrowser
|
||||
{
|
||||
namespace
|
||||
{
|
||||
FilterConstType ProductsNoFoldersFilter()
|
||||
FilterConstType EntryTypeNoFoldersFilter(AssetBrowserEntry::AssetEntryType entryType = AssetBrowserEntry::AssetEntryType::Product)
|
||||
{
|
||||
EntryTypeFilter* productFilter = new EntryTypeFilter();
|
||||
productFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Product);
|
||||
EntryTypeFilter* entryTypeFilter = new EntryTypeFilter();
|
||||
entryTypeFilter->SetEntryType(entryType);
|
||||
// in case entry is a source or folder, it may still contain relevant product
|
||||
productFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||
entryTypeFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||
|
||||
EntryTypeFilter* foldersFilter = new EntryTypeFilter();
|
||||
foldersFilter->SetEntryType(AssetBrowserEntry::AssetEntryType::Folder);
|
||||
@@ -30,7 +36,7 @@ namespace AzToolsFramework
|
||||
noFoldersFilter->SetFilter(FilterConstType(foldersFilter));
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||
compFilter->AddFilter(FilterConstType(productFilter));
|
||||
compFilter->AddFilter(FilterConstType(entryTypeFilter));
|
||||
compFilter->AddFilter(FilterConstType(noFoldersFilter));
|
||||
|
||||
return FilterConstType(compFilter);
|
||||
@@ -79,15 +85,39 @@ namespace AzToolsFramework
|
||||
|
||||
void AssetSelectionModel::SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds)
|
||||
{
|
||||
m_selectedFilePaths.clear();
|
||||
|
||||
m_selectedAssetIds = selectedAssetIds;
|
||||
}
|
||||
|
||||
void AssetSelectionModel::SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId)
|
||||
{
|
||||
m_selectedFilePaths.clear();
|
||||
|
||||
m_selectedAssetIds.clear();
|
||||
m_selectedAssetIds.push_back(selectedAssetId);
|
||||
}
|
||||
|
||||
const AZStd::vector<AZStd::string>& AssetSelectionModel::GetSelectedFilePaths() const
|
||||
{
|
||||
return m_selectedFilePaths;
|
||||
}
|
||||
|
||||
void AssetSelectionModel::SetSelectedFilePaths(const AZStd::vector<AZStd::string>& selectedFilePaths)
|
||||
{
|
||||
m_selectedAssetIds.clear();
|
||||
|
||||
m_selectedFilePaths = selectedFilePaths;
|
||||
}
|
||||
|
||||
void AssetSelectionModel::SetSelectedFilePath(const AZStd::string& selectedFilePath)
|
||||
{
|
||||
m_selectedAssetIds.clear();
|
||||
|
||||
m_selectedFilePaths.clear();
|
||||
m_selectedFilePaths.push_back(selectedFilePath);
|
||||
}
|
||||
|
||||
void AssetSelectionModel::SetDefaultDirectory(AZStd::string_view defaultDirectory)
|
||||
{
|
||||
m_defaultDirectory = defaultDirectory;
|
||||
@@ -136,7 +166,7 @@ namespace AzToolsFramework
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||
compFilter->AddFilter(assetTypeFilterPtr);
|
||||
compFilter->AddFilter(ProductsNoFoldersFilter());
|
||||
compFilter->AddFilter(EntryTypeNoFoldersFilter());
|
||||
|
||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||
selection.SetMultiselect(multiselect);
|
||||
@@ -169,7 +199,7 @@ namespace AzToolsFramework
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||
compFilter->AddFilter(anyAssetTypeFilterPtr);
|
||||
compFilter->AddFilter(ProductsNoFoldersFilter());
|
||||
compFilter->AddFilter(EntryTypeNoFoldersFilter());
|
||||
|
||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||
selection.SetMultiselect(multiselect);
|
||||
@@ -190,7 +220,28 @@ namespace AzToolsFramework
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||
compFilter->AddFilter(assetGroupFilterPtr);
|
||||
compFilter->AddFilter(ProductsNoFoldersFilter());
|
||||
compFilter->AddFilter(EntryTypeNoFoldersFilter());
|
||||
|
||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||
selection.SetMultiselect(multiselect);
|
||||
|
||||
return selection;
|
||||
}
|
||||
|
||||
AssetSelectionModel AssetSelectionModel::SourceAssetTypeSelection(const QString& pattern, bool multiselect)
|
||||
{
|
||||
AssetSelectionModel selection;
|
||||
|
||||
RegExpFilter* patternFilter = new RegExpFilter();
|
||||
patternFilter->SetFilterPattern(pattern);
|
||||
patternFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||
auto patternFilterPtr = FilterConstType(patternFilter);
|
||||
|
||||
selection.SetDisplayFilter(patternFilterPtr);
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::AND);
|
||||
compFilter->AddFilter(patternFilterPtr);
|
||||
compFilter->AddFilter(EntryTypeNoFoldersFilter(AssetBrowserEntry::AssetEntryType::Source));
|
||||
|
||||
selection.SetSelectionFilter(FilterConstType(compFilter));
|
||||
selection.SetMultiselect(multiselect);
|
||||
@@ -204,7 +255,7 @@ namespace AzToolsFramework
|
||||
|
||||
CompositeFilter* compFilter = new CompositeFilter(CompositeFilter::LogicOperatorType::OR);
|
||||
selection.SetDisplayFilter(FilterConstType(compFilter));
|
||||
selection.SetSelectionFilter(ProductsNoFoldersFilter());
|
||||
selection.SetSelectionFilter(EntryTypeNoFoldersFilter());
|
||||
selection.SetMultiselect(multiselect);
|
||||
|
||||
return selection;
|
||||
|
||||
+10
-1
@@ -44,6 +44,10 @@ namespace AzToolsFramework
|
||||
void SetSelectedAssetIds(const AZStd::vector<AZ::Data::AssetId>& selectedAssetIds);
|
||||
void SetSelectedAssetId(const AZ::Data::AssetId& selectedAssetId);
|
||||
|
||||
const AZStd::vector<AZStd::string>& GetSelectedFilePaths() const;
|
||||
void SetSelectedFilePaths(const AZStd::vector<AZStd::string>& selectedFilePaths);
|
||||
void SetSelectedFilePath(const AZStd::string& selectedFilePath);
|
||||
|
||||
void SetDefaultDirectory(AZStd::string_view defaultDirectory);
|
||||
AZStd::string_view GetDefaultDirectory() const;
|
||||
|
||||
@@ -60,6 +64,7 @@ namespace AzToolsFramework
|
||||
static AssetSelectionModel AssetTypeSelection(const char* assetTypeName, bool multiselect = false);
|
||||
static AssetSelectionModel AssetTypesSelection(const AZStd::vector<AZ::Data::AssetType>& assetTypes, bool multiselect = false);
|
||||
static AssetSelectionModel AssetGroupSelection(const char* group, bool multiselect = false);
|
||||
static AssetSelectionModel SourceAssetTypeSelection(const QString& pattern, bool multiselect = false);
|
||||
static AssetSelectionModel EverythingSelection(bool multiselect = false);
|
||||
|
||||
private:
|
||||
@@ -68,8 +73,12 @@ namespace AzToolsFramework
|
||||
// some entries like folder should always be displayed, but not always selectable, thus 2 separate filters
|
||||
FilterConstType m_selectionFilter;
|
||||
FilterConstType m_displayFilter;
|
||||
|
||||
|
||||
//! Selection can be based on asset ids (for products), or file paths (for sources)
|
||||
//! These are mututally exclusive
|
||||
AZStd::vector<AZ::Data::AssetId> m_selectedAssetIds;
|
||||
AZStd::vector<AZStd::string> m_selectedFilePaths;
|
||||
|
||||
AZStd::vector<const AssetBrowserEntry*> m_results;
|
||||
AZStd::string m_defaultDirectory;
|
||||
|
||||
|
||||
@@ -251,6 +251,40 @@ namespace AzToolsFramework
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RegExpFilter
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
RegExpFilter::RegExpFilter()
|
||||
: m_filterPattern("")
|
||||
{
|
||||
}
|
||||
|
||||
void RegExpFilter::SetFilterPattern(const QString& filterPattern)
|
||||
{
|
||||
m_filterPattern = filterPattern;
|
||||
Q_EMIT updatedSignal();
|
||||
}
|
||||
|
||||
QString RegExpFilter::GetNameInternal() const
|
||||
{
|
||||
return m_filterPattern;
|
||||
}
|
||||
|
||||
bool RegExpFilter::MatchInternal(const AssetBrowserEntry* entry) const
|
||||
{
|
||||
// no filter pattern matches any asset
|
||||
if (m_filterPattern.isEmpty())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// entry's name matches regular expression pattern
|
||||
QRegExp regExp(m_filterPattern);
|
||||
regExp.setPatternSyntax(QRegExp::Wildcard);
|
||||
|
||||
return regExp.exactMatch(entry->GetDisplayName());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AssetTypeFilter
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -115,6 +115,28 @@ namespace AzToolsFramework
|
||||
QString m_filterString;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RegExpFilter
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//! RegExpFilter filters assets based on a regular expression pattern
|
||||
class RegExpFilter
|
||||
: public AssetBrowserEntryFilter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RegExpFilter();
|
||||
~RegExpFilter() override = default;
|
||||
|
||||
void SetFilterPattern(const QString& filterPattern);
|
||||
|
||||
protected:
|
||||
QString GetNameInternal() const override;
|
||||
bool MatchInternal(const AssetBrowserEntry* entry) const override;
|
||||
|
||||
private:
|
||||
QString m_filterPattern;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// AssetTypeFilter
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+22
-6
@@ -39,7 +39,12 @@ namespace AzToolsFramework
|
||||
typeFilter->SetAssetType(filterType);
|
||||
typeFilter->SetFilterPropagation(AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||
|
||||
m_assetBrowserFilterModel->SetFilter(FilterConstType(typeFilter));
|
||||
SetFilter(FilterConstType(typeFilter));
|
||||
}
|
||||
|
||||
void AssetCompleterModel::SetFilter(FilterConstType filter)
|
||||
{
|
||||
m_assetBrowserFilterModel->SetFilter(filter);
|
||||
|
||||
RefreshAssetList();
|
||||
}
|
||||
@@ -120,9 +125,6 @@ namespace AzToolsFramework
|
||||
int rows = m_assetBrowserFilterModel->rowCount(index);
|
||||
if (rows == 0)
|
||||
{
|
||||
if (index != QModelIndex()) {
|
||||
AZ_Error("AssetCompleterModel", false, "No children detected in FetchResources()");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,7 +133,7 @@ namespace AzToolsFramework
|
||||
QModelIndex childIndex = m_assetBrowserFilterModel->index(i, 0, index);
|
||||
AssetBrowserEntry* childEntry = GetAssetEntry(m_assetBrowserFilterModel->mapToSource(childIndex));
|
||||
|
||||
if (childEntry->GetEntryType() == AssetBrowserEntry::AssetEntryType::Product)
|
||||
if (childEntry->GetEntryType() == m_entryType)
|
||||
{
|
||||
ProductAssetBrowserEntry* productEntry = static_cast<ProductAssetBrowserEntry*>(childEntry);
|
||||
AZStd::string assetName;
|
||||
@@ -167,7 +169,6 @@ namespace AzToolsFramework
|
||||
return m_assets[index.row()].m_displayName;
|
||||
}
|
||||
|
||||
|
||||
const AZ::Data::AssetId AssetCompleterModel::GetAssetIdFromIndex(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
@@ -177,4 +178,19 @@ namespace AzToolsFramework
|
||||
|
||||
return m_assets[index.row()].m_assetId;
|
||||
}
|
||||
|
||||
const AZStd::string_view AssetCompleterModel::GetPathFromIndex(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return m_assets[index.row()].m_path;
|
||||
}
|
||||
|
||||
void AssetCompleterModel::SetFetchEntryType(AssetBrowserEntry::AssetEntryType entryType)
|
||||
{
|
||||
m_entryType = entryType;
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -32,6 +32,7 @@ namespace AzToolsFramework
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
void SetFilter(AZ::Data::AssetType filterType);
|
||||
void SetFilter(FilterConstType filter);
|
||||
void RefreshAssetList();
|
||||
void SearchStringHighlight(QString searchString);
|
||||
|
||||
@@ -39,6 +40,9 @@ namespace AzToolsFramework
|
||||
|
||||
const AZStd::string_view GetNameFromIndex(const QModelIndex& index);
|
||||
const AZ::Data::AssetId GetAssetIdFromIndex(const QModelIndex& index);
|
||||
const AZStd::string_view GetPathFromIndex(const QModelIndex& index);
|
||||
|
||||
void SetFetchEntryType(AssetBrowserEntry::AssetEntryType entryType);
|
||||
|
||||
private:
|
||||
struct AssetItem
|
||||
@@ -57,6 +61,8 @@ namespace AzToolsFramework
|
||||
AZStd::vector<AssetItem> m_assets;
|
||||
//! String that will be highlighted in the suggestions
|
||||
QString m_highlightString;
|
||||
|
||||
AssetBrowserEntry::AssetEntryType m_entryType = AssetBrowserEntry::AssetEntryType::Product;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+8
-3
@@ -1288,7 +1288,7 @@ namespace AzToolsFramework
|
||||
return newCtrl;
|
||||
}
|
||||
|
||||
void AssetPropertyHandlerDefault::ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName)
|
||||
void AssetPropertyHandlerDefault::ConsumeAttributeInternal(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName)
|
||||
{
|
||||
(void)debugName;
|
||||
|
||||
@@ -1487,6 +1487,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
}
|
||||
|
||||
void AssetPropertyHandlerDefault::ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName)
|
||||
{
|
||||
ConsumeAttributeInternal(GUI, attrib, attrValue, debugName);
|
||||
}
|
||||
|
||||
void AssetPropertyHandlerDefault::WriteGUIValuesIntoProperty(size_t index, PropertyAssetCtrl* GUI, property_t& instance, InstanceDataNode* node)
|
||||
{
|
||||
(void)index;
|
||||
@@ -1629,8 +1634,8 @@ namespace AzToolsFramework
|
||||
|
||||
void RegisterAssetPropertyHandler()
|
||||
{
|
||||
EBUS_EVENT(PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew AssetPropertyHandlerDefault());
|
||||
EBUS_EVENT(PropertyTypeRegistrationMessages::Bus, RegisterPropertyType, aznew SimpleAssetPropertyHandlerDefault());
|
||||
PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::RegisterPropertyType, aznew AssetPropertyHandlerDefault());
|
||||
PropertyTypeRegistrationMessages::Bus::Broadcast(&PropertyTypeRegistrationMessages::RegisterPropertyType, aznew SimpleAssetPropertyHandlerDefault());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-5
@@ -175,10 +175,11 @@ namespace AzToolsFramework
|
||||
virtual void SetFolderSelection(const AZStd::string& /* folderPath */) {}
|
||||
virtual void ClearAssetInternal();
|
||||
|
||||
void ConfigureAutocompleter();
|
||||
virtual void ConfigureAutocompleter();
|
||||
void RefreshAutocompleter();
|
||||
void EnableAutocompleter();
|
||||
void DisableAutocompleter();
|
||||
const QModelIndex GetSourceIndex(const QModelIndex& index);
|
||||
|
||||
void HandleFieldClear();
|
||||
AZStd::string AddDefaultSuffix(const AZStd::string& filename);
|
||||
@@ -235,20 +236,19 @@ namespace AzToolsFramework
|
||||
void SetSelectedAssetID(const AZ::Data::AssetId& newID, const AZ::Data::AssetType& newType);
|
||||
void SetCurrentAssetHint(const AZStd::string& hint);
|
||||
void SetDefaultAssetID(const AZ::Data::AssetId& defaultID);
|
||||
void PopupAssetPicker();
|
||||
virtual void PopupAssetPicker();
|
||||
void OnClearButtonClicked();
|
||||
void UpdateAssetDisplay();
|
||||
void OnLineEditFocus(bool focus);
|
||||
virtual void OnEditButtonClicked();
|
||||
void OnThumbnailClicked();
|
||||
void OnCompletionModelReset();
|
||||
void OnAutocomplete(const QModelIndex& index);
|
||||
virtual void OnAutocomplete(const QModelIndex& index);
|
||||
void OnTextChange(const QString& text);
|
||||
void OnReturnPressed();
|
||||
void ShowContextMenu(const QPoint& pos);
|
||||
|
||||
private:
|
||||
const QModelIndex GetSourceIndex(const QModelIndex& index);
|
||||
void UpdateThumbnail();
|
||||
};
|
||||
|
||||
@@ -270,7 +270,8 @@ namespace AzToolsFramework
|
||||
virtual void UpdateWidgetInternalTabbing(PropertyAssetCtrl* widget) override { widget->UpdateTabOrder(); }
|
||||
|
||||
virtual QWidget* CreateGUI(QWidget* pParent) override;
|
||||
virtual void ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||
static void ConsumeAttributeInternal(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName);
|
||||
void ConsumeAttribute(PropertyAssetCtrl* GUI, AZ::u32 attrib, PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||
virtual void WriteGUIValuesIntoProperty(size_t index, PropertyAssetCtrl* GUI, property_t& instance, InstanceDataNode* node) override;
|
||||
virtual bool ReadValuesIntoGUI(size_t index, PropertyAssetCtrl* GUI, const property_t& instance, InstanceDataNode* node) override;
|
||||
};
|
||||
|
||||
@@ -669,6 +669,7 @@ namespace GraphCanvas
|
||||
{
|
||||
GeometryNotificationBus::Handler::BusDisconnect();
|
||||
SceneNotificationBus::Handler::BusDisconnect();
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void GestureSceneHelper::TrackElement(const AZ::EntityId& elementId)
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace GraphCanvas
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("TranslationAsset", false, "Serialization of the TranslationFormat failed for: %s", asset.GetHint().c_str());
|
||||
AZ_Warning("TranslationAsset", false, "Serialization of the TranslationFormat failed for: %s", asset.GetHint().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ namespace GraphCanvas
|
||||
AZStd::string baseKey = contextStr;
|
||||
if (keyStr.empty())
|
||||
{
|
||||
AZ_Error("TranslationDatabase", false, "Every entry in the Translation data must have a key: %s", baseKey.c_str());
|
||||
AZ_Warning("TranslationDatabase", false, "Every entry in the Translation data must have a key: %s", baseKey.c_str());
|
||||
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Every entry in the Translation data must have a key");
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +26,14 @@ namespace ScriptCanvas
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
class ScriptCanvasAsset;
|
||||
|
||||
class EditorAssetConversionBusTraits
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
|
||||
|
||||
virtual AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> LoadAsset(AZStd::string_view graphPath) = 0;
|
||||
virtual AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset, AZStd::string_view graphPathForRawLuaFile) = 0;
|
||||
virtual AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset) = 0;
|
||||
virtual AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const SourceHandle& editAsset, AZStd::string_view graphPathForRawLuaFile) = 0;
|
||||
virtual AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const SourceHandle& editAsset) = 0;
|
||||
};
|
||||
|
||||
using EditorAssetConversionBus = AZ::EBus<EditorAssetConversionBusTraits>;
|
||||
|
||||
@@ -64,7 +64,6 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void EditorAssetSystemComponent::Activate()
|
||||
{
|
||||
m_editorAssetRegistry.Register<ScriptCanvasAsset, ScriptCanvasAssetHandler, ScriptCanvasAssetDescription>();
|
||||
m_editorAssetRegistry.Register<ScriptCanvas::SubgraphInterfaceAsset, ScriptCanvas::SubgraphInterfaceAssetHandler, ScriptCanvas::SubgraphInterfaceAssetDescription>();
|
||||
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect();
|
||||
@@ -98,35 +97,25 @@ namespace ScriptCanvasEditor
|
||||
return false;
|
||||
}
|
||||
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> EditorAssetSystemComponent::LoadAsset(AZStd::string_view graphPath)
|
||||
{
|
||||
auto outcome = ScriptCanvasBuilder::LoadEditorAsset(graphPath, AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
|
||||
|
||||
if (outcome.IsSuccess())
|
||||
{
|
||||
return outcome.GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> EditorAssetSystemComponent::CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset)
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> EditorAssetSystemComponent::CreateRuntimeAsset(const SourceHandle& editAsset)
|
||||
{
|
||||
return ScriptCanvasBuilder::CreateRuntimeAsset(editAsset);
|
||||
}
|
||||
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> EditorAssetSystemComponent::CreateLuaAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset, AZStd::string_view graphPathForRawLuaFile)
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> EditorAssetSystemComponent::CreateLuaAsset(const SourceHandle& editAsset, AZStd::string_view graphPathForRawLuaFile)
|
||||
{
|
||||
return ScriptCanvasBuilder::CreateLuaAsset(editAsset->GetScriptCanvasEntity(), editAsset->GetId(), graphPathForRawLuaFile);
|
||||
return ScriptCanvasBuilder::CreateLuaAsset(editAsset, graphPathForRawLuaFile);
|
||||
}
|
||||
|
||||
void EditorAssetSystemComponent::AddSourceFileOpeners([[maybe_unused]] const char* fullSourceFileName, const AZ::Uuid& sourceUuid, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers)
|
||||
void EditorAssetSystemComponent::AddSourceFileOpeners
|
||||
( [[maybe_unused]] const char* fullSourceFileName
|
||||
, const AZ::Uuid& sourceUuid
|
||||
, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers)
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
if (const SourceAssetBrowserEntry* source = SourceAssetBrowserEntry::GetSourceByUuid(sourceUuid)) // get the full details of the source file based on its UUID.
|
||||
// get the full details of the source file based on its UUID.
|
||||
if (const SourceAssetBrowserEntry* source = SourceAssetBrowserEntry::GetSourceByUuid(sourceUuid))
|
||||
{
|
||||
if (!HandlesSource(source))
|
||||
{
|
||||
@@ -138,22 +127,31 @@ namespace ScriptCanvasEditor
|
||||
// has no UUID / Not a source file.
|
||||
return;
|
||||
}
|
||||
// You can push back any number of "Openers" - choose a unique identifier, and icon, and then a lambda which will be activated if the user chooses to open it with your opener:
|
||||
openers.push_back({ "ScriptCanvas_Editor_Asset_Edit", "Script Canvas Editor...", QIcon(),
|
||||
|
||||
// You can push back any number of "Openers" - choose a unique identifier, and icon,
|
||||
// and then a lambda which will be activated if the user chooses to open it with your opener:
|
||||
|
||||
openers.push_back({ "ScriptCanvas_Editor_Asset_Edit", "Script Canvas Editor..."
|
||||
, QIcon(ScriptCanvasAssetDescription().GetIconPathImpl()),
|
||||
[](const char*, const AZ::Uuid& scSourceUuid)
|
||||
{
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
AZ::Data::AssetId sourceAssetId(scSourceUuid, 0);
|
||||
|
||||
auto& assetManager = AZ::Data::AssetManager::Instance();
|
||||
AZ::Data::Asset<ScriptCanvasAsset> scriptCanvasAsset = assetManager.GetAsset(sourceAssetId, azrtti_typeid<ScriptCanvasAsset>(), AZ::Data::AssetLoadBehavior::Default);
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, scriptCanvasAsset.GetId(), -1);
|
||||
if (!openOutcome)
|
||||
{
|
||||
AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data());
|
||||
}
|
||||
} });
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
|
||||
if (auto sourceHandle = CompleteDescription(SourceHandle(nullptr, scSourceUuid, {})))
|
||||
{
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset
|
||||
, *sourceHandle, Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
if (!openOutcome)
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", openOutcome, "%s", openOutcome.GetError().data());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false
|
||||
, "Unabled to find full path for Source UUid %s", scSourceUuid.ToString<AZStd::string>().c_str());
|
||||
}
|
||||
}});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,9 +49,8 @@ namespace ScriptCanvasEditor
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EditorAssetConversionBus::Handler...
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> LoadAsset(AZStd::string_view graphPath) override;
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset) override;
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset, AZStd::string_view graphPathForRawLuaFile) override;
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const SourceHandle& editAsset) override;
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const SourceHandle& editAsset, AZStd::string_view graphPathForRawLuaFile) override;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ScriptCanvas::AssetRegistry& GetAssetRegistry();
|
||||
|
||||
@@ -13,15 +13,50 @@
|
||||
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
|
||||
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
|
||||
namespace ScriptCanvasBuilderCpp
|
||||
namespace BuildVariableOverridesCpp
|
||||
{
|
||||
void AppendTabs(AZStd::string& result, size_t depth)
|
||||
enum Version
|
||||
{
|
||||
for (size_t i = 0; i < depth; ++i)
|
||||
Original = 1,
|
||||
EditorAssetRedux,
|
||||
|
||||
// add description above
|
||||
Current
|
||||
};
|
||||
|
||||
bool VersionConverter
|
||||
( AZ::SerializeContext& serializeContext
|
||||
, AZ::SerializeContext::DataElementNode& rootElement)
|
||||
{
|
||||
if (rootElement.GetVersion() < BuildVariableOverridesCpp::Version::EditorAssetRedux)
|
||||
{
|
||||
result += "\t";
|
||||
auto sourceIndex = rootElement.FindElement(AZ_CRC_CE("source"));
|
||||
if (sourceIndex == -1)
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, "BuildVariableOverrides coversion failed: 'source' was missing");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto& sourceElement = rootElement.GetSubElement(sourceIndex);
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
|
||||
if (!sourceElement.GetData(asset))
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, "BuildVariableOverrides coversion failed: could not retrieve 'source' data");
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptCanvasEditor::SourceHandle sourceHandle(nullptr, asset.GetId().m_guid, {});
|
||||
if (!rootElement.AddElementWithData(serializeContext, "source", sourceHandle))
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, "BuildVariableOverrides coversion failed: could not add updated 'source' data");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +64,7 @@ namespace ScriptCanvasBuilder
|
||||
{
|
||||
void BuildVariableOverrides::Clear()
|
||||
{
|
||||
m_source.Reset();
|
||||
m_source = {};
|
||||
m_variables.clear();
|
||||
m_overrides.clear();
|
||||
m_overridesUnused.clear();
|
||||
@@ -39,12 +74,20 @@ namespace ScriptCanvasBuilder
|
||||
|
||||
void BuildVariableOverrides::CopyPreviousOverriddenValues(const BuildVariableOverrides& source)
|
||||
{
|
||||
auto copyPreviousIfFound = [](ScriptCanvas::GraphVariable& overriddenValue, const AZStd::vector<ScriptCanvas::GraphVariable>& source)
|
||||
auto isEqual = [](const ScriptCanvas::GraphVariable& lhs, const ScriptCanvas::GraphVariable& rhs)
|
||||
{
|
||||
if (auto iter = AZStd::find_if(source.begin(), source.end(), [&overriddenValue](const auto& candidate) { return candidate.GetVariableId() == overriddenValue.GetVariableId(); });
|
||||
iter != source.end())
|
||||
return (lhs.GetVariableId() == rhs.GetVariableId() && lhs.GetDataType() == rhs.GetDataType())
|
||||
|| (lhs.GetVariableName() == rhs.GetVariableName() && lhs.GetDataType() == rhs.GetDataType());
|
||||
};
|
||||
|
||||
auto copyPreviousIfFound = [isEqual](ScriptCanvas::GraphVariable& overriddenValue, const AZStd::vector<ScriptCanvas::GraphVariable>& source)
|
||||
{
|
||||
auto iter = AZStd::find_if(source.begin(), source.end()
|
||||
, [&overriddenValue, isEqual](const auto& candidate) { return isEqual(candidate, overriddenValue); });
|
||||
|
||||
if (iter != source.end())
|
||||
{
|
||||
overriddenValue.DeepCopy(*iter);
|
||||
overriddenValue.ModDatum().DeepCopyDatum(*iter->GetDatum());
|
||||
overriddenValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide);
|
||||
overriddenValue.SetAllowSignalOnChange(false);
|
||||
return true;
|
||||
@@ -64,6 +107,15 @@ namespace ScriptCanvasBuilder
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& overriddenValue : m_overridesUnused)
|
||||
{
|
||||
if (!copyPreviousIfFound(overriddenValue, source.m_overridesUnused))
|
||||
{
|
||||
// the variable in question may have been previously used, and is now unused, so copy the previous value over
|
||||
copyPreviousIfFound(overriddenValue, source.m_overrides);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one.
|
||||
// the above will provide the data to handle the cases where only certain dependency nodes were removed
|
||||
@@ -100,7 +152,7 @@ namespace ScriptCanvasBuilder
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
|
||||
{
|
||||
serializeContext->Class<BuildVariableOverrides>()
|
||||
->Version(1)
|
||||
->Version(BuildVariableOverridesCpp::Version::Current, &BuildVariableOverridesCpp::VersionConverter)
|
||||
->Field("source", &BuildVariableOverrides::m_source)
|
||||
->Field("variables", &BuildVariableOverrides::m_variables)
|
||||
->Field("entityId", &BuildVariableOverrides::m_entityIds)
|
||||
@@ -194,45 +246,12 @@ namespace ScriptCanvasBuilder
|
||||
}
|
||||
}
|
||||
|
||||
EditorAssetTree* EditorAssetTree::ModRoot()
|
||||
{
|
||||
if (!m_parent)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return m_parent->ModRoot();
|
||||
}
|
||||
|
||||
void EditorAssetTree::SetParent(EditorAssetTree& parent)
|
||||
{
|
||||
m_parent = &parent;
|
||||
}
|
||||
|
||||
AZStd::string EditorAssetTree::ToString(size_t depth) const
|
||||
{
|
||||
AZStd::string result;
|
||||
ScriptCanvasBuilderCpp::AppendTabs(result, depth);
|
||||
result += m_asset.GetId().ToString<AZStd::string>();
|
||||
result += m_asset.GetHint();
|
||||
depth += m_dependencies.empty() ? 0 : 1;
|
||||
|
||||
for (const auto& dependency : m_dependencies)
|
||||
{
|
||||
result += "\n";
|
||||
ScriptCanvasBuilderCpp::AppendTabs(result, depth);
|
||||
result += dependency.ToString(depth);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& buildOverrides)
|
||||
{
|
||||
ScriptCanvas::RuntimeDataOverrides runtimeOverrides;
|
||||
|
||||
runtimeOverrides.m_runtimeAsset = AZ::Data::Asset<ScriptCanvas::RuntimeAsset>
|
||||
(AZ::Data::AssetId(buildOverrides.m_source.GetId().m_guid, AZ_CRC("RuntimeData", 0x163310ae)), azrtti_typeid<ScriptCanvas::RuntimeAsset>(), {});
|
||||
(AZ::Data::AssetId(buildOverrides.m_source.Id(), AZ_CRC("RuntimeData", 0x163310ae)), azrtti_typeid<ScriptCanvas::RuntimeAsset>(), {});
|
||||
runtimeOverrides.m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
runtimeOverrides.m_variableIndices.resize(buildOverrides.m_variables.size());
|
||||
|
||||
@@ -295,76 +314,9 @@ namespace ScriptCanvasBuilder
|
||||
return runtimeOverrides;
|
||||
}
|
||||
|
||||
AZ::Outcome<EditorAssetTree, AZStd::string> LoadEditorAssetTree(AZ::Data::AssetId editorAssetId, AZStd::string_view assetHint, EditorAssetTree* parent)
|
||||
AZ::Outcome<BuildVariableOverrides, AZStd::string> ParseEditorAssetTree(const ScriptCanvasEditor::EditorAssetTree& editorAssetTree)
|
||||
{
|
||||
EditorAssetTree result;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
AZStd::string watchFolder;
|
||||
bool resultFound = false;
|
||||
|
||||
if (!AzToolsFramework::AssetSystemRequestBus::FindFirstHandler())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("LoadEditorAssetTree found no handler for AzToolsFramework::AssetSystemRequestBus."));
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
|
||||
( resultFound
|
||||
, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourceUUID
|
||||
, editorAssetId.m_guid
|
||||
, assetInfo
|
||||
, watchFolder);
|
||||
|
||||
if (!resultFound)
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%.*s.", editorAssetId.ToString<AZStd::string>().c_str(), aznumeric_cast<int>(assetHint.size()), assetHint.data()));
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::Data::AssetId> dependentAssets;
|
||||
|
||||
auto filterCB = [&dependentAssets](const AZ::Data::AssetFilterInfo& filterInfo)->bool
|
||||
{
|
||||
if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvas::SubgraphInterfaceAsset>())
|
||||
{
|
||||
dependentAssets.push_back(AZ::Data::AssetId(filterInfo.m_assetId.m_guid, 0));
|
||||
}
|
||||
else if (filterInfo.m_assetType == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
|
||||
{
|
||||
dependentAssets.push_back(filterInfo.m_assetId);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
auto loadAssetOutcome = ScriptCanvasBuilder::LoadEditorAsset(assetInfo.m_relativePath, editorAssetId, filterCB);
|
||||
if (!loadAssetOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load graph from %s-%s: %s", editorAssetId.ToString<AZStd::string>().c_str(), assetHint.data(), loadAssetOutcome.GetError().c_str()));
|
||||
}
|
||||
|
||||
for (auto& dependentAsset : dependentAssets)
|
||||
{
|
||||
auto loadDependentOutcome = LoadEditorAssetTree(dependentAsset, "", &result);
|
||||
if (!loadDependentOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load dependent graph from %s-%s: %s", editorAssetId.ToString<AZStd::string>().c_str(), assetHint.data(), loadDependentOutcome.GetError().c_str()));
|
||||
}
|
||||
|
||||
result.m_dependencies.push_back(loadDependentOutcome.TakeValue());
|
||||
}
|
||||
|
||||
if (parent)
|
||||
{
|
||||
result.SetParent(*parent);
|
||||
}
|
||||
|
||||
result.m_asset = loadAssetOutcome.TakeValue();
|
||||
|
||||
return AZ::Success(result);
|
||||
}
|
||||
|
||||
AZ::Outcome<BuildVariableOverrides, AZStd::string> ParseEditorAssetTree(const EditorAssetTree& editorAssetTree)
|
||||
{
|
||||
auto buildEntity = editorAssetTree.m_asset->GetScriptCanvasEntity();
|
||||
auto buildEntity = editorAssetTree.m_asset.Get()->GetEntity();
|
||||
if (!buildEntity)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("No entity from source asset"));
|
||||
@@ -400,9 +352,8 @@ namespace ScriptCanvasBuilder
|
||||
if (!parseDependentOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format
|
||||
( "ParseEditorAssetTree failed to parse dependent graph from %s-%s: %s"
|
||||
, dependentAsset.m_asset.GetId().ToString<AZStd::string>().c_str()
|
||||
, dependentAsset.m_asset.GetHint().c_str()
|
||||
( "ParseEditorAssetTree failed to parse dependent graph from %s: %s"
|
||||
, dependentAsset.m_asset.ToString().c_str()
|
||||
, parseDependentOutcome.GetError().c_str()));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
class ScriptCanvasAsset;
|
||||
class EditorAssetTree;
|
||||
}
|
||||
|
||||
namespace ScriptCanvasBuilder
|
||||
@@ -39,8 +40,8 @@ namespace ScriptCanvasBuilder
|
||||
void PopulateFromParsedResults(ScriptCanvas::Grammar::AbstractCodeModelConstPtr abstractCodeModel, const ScriptCanvas::VariableData& variables);
|
||||
|
||||
// #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one.
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> m_source;
|
||||
|
||||
ScriptCanvasEditor::SourceHandle m_source;
|
||||
|
||||
// all of the variables here are overrides
|
||||
AZStd::vector<ScriptCanvas::GraphVariable> m_variables;
|
||||
// the values here may or may not be overrides
|
||||
@@ -48,30 +49,11 @@ namespace ScriptCanvasBuilder
|
||||
// these two variable lists are all that gets exposed to the edit context
|
||||
AZStd::vector<ScriptCanvas::GraphVariable> m_overrides;
|
||||
AZStd::vector<ScriptCanvas::GraphVariable> m_overridesUnused;
|
||||
// AZStd::vector<size_t> m_entityIdRuntimeInputIndices; since all of the entity ids need to go in, they may not need indices
|
||||
AZStd::vector<BuildVariableOverrides> m_dependencies;
|
||||
};
|
||||
|
||||
class EditorAssetTree
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(EditorAssetTree, AZ::SystemAllocator, 0);
|
||||
|
||||
EditorAssetTree* m_parent = nullptr;
|
||||
AZStd::vector<EditorAssetTree> m_dependencies;
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> m_asset;
|
||||
|
||||
EditorAssetTree* ModRoot();
|
||||
|
||||
void SetParent(EditorAssetTree& parent);
|
||||
|
||||
AZStd::string ToString(size_t depth = 0) const;
|
||||
};
|
||||
|
||||
// copy the variables overridden during editor / prefab build time back to runtime data
|
||||
ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& overrides);
|
||||
|
||||
AZ::Outcome<EditorAssetTree, AZStd::string> LoadEditorAssetTree(AZ::Data::AssetId editorAssetId, AZStd::string_view assetHint, EditorAssetTree* parent = nullptr);
|
||||
|
||||
AZ::Outcome<BuildVariableOverrides, AZStd::string> ParseEditorAssetTree(const EditorAssetTree& editorAssetTree);
|
||||
AZ::Outcome<BuildVariableOverrides, AZStd::string> ParseEditorAssetTree(const ScriptCanvasEditor::EditorAssetTree& editorAssetTree);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,6 @@ namespace ScriptCanvasBuilder
|
||||
SharedHandlers HandleAssetTypes()
|
||||
{
|
||||
SharedHandlers handlers;
|
||||
handlers.m_editorAssetHandler = RegisterHandler<ScriptCanvasEditor::ScriptCanvasAsset, ScriptCanvasEditor::ScriptCanvasAssetHandler>("scriptcanvas", false);
|
||||
handlers.m_subgraphInterfaceHandler = RegisterHandler<ScriptCanvas::SubgraphInterfaceAsset, ScriptCanvas::SubgraphInterfaceAssetHandler>("scriptcanvas_fn_compiled", true);
|
||||
handlers.m_runtimeAssetHandler = RegisterHandler<ScriptCanvas::RuntimeAsset, JobDependencyVerificationHandler>("scriptcanvas_compiled", true);
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
|
||||
#include <ScriptCanvas/Asset/SubgraphInterfaceAssetHandler.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
|
||||
#include <ScriptCanvas/Core/Connection.h>
|
||||
@@ -27,12 +28,12 @@
|
||||
#include <ScriptCanvas/Grammar/AbstractCodeModel.h>
|
||||
#include <ScriptCanvas/Results/ErrorText.h>
|
||||
#include <ScriptCanvas/Utils/BehaviorContextUtils.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
|
||||
namespace ScriptCanvasBuilder
|
||||
{
|
||||
void Worker::Activate(const AssetHandlers& handlers)
|
||||
{
|
||||
m_editorAssetHandler = handlers.m_editorAssetHandler;
|
||||
m_runtimeAssetHandler = handlers.m_runtimeAssetHandler;
|
||||
m_subgraphInterfaceHandler = handlers.m_subgraphInterfaceHandler;
|
||||
}
|
||||
@@ -44,54 +45,22 @@ namespace ScriptCanvasBuilder
|
||||
AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.data(), request.m_sourceFile.data(), fullPath, false);
|
||||
AzFramework::StringFunc::Path::Normalize(fullPath);
|
||||
|
||||
if (!m_editorAssetHandler)
|
||||
{
|
||||
AZ_Error(s_scriptCanvasBuilder, false, R"(CreateJobs for %s failed because the ScriptCanvas Editor Asset handler is missing.)", fullPath.data());
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
|
||||
|
||||
AZ::IO::FileIOStream stream(fullPath.c_str(), AZ::IO::OpenMode::ModeRead);
|
||||
if (!AZ::IO::RetryOpenStream(stream))
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
|
||||
{
|
||||
AZ::IO::FileIOStream ioStream;
|
||||
if (!ioStream.Open(fullPath.data(), AZ::IO::OpenMode::ModeRead))
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::vector<AZ::u8> fileBuffer(ioStream.GetLength());
|
||||
size_t bytesRead = ioStream.Read(fileBuffer.size(), fileBuffer.data());
|
||||
if (bytesRead != ioStream.GetLength())
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, AZStd::string::format("File failed to read completely: %s", fullPath.data()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
assetDataStream->Open(AZStd::move(fileBuffer));
|
||||
}
|
||||
|
||||
m_processEditorAssetDependencies.clear();
|
||||
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
|
||||
asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom()));
|
||||
if (m_editorAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, {}) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the asset data could not be loaded from the file", fullPath.data());
|
||||
return;
|
||||
}
|
||||
const ScriptCanvasEditor::Graph* sourceGraph = nullptr;
|
||||
const ScriptCanvas::GraphData* graphData = nullptr;
|
||||
|
||||
auto* scriptCanvasEntity = asset.Get()->GetScriptCanvasEntity();
|
||||
auto* sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvasEditor::Graph>(scriptCanvasEntity);
|
||||
ScriptCanvasEditor::SourceHandle sourceHandle;
|
||||
|
||||
auto sourceOutcome = ScriptCanvasEditor::LoadFromFile(fullPath);
|
||||
if (sourceOutcome.IsSuccess())
|
||||
{
|
||||
sourceHandle = sourceOutcome.TakeValue();
|
||||
sourceGraph = sourceHandle.Get();
|
||||
graphData = sourceGraph->GetGraphDataConst();
|
||||
}
|
||||
|
||||
AZ_Assert(sourceGraph, "Graph component is missing from entity.");
|
||||
AZ_Assert(sourceGraph->GetGraphData(), "GraphData is missing from entity");
|
||||
AZ_Assert(graphData, "GraphData is missing from entity");
|
||||
|
||||
struct EntityIdComparer
|
||||
{
|
||||
@@ -102,7 +71,7 @@ namespace ScriptCanvasBuilder
|
||||
return lhsEntityId < rhsEntityId;
|
||||
}
|
||||
};
|
||||
const AZStd::set<AZ::Entity*, EntityIdComparer> sortedEntities(sourceGraph->GetGraphData()->m_nodes.begin(), sourceGraph->GetGraphData()->m_nodes.end());
|
||||
const AZStd::set<AZ::Entity*, EntityIdComparer> sortedEntities(graphData->m_nodes.begin(), graphData->m_nodes.end());
|
||||
|
||||
size_t fingerprint = 0;
|
||||
for (const auto& nodeEntity : sortedEntities)
|
||||
@@ -155,7 +124,7 @@ namespace ScriptCanvasBuilder
|
||||
};
|
||||
|
||||
AZ_Verify(serializeContext->EnumerateInstanceConst
|
||||
( sourceGraph->GetGraphData()
|
||||
( graphData
|
||||
, azrtti_typeid<ScriptCanvas::GraphData>()
|
||||
, assetFilter
|
||||
, {}
|
||||
@@ -168,17 +137,6 @@ namespace ScriptCanvasBuilder
|
||||
|
||||
for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms)
|
||||
{
|
||||
if (info.HasTag("tools"))
|
||||
{
|
||||
AssetBuilderSDK::JobDescriptor copyDescriptor;
|
||||
copyDescriptor.m_priority = 2;
|
||||
copyDescriptor.m_critical = true;
|
||||
copyDescriptor.m_jobKey = s_scriptCanvasCopyJobKey;
|
||||
copyDescriptor.SetPlatformIdentifier(info.m_identifier.c_str());
|
||||
copyDescriptor.m_additionalFingerprintInfo = AZStd::string(GetFingerprintString()).append("|").append(AZStd::to_string(static_cast<AZ::u64>(fingerprint)));
|
||||
response.m_createJobOutputs.push_back(copyDescriptor);
|
||||
}
|
||||
|
||||
AssetBuilderSDK::JobDescriptor jobDescriptor;
|
||||
jobDescriptor.m_priority = 2;
|
||||
jobDescriptor.m_critical = true;
|
||||
@@ -244,49 +202,14 @@ namespace ScriptCanvasBuilder
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_editorAssetHandler)
|
||||
{
|
||||
AZ_Error(s_scriptCanvasBuilder, false, R"(Exporting of .scriptcanvas for "%s" file failed as no editor asset handler was registered for script canvas. The ScriptCanvas Gem might not be enabled.)", fullPath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_runtimeAssetHandler)
|
||||
{
|
||||
AZ_Error(s_scriptCanvasBuilder, false, R"(Exporting of .scriptcanvas for "%s" file failed as no runtime asset handler was registered for script canvas.)", fullPath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<AZ::Data::AssetDataStream> assetDataStream = AZStd::make_shared<AZ::Data::AssetDataStream>();
|
||||
|
||||
AZ::IO::FileIOStream stream(fullPath.c_str(), AZ::IO::OpenMode::ModeRead);
|
||||
if (!AZ::IO::RetryOpenStream(stream))
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream
|
||||
{
|
||||
AZ::IO::FileIOStream ioStream;
|
||||
if (!ioStream.Open(fullPath.data(), AZ::IO::OpenMode::ModeRead))
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data());
|
||||
return;
|
||||
}
|
||||
AZStd::vector<AZ::u8> fileBuffer(ioStream.GetLength());
|
||||
size_t bytesRead = ioStream.Read(fileBuffer.size(), fileBuffer.data());
|
||||
if (bytesRead != ioStream.GetLength())
|
||||
{
|
||||
AZ_Warning(s_scriptCanvasBuilder, false, AZStd::string::format("File failed to read completely: %s", fullPath.data()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
assetDataStream->Open(AZStd::move(fileBuffer));
|
||||
}
|
||||
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> asset;
|
||||
asset.Create(request.m_sourceFileUUID);
|
||||
if (m_editorAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, nullptr) != AZ::Data::AssetHandler::LoadResult::LoadComplete)
|
||||
auto loadOutcome = ScriptCanvasEditor::LoadFromFile(request.m_fullPath);
|
||||
if (!loadOutcome.IsSuccess())
|
||||
{
|
||||
AZ_Error(s_scriptCanvasBuilder, false, R"(Loading of ScriptCanvas asset for source file "%s" has failed)", fullPath.data());
|
||||
return;
|
||||
@@ -299,23 +222,11 @@ namespace ScriptCanvasBuilder
|
||||
AzFramework::StringFunc::Path::Join(request.m_tempDirPath.c_str(), fileNameOnly.c_str(), runtimeScriptCanvasOutputPath, true, true);
|
||||
AzFramework::StringFunc::Path::ReplaceExtension(runtimeScriptCanvasOutputPath, ScriptCanvas::RuntimeAsset::GetFileExtension());
|
||||
|
||||
if (request.m_jobDescription.m_jobKey == s_scriptCanvasCopyJobKey)
|
||||
{
|
||||
// ScriptCanvas Editor Asset Copy job
|
||||
// The SubID is zero as this represents the main asset
|
||||
AssetBuilderSDK::JobProduct jobProduct;
|
||||
jobProduct.m_productFileName = fullPath;
|
||||
jobProduct.m_productAssetType = azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>();
|
||||
jobProduct.m_productSubID = 0;
|
||||
jobProduct.m_dependenciesHandled = true;
|
||||
jobProduct.m_dependencies.clear();
|
||||
response.m_outputProducts.push_back(AZStd::move(jobProduct));
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ::Entity* buildEntity = asset.Get()->GetScriptCanvasEntity();
|
||||
auto sourceHandle = loadOutcome.TakeValue();
|
||||
|
||||
if (request.m_jobDescription.m_jobKey == s_scriptCanvasProcessJobKey)
|
||||
{
|
||||
AZ::Entity* buildEntity = sourceHandle.Get()->GetEntity();
|
||||
ProcessTranslationJobInput input;
|
||||
input.assetID = AZ::Data::AssetId(request.m_sourceFileUUID, AZ_CRC("RuntimeData", 0x163310ae));
|
||||
input.request = &request;
|
||||
@@ -370,7 +281,8 @@ namespace ScriptCanvasBuilder
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AzFramework::StringFunc::Find(fileNameOnly, s_unitTestParseErrorPrefix) != AZStd::string::npos)
|
||||
if (!ScriptCanvas::Grammar::g_processingErrorsForUnitTestsEnabled
|
||||
&& AzFramework::StringFunc::Find(fileNameOnly, s_unitTestParseErrorPrefix) != AZStd::string::npos)
|
||||
{
|
||||
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
class Graph;
|
||||
class ScriptCanvasAsset;
|
||||
class SourceHandle;
|
||||
}
|
||||
|
||||
namespace ScriptCanvasBuilder
|
||||
{
|
||||
constexpr const char* s_scriptCanvasBuilder = "ScriptCanvasBuilder";
|
||||
constexpr const char* s_scriptCanvasCopyJobKey = "Script Canvas Copy Job";
|
||||
constexpr const char* s_scriptCanvasProcessJobKey = "Script Canvas Process Job";
|
||||
constexpr const char* s_unitTestParseErrorPrefix = "LY_SC_UnitTest";
|
||||
|
||||
@@ -59,6 +59,8 @@ namespace ScriptCanvasBuilder
|
||||
PrefabIntegration,
|
||||
CorrectGraphVariableVersion,
|
||||
ReflectEntityIdNodes,
|
||||
FixExecutionStateNodeableConstruction,
|
||||
|
||||
// add new entries above
|
||||
Current,
|
||||
};
|
||||
@@ -69,7 +71,6 @@ namespace ScriptCanvasBuilder
|
||||
|
||||
struct AssetHandlers
|
||||
{
|
||||
AZ::Data::AssetHandler* m_editorAssetHandler = nullptr;
|
||||
AZ::Data::AssetHandler* m_editorFunctionAssetHandler = nullptr;
|
||||
AZ::Data::AssetHandler* m_runtimeAssetHandler = nullptr;
|
||||
AZ::Data::AssetHandler* m_subgraphInterfaceHandler = nullptr;
|
||||
@@ -80,7 +81,6 @@ namespace ScriptCanvasBuilder
|
||||
|
||||
struct SharedHandlers
|
||||
{
|
||||
HandlerOwnership m_editorAssetHandler{};
|
||||
HandlerOwnership m_editorFunctionAssetHandler{};
|
||||
HandlerOwnership m_runtimeAssetHandler{};
|
||||
HandlerOwnership m_subgraphInterfaceHandler{};
|
||||
@@ -122,13 +122,13 @@ namespace ScriptCanvasBuilder
|
||||
}
|
||||
};
|
||||
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& asset);
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const ScriptCanvasEditor::SourceHandle& asset);
|
||||
|
||||
AZ::Outcome<ScriptCanvas::GraphData, AZStd::string> CompileGraphData(AZ::Entity* scriptCanvasEntity);
|
||||
|
||||
AZ::Outcome<ScriptCanvas::VariableData, AZStd::string> CompileVariableData(AZ::Entity* scriptCanvasEntity);
|
||||
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(AZ::Entity* buildEntity, AZ::Data::AssetId scriptAssetId, AZStd::string_view rawLuaFilePath);
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const ScriptCanvasEditor::SourceHandle& editAsset, AZStd::string_view rawLuaFilePath);
|
||||
|
||||
int GetBuilderVersion();
|
||||
|
||||
@@ -169,7 +169,6 @@ namespace ScriptCanvasBuilder
|
||||
void ShutDown() override {};
|
||||
|
||||
private:
|
||||
AZ::Data::AssetHandler* m_editorAssetHandler = nullptr;
|
||||
AZ::Data::AssetHandler* m_runtimeAssetHandler = nullptr;
|
||||
AZ::Data::AssetHandler* m_subgraphInterfaceHandler = nullptr;
|
||||
|
||||
|
||||
@@ -29,19 +29,20 @@
|
||||
#include <ScriptCanvas/Results/ErrorText.h>
|
||||
#include <ScriptCanvas/Utils/BehaviorContextUtils.h>
|
||||
#include <Source/Components/SceneComponent.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
|
||||
|
||||
namespace ScriptCanvasBuilder
|
||||
{
|
||||
AssetHandlers::AssetHandlers(SharedHandlers& source)
|
||||
: m_editorAssetHandler(source.m_editorAssetHandler.first)
|
||||
, m_editorFunctionAssetHandler(source.m_editorFunctionAssetHandler.first)
|
||||
: m_editorFunctionAssetHandler(source.m_editorFunctionAssetHandler.first)
|
||||
, m_runtimeAssetHandler(source.m_runtimeAssetHandler.first)
|
||||
, m_subgraphInterfaceHandler(source.m_subgraphInterfaceHandler.first)
|
||||
{}
|
||||
|
||||
void SharedHandlers::DeleteOwnedHandlers()
|
||||
{
|
||||
DeleteIfOwned(m_editorAssetHandler);
|
||||
DeleteIfOwned(m_editorFunctionAssetHandler);
|
||||
DeleteIfOwned(m_runtimeAssetHandler);
|
||||
DeleteIfOwned(m_subgraphInterfaceHandler);
|
||||
@@ -77,36 +78,23 @@ namespace ScriptCanvasBuilder
|
||||
return ScriptCanvas::Translation::ParseGraph(request);
|
||||
}
|
||||
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(AZ::Entity* buildEntity, AZ::Data::AssetId scriptAssetId, AZStd::string_view rawLuaFilePath)
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> CreateLuaAsset(const ScriptCanvasEditor::SourceHandle& editAsset, AZStd::string_view rawLuaFilePath)
|
||||
{
|
||||
AZStd::string fullPath(rawLuaFilePath);
|
||||
AZStd::string fileNameOnly;
|
||||
AzFramework::StringFunc::Path::GetFullFileName(rawLuaFilePath.data(), fileNameOnly);
|
||||
AzFramework::StringFunc::Path::Normalize(fullPath);
|
||||
|
||||
auto sourceGraph = PrepareSourceGraph(buildEntity);
|
||||
auto sourceGraph = PrepareSourceGraph(editAsset.Mod()->GetEntity());
|
||||
|
||||
ScriptCanvas::Grammar::Request request;
|
||||
request.scriptAssetId = scriptAssetId;
|
||||
request.scriptAssetId = editAsset.Id();
|
||||
request.graph = sourceGraph;
|
||||
request.name = fileNameOnly;
|
||||
request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile;
|
||||
request.printModelToConsole = ScriptCanvas::Grammar::g_printAbstractCodeModel;
|
||||
request.path = fullPath;
|
||||
|
||||
bool pathFound = false;
|
||||
AZStd::string relativePath;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
|
||||
( pathFound
|
||||
, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath
|
||||
, fullPath.c_str(), relativePath);
|
||||
|
||||
if (!pathFound)
|
||||
{
|
||||
AZ::Failure(AZStd::string::format("Failed to get engine relative path from %s", fullPath.c_str()));
|
||||
}
|
||||
|
||||
request.namespacePath = relativePath;
|
||||
const ScriptCanvas::Translation::Result translationResult = TranslateToLua(request);
|
||||
|
||||
auto isSuccessOutcome = translationResult.IsSuccess(ScriptCanvas::Translation::TargetFlags::Lua);
|
||||
@@ -117,7 +105,7 @@ namespace ScriptCanvasBuilder
|
||||
|
||||
auto& translation = translationResult.m_translations.find(ScriptCanvas::Translation::TargetFlags::Lua)->second;
|
||||
AZ::Data::Asset<AZ::ScriptAsset> asset;
|
||||
scriptAssetId.m_subId = AZ::ScriptAsset::CompiledAssetSubId;
|
||||
AZ::Data::AssetId scriptAssetId(editAsset.Id(), AZ::ScriptAsset::CompiledAssetSubId);
|
||||
asset.Create(scriptAssetId);
|
||||
auto writeStream = asset.Get()->CreateWriteStream();
|
||||
|
||||
@@ -144,12 +132,12 @@ namespace ScriptCanvasBuilder
|
||||
return AZ::Success(result);
|
||||
}
|
||||
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>& editAsset)
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> CreateRuntimeAsset(const ScriptCanvasEditor::SourceHandle& editAsset)
|
||||
{
|
||||
// Flush asset manager events to ensure no asset references are held by closures queued on Ebuses.
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
|
||||
auto runtimeAssetId = editAsset.GetId();
|
||||
AZ::Data::AssetId runtimeAssetId = editAsset.Id();
|
||||
runtimeAssetId.m_subId = AZ_CRC("RuntimeData", 0x163310ae);
|
||||
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> runtimeAsset;
|
||||
runtimeAsset.Create(runtimeAssetId);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
|
||||
@@ -93,49 +94,6 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> LoadScriptCanvasDataFromJson
|
||||
( ScriptCanvas::ScriptCanvasData& dataTarget
|
||||
, AZStd::string_view source
|
||||
, AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
namespace JSRU = AZ::JsonSerializationUtils;
|
||||
using namespace ScriptCanvas;
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = &serializeContext;
|
||||
settings.m_metadata.Create<SerializationListeners>();
|
||||
|
||||
auto loadResult = JSRU::LoadObjectFromStringByType
|
||||
( &dataTarget
|
||||
, azrtti_typeid<ScriptCanvasData>()
|
||||
, source
|
||||
, &settings);
|
||||
|
||||
if (!loadResult.IsSuccess())
|
||||
{
|
||||
return loadResult;
|
||||
}
|
||||
|
||||
if (auto graphData = dataTarget.ModGraph())
|
||||
{
|
||||
auto listeners = settings.m_metadata.Find<SerializationListeners>();
|
||||
AZ_Assert(listeners, "Failed to find SerializationListeners");
|
||||
|
||||
ScriptCanvasAssetHandlerCpp::CollectNodes(graphData->GetGraphData()->m_nodes, *listeners);
|
||||
|
||||
for (auto listener : *listeners)
|
||||
{
|
||||
listener->OnDeserialize();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Failed to find graph data after loading source"));
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData
|
||||
( const AZ::Data::Asset<AZ::Data::AssetData>& assetTarget
|
||||
, AZStd::shared_ptr<AZ::Data::AssetDataStream> streamSource
|
||||
@@ -167,7 +125,7 @@ namespace ScriptCanvasEditor
|
||||
settings.m_serializeContext = m_serializeContext;
|
||||
settings.m_metadata.Create<SerializationListeners>();
|
||||
// attempt JSON deserialization...
|
||||
auto jsonResult = LoadScriptCanvasDataFromJson
|
||||
auto jsonResult = LoadDataFromJson
|
||||
( scriptCanvasDataTarget
|
||||
, AZStd::string_view{ byteBuffer.begin(), byteBuffer.size() }
|
||||
, *m_serializeContext);
|
||||
@@ -228,6 +186,7 @@ namespace ScriptCanvasEditor
|
||||
, AZ::IO::GenericStream* stream
|
||||
, [[maybe_unused]] AZ::DataStream::StreamType streamType)
|
||||
{
|
||||
// #sc_editor_asset delete usage of this, and route to ScriptCanvasEditor::SaveToStream
|
||||
namespace JSRU = AZ::JsonSerializationUtils;
|
||||
using namespace ScriptCanvas;
|
||||
|
||||
|
||||
@@ -82,30 +82,6 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void ScriptCanvasAssetHolder::OpenEditor() const
|
||||
{
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
|
||||
if (m_scriptCanvasAsset.IsReady())
|
||||
{
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_scriptCanvasAsset.GetId(), -1);
|
||||
|
||||
if (!openOutcome)
|
||||
{
|
||||
AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data());
|
||||
}
|
||||
}
|
||||
else if (m_ownerId.first.IsValid())
|
||||
{
|
||||
AzToolsFramework::EntityIdList selectedEntityIds;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
|
||||
|
||||
// Going to bypass the multiple selected entities flow for right now.
|
||||
if (selectedEntityIds.size() == 1)
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::CreateScriptCanvasAssetFor, m_ownerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScriptCanvas::ScriptCanvasId ScriptCanvasAssetHolder::GetScriptCanvasId() const
|
||||
|
||||
@@ -58,111 +58,8 @@ namespace ScriptCanvasEditor
|
||||
SaveAs(assetId, {}, onSaveCallback);
|
||||
}
|
||||
|
||||
void AssetTracker::SaveAs(AZ::Data::AssetId assetId, const AZStd::string& path, Callbacks::OnSave onSaveCallback)
|
||||
void AssetTracker::SaveAs(AZ::Data::AssetId /*assetId*/, const AZStd::string& /*path*/, Callbacks::OnSave /*onSaveCallback*/)
|
||||
{
|
||||
auto assetIter = m_assetsInUse.find(assetId);
|
||||
|
||||
if (assetIter != m_assetsInUse.end())
|
||||
{
|
||||
auto onSave = [this, assetId, onSaveCallback](bool saveSuccess, AZ::Data::AssetPtr asset, AZ::Data::AssetId previousFileAssetId)
|
||||
{
|
||||
AZ::Data::AssetId signalId = assetId;
|
||||
AZ::Data::AssetId fileAssetId = asset->GetId();
|
||||
|
||||
// If there is a previous file Id is valid, it means this is a save-as operation and we need to remap the tracking.
|
||||
if (previousFileAssetId.IsValid())
|
||||
{
|
||||
if (saveSuccess)
|
||||
{
|
||||
fileAssetId = m_assetsInUse[assetId]->GetFileAssetId();
|
||||
m_remappedAsset[asset->GetId()] = fileAssetId;
|
||||
|
||||
// Erase the asset first so the smart pointer can deal with it's things.
|
||||
m_assetsInUse.erase(fileAssetId);
|
||||
|
||||
// Then perform the insert once we know nothing will attempt to delete this while we are operating on it.
|
||||
m_assetsInUse[fileAssetId] = m_assetsInUse[assetId];
|
||||
m_assetsInUse.erase(assetId);
|
||||
}
|
||||
|
||||
m_savingAssets.erase(assetId);
|
||||
m_savingAssets.insert(fileAssetId);
|
||||
|
||||
signalId = fileAssetId;
|
||||
|
||||
if (m_queuedCloses.erase(assetId))
|
||||
{
|
||||
m_queuedCloses.insert(fileAssetId);
|
||||
}
|
||||
|
||||
auto assetIter = m_assetsInUse.find(fileAssetId);
|
||||
|
||||
if (assetIter != m_assetsInUse.end())
|
||||
{
|
||||
AZStd::invoke(onSaveCallback, saveSuccess, m_assetsInUse[fileAssetId]->GetAsset().Get(), previousFileAssetId);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Error("ScriptCanvas", !saveSuccess, "Unable to find Memory Asset for Asset(%s)", fileAssetId.ToString<AZStd::string>().c_str());
|
||||
AZStd::invoke(onSaveCallback, saveSuccess, asset, previousFileAssetId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (saveSuccess)
|
||||
{
|
||||
// This should be the case when we get a save as from a newly created file.
|
||||
//
|
||||
// If we find the 'memory' asset id in the assets in use. This means this was a new file that was saved.
|
||||
// To maintain all of the look-up stuff, we need to treat this like a remapping stage.
|
||||
auto assetInUseIter = m_assetsInUse.find(assetId);
|
||||
if (assetInUseIter != m_assetsInUse.end())
|
||||
{
|
||||
fileAssetId = assetInUseIter->second->GetFileAssetId();
|
||||
|
||||
if (assetId != fileAssetId)
|
||||
{
|
||||
m_remappedAsset[assetId] = fileAssetId;
|
||||
|
||||
m_assetsInUse.erase(fileAssetId);
|
||||
m_assetsInUse[fileAssetId] = AZStd::move(assetInUseIter->second);
|
||||
m_assetsInUse.erase(assetId);
|
||||
|
||||
m_savingAssets.erase(assetId);
|
||||
m_savingAssets.insert(fileAssetId);
|
||||
|
||||
if (m_queuedCloses.erase(assetId))
|
||||
{
|
||||
m_queuedCloses.insert(fileAssetId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileAssetId = CheckAssetId(fileAssetId);
|
||||
}
|
||||
|
||||
signalId = fileAssetId;
|
||||
}
|
||||
|
||||
if (onSaveCallback)
|
||||
{
|
||||
AZStd::invoke(onSaveCallback, saveSuccess, m_assetsInUse[signalId]->GetAsset().Get(), previousFileAssetId);
|
||||
}
|
||||
|
||||
AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetSaved, m_assetsInUse[signalId], saveSuccess);
|
||||
}
|
||||
|
||||
SignalSaveComplete(signalId);
|
||||
};
|
||||
|
||||
m_savingAssets.insert(assetId);
|
||||
assetIter->second->SaveAs(path, onSave);
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "Cannot SaveAs into an existing AssetId");
|
||||
}
|
||||
}
|
||||
|
||||
bool AssetTracker::Load(AZ::Data::AssetId fileAssetId, AZ::Data::AssetType assetType, Callbacks::OnAssetReadyCallback onAssetReadyCallback)
|
||||
@@ -541,48 +438,4 @@ namespace ScriptCanvasEditor
|
||||
return AZ::EntityId();
|
||||
}
|
||||
|
||||
void AssetTracker::OnAssetReady(const ScriptCanvasMemoryAsset* asset)
|
||||
{
|
||||
AZ::Data::AssetId assetId = CheckAssetId(asset->GetId());
|
||||
|
||||
auto assetInUseIter = m_assetsInUse.find(assetId);
|
||||
if (assetInUseIter != m_assetsInUse.end())
|
||||
{
|
||||
AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetReady, assetInUseIter->second);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetTracker::OnAssetReloaded(const ScriptCanvasMemoryAsset* asset)
|
||||
{
|
||||
AZ::Data::AssetId assetId = CheckAssetId(asset->GetId());
|
||||
|
||||
auto assetInUseIter = m_assetsInUse.find(assetId);
|
||||
if (assetInUseIter != m_assetsInUse.end())
|
||||
{
|
||||
AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetReloaded, assetInUseIter->second);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetTracker::OnAssetSaved(const ScriptCanvasMemoryAsset* asset, bool isSuccessful)
|
||||
{
|
||||
AZ::Data::AssetId assetId = CheckAssetId(asset->GetId());
|
||||
|
||||
auto assetInUseIter = m_assetsInUse.find(assetId);
|
||||
if (assetInUseIter != m_assetsInUse.end())
|
||||
{
|
||||
AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetSaved, assetInUseIter->second, isSuccessful);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetTracker::OnAssetError(const ScriptCanvasMemoryAsset* asset)
|
||||
{
|
||||
AZ::Data::AssetId assetId = CheckAssetId(asset->GetId());
|
||||
|
||||
auto assetInUseIter = m_assetsInUse.find(assetId);
|
||||
if (assetInUseIter != m_assetsInUse.end())
|
||||
{
|
||||
AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetError, assetInUseIter->second);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
|
||||
|
||||
#include <GraphCanvas/Editor/EditorTypes.h>
|
||||
#include <ScriptCanvas/Bus/RequestBus.h>
|
||||
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
@@ -119,10 +120,5 @@ namespace ScriptCanvasEditor
|
||||
// Invoked when an asset is loaded from file and becomes ready
|
||||
Callbacks::OnAssetReadyCallback m_onAssetReadyCallback;
|
||||
|
||||
// Internal::MemoryAssetNotificationBus
|
||||
void OnAssetReady(const ScriptCanvasMemoryAsset* asset) override;
|
||||
void OnAssetReloaded(const ScriptCanvasMemoryAsset* asset) override;
|
||||
void OnAssetSaved(const ScriptCanvasMemoryAsset* asset, bool isSuccessful) override;
|
||||
void OnAssetError(const ScriptCanvasMemoryAsset* asset) override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h>
|
||||
#include <Editor/Assets/ScriptCanvasMemoryAsset.h>
|
||||
#include <ScriptCanvas/Bus/RequestBus.h>
|
||||
|
||||
class QWidget;
|
||||
|
||||
@@ -154,17 +155,5 @@ namespace ScriptCanvasEditor
|
||||
using MemoryAssetSystemNotificationBus = AZ::EBus<MemoryAssetSystemNotifications>;
|
||||
}
|
||||
|
||||
class MemoryAssetNotifications
|
||||
: public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AZ::Data::AssetId;
|
||||
|
||||
virtual void OnFileStateChanged(Tracker::ScriptCanvasFileState) {}
|
||||
};
|
||||
|
||||
using MemoryAssetNotificationBus = AZ::EBus<MemoryAssetNotifications>;
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
@@ -18,22 +18,11 @@ namespace ScriptCanvasEditor
|
||||
namespace Callbacks
|
||||
{
|
||||
//! Callback used to know when a save operation failed or succeeded
|
||||
using OnSave = AZStd::function<void(bool saveSuccess, AZ::Data::AssetPtr, AZ::Data::AssetId previousFileAssetId)>;
|
||||
using OnSave = AZStd::function<void(bool saveSuccess, const SourceHandle& attempt, const SourceHandle& previous)>;
|
||||
|
||||
using OnAssetReadyCallback = AZStd::function<void(ScriptCanvasMemoryAsset&)>;
|
||||
using OnAssetCreatedCallback = OnAssetReadyCallback;
|
||||
}
|
||||
|
||||
namespace Tracker
|
||||
{
|
||||
enum class ScriptCanvasFileState : AZ::s32
|
||||
{
|
||||
NEW,
|
||||
MODIFIED,
|
||||
UNMODIFIED,
|
||||
SOURCE_REMOVED,
|
||||
INVALID = -1
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerializationResult.h>
|
||||
#include <AzCore/Serialization/Json/JsonUtils.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <ScriptCanvas/Core/SerializationListener.h>
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Libraries/Math/MathNodeUtilities.h>
|
||||
|
||||
namespace ScriptCanvasFileHandlingCpp
|
||||
{
|
||||
void AppendTabs(AZStd::string& result, size_t depth)
|
||||
{
|
||||
for (size_t i = 0; i < depth; ++i)
|
||||
{
|
||||
result += "\t";
|
||||
}
|
||||
}
|
||||
|
||||
void CollectNodes(const ScriptCanvas::GraphData::NodeContainer& container, ScriptCanvas::SerializationListeners& listeners)
|
||||
{
|
||||
for (auto& nodeEntity : container)
|
||||
{
|
||||
if (nodeEntity)
|
||||
{
|
||||
if (auto listener = azrtti_cast<ScriptCanvas::SerializationListener*>
|
||||
( AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Node>(nodeEntity)))
|
||||
{
|
||||
listeners.push_back(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
EditorAssetTree* EditorAssetTree::ModRoot()
|
||||
{
|
||||
if (!m_parent)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return m_parent->ModRoot();
|
||||
}
|
||||
|
||||
void EditorAssetTree::SetParent(EditorAssetTree& parent)
|
||||
{
|
||||
m_parent = &parent;
|
||||
}
|
||||
|
||||
AZStd::string EditorAssetTree::ToString(size_t depth) const
|
||||
{
|
||||
AZStd::string result;
|
||||
ScriptCanvasFileHandlingCpp::AppendTabs(result, depth);
|
||||
result += m_asset.ToString();
|
||||
depth += m_dependencies.empty() ? 0 : 1;
|
||||
|
||||
for (const auto& dependency : m_dependencies)
|
||||
{
|
||||
result += "\n";
|
||||
ScriptCanvasFileHandlingCpp::AppendTabs(result, depth);
|
||||
result += dependency.ToString(depth);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> LoadDataFromJson
|
||||
( ScriptCanvas::ScriptCanvasData& dataTarget
|
||||
, AZStd::string_view source
|
||||
, AZ::SerializeContext& serializeContext)
|
||||
{
|
||||
namespace JSRU = AZ::JsonSerializationUtils;
|
||||
using namespace ScriptCanvas;
|
||||
|
||||
AZ::JsonDeserializerSettings settings;
|
||||
settings.m_serializeContext = &serializeContext;
|
||||
settings.m_metadata.Create<SerializationListeners>();
|
||||
|
||||
auto loadResult = JSRU::LoadObjectFromStringByType
|
||||
( &dataTarget
|
||||
, azrtti_typeid<ScriptCanvasData>()
|
||||
, source
|
||||
, &settings);
|
||||
|
||||
if (!loadResult.IsSuccess())
|
||||
{
|
||||
return loadResult;
|
||||
}
|
||||
|
||||
if (auto graphData = dataTarget.ModGraph())
|
||||
{
|
||||
auto listeners = settings.m_metadata.Find<SerializationListeners>();
|
||||
AZ_Assert(listeners, "Failed to find SerializationListeners");
|
||||
|
||||
ScriptCanvasFileHandlingCpp::CollectNodes(graphData->GetGraphData()->m_nodes, *listeners);
|
||||
|
||||
for (auto listener : *listeners)
|
||||
{
|
||||
listener->OnDeserialize();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Failed to find graph data after loading source"));
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
|
||||
AZ::Outcome<EditorAssetTree, AZStd::string> LoadEditorAssetTree(SourceHandle handle, EditorAssetTree* parent)
|
||||
{
|
||||
if (!CompleteDescriptionInPlace(handle))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to describe graph from %s", handle.ToString().c_str()));
|
||||
}
|
||||
|
||||
if (!handle.Get())
|
||||
{
|
||||
auto loadAssetOutcome = LoadFromFile(handle.Path().c_str());
|
||||
if (!loadAssetOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load graph from %s: %s"
|
||||
, handle.ToString().c_str(), loadAssetOutcome.GetError().c_str()));
|
||||
}
|
||||
|
||||
handle = SourceHandle(loadAssetOutcome.GetValue(), handle.Id(), handle.Path().c_str());
|
||||
}
|
||||
|
||||
AZStd::vector<SourceHandle> dependentAssets;
|
||||
const auto subgraphInterfaceAssetTypeID = azrtti_typeid<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>>();
|
||||
|
||||
auto beginElementCB = [&subgraphInterfaceAssetTypeID, &dependentAssets]
|
||||
( void* instance
|
||||
, const AZ::SerializeContext::ClassData* classData
|
||||
, const AZ::SerializeContext::ClassElement* classElement) -> bool
|
||||
{
|
||||
if (classElement)
|
||||
{
|
||||
// if we are a pointer, then we may be pointing to a derived type.
|
||||
if (classElement->m_flags & AZ::SerializeContext::ClassElement::FLG_POINTER)
|
||||
{
|
||||
// if ptr is a pointer-to-pointer, cast its value to a void* (or const void*) and dereference to get to the actual object pointer.
|
||||
instance = *(void**)(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if (classData->m_typeId == subgraphInterfaceAssetTypeID)
|
||||
{
|
||||
auto asset = reinterpret_cast<AZ::Data::Asset<ScriptCanvas::SubgraphInterfaceAsset>*>(instance);
|
||||
auto id = asset->GetId();
|
||||
dependentAssets.push_back(SourceHandle(nullptr, id.m_guid, {}));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
AZ_Assert(serializeContext, "LoadEditorAssetTree() ailed to retrieve serialize context!");
|
||||
|
||||
const ScriptCanvasEditor::Graph* graph = handle.Get();
|
||||
serializeContext->EnumerateObject(graph, beginElementCB, nullptr, AZ::SerializeContext::ENUM_ACCESS_FOR_READ);
|
||||
|
||||
EditorAssetTree result;
|
||||
|
||||
for (auto& dependentAsset : dependentAssets)
|
||||
{
|
||||
auto loadDependentOutcome = LoadEditorAssetTree(dependentAsset, &result);
|
||||
if (!loadDependentOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load graph from %s: %s"
|
||||
, dependentAsset.ToString().c_str(), loadDependentOutcome.GetError().c_str()));
|
||||
}
|
||||
|
||||
result.m_dependencies.push_back(loadDependentOutcome.TakeValue());
|
||||
}
|
||||
|
||||
if (parent)
|
||||
{
|
||||
result.SetParent(*parent);
|
||||
}
|
||||
|
||||
result.m_asset = AZStd::move(handle);
|
||||
return AZ::Success(result);
|
||||
}
|
||||
|
||||
AZ::Outcome<ScriptCanvasEditor::SourceHandle, AZStd::string> LoadFromFile(AZStd::string_view path)
|
||||
{
|
||||
namespace JSRU = AZ::JsonSerializationUtils;
|
||||
|
||||
auto fileStringOutcome = AZ::Utils::ReadFile<AZStd::string>(path);
|
||||
if (!fileStringOutcome)
|
||||
{
|
||||
return AZ::Failure(fileStringOutcome.TakeError());
|
||||
}
|
||||
|
||||
const auto& asString = fileStringOutcome.GetValue();
|
||||
ScriptCanvas::DataPtr scriptCanvasData = aznew ScriptCanvas::ScriptCanvasData();
|
||||
if (!scriptCanvasData)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("failed to allocate ScriptCanvas::ScriptCanvasData after loading source file"));
|
||||
}
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
if (!serializeContext)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("no serialize context available to properly parse source file"));
|
||||
}
|
||||
|
||||
// attempt JSON deserialization...
|
||||
auto jsonResult = LoadDataFromJson(*scriptCanvasData, AZStd::string_view{ asString.begin(), asString.size() }, *serializeContext);
|
||||
if (!jsonResult.IsSuccess())
|
||||
{
|
||||
// ...try legacy xml as a failsafe
|
||||
AZ::IO::ByteContainerStream byteStream(&asString);
|
||||
if (!AZ::Utils::LoadObjectFromStreamInPlace
|
||||
( byteStream
|
||||
, *scriptCanvasData
|
||||
, serializeContext
|
||||
, AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)))
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("XML and JSON load attempts failed: %s", jsonResult.GetError().c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto entity = scriptCanvasData->GetScriptCanvasEntity())
|
||||
{
|
||||
AZ_Assert(entity->GetState() == AZ::Entity::State::Constructed, "Entity loaded in bad state");
|
||||
AZ::u64 entityId =
|
||||
aznumeric_caster(ScriptCanvas::MathNodeUtilities::GetRandomIntegral<AZ::s64>(1, std::numeric_limits<AZ::s64>::max()));
|
||||
entity->SetId(AZ::EntityId(entityId));
|
||||
|
||||
auto graph = entity->FindComponent<ScriptCanvasEditor::Graph>();
|
||||
graph->MarkOwnership(*scriptCanvasData);
|
||||
|
||||
entity->Init();
|
||||
entity->Activate();
|
||||
}
|
||||
else
|
||||
{
|
||||
return AZ::Failure(AZStd::string("Loaded script canvas file was missing a necessary Entity."));
|
||||
}
|
||||
|
||||
return AZ::Success(ScriptCanvasEditor::SourceHandle(scriptCanvasData, path));
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> SaveToStream(const SourceHandle& source, AZ::IO::GenericStream& stream)
|
||||
{
|
||||
namespace JSRU = AZ::JsonSerializationUtils;
|
||||
|
||||
if (!source.IsGraphValid())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("no source graph to save"));
|
||||
}
|
||||
|
||||
if (source.Path().empty())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("no destination path specified"));
|
||||
}
|
||||
|
||||
AZ::SerializeContext* serializeContext = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
|
||||
if (!serializeContext)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("no serialize context available to properly save source file"));
|
||||
}
|
||||
|
||||
auto graphData = source.Get()->GetOwnership();
|
||||
if (!graphData)
|
||||
{
|
||||
return AZ::Failure(AZStd::string("source is missing save container"));
|
||||
}
|
||||
|
||||
if (graphData->GetEditorGraph() != source.Get())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("source save container refers to incorrect graph"));
|
||||
}
|
||||
|
||||
auto saveTarget = graphData->ModGraph();
|
||||
if (!saveTarget || !saveTarget->GetGraphData())
|
||||
{
|
||||
return AZ::Failure(AZStd::string("source save container failed to return serializable graph data"));
|
||||
}
|
||||
|
||||
AZ::JsonSerializerSettings settings;
|
||||
settings.m_metadata.Create<ScriptCanvas::SerializationListeners>();
|
||||
auto listeners = settings.m_metadata.Find<ScriptCanvas::SerializationListeners>();
|
||||
AZ_Assert(listeners, "Failed to create SerializationListeners");
|
||||
ScriptCanvasFileHandlingCpp::CollectNodes(saveTarget->GetGraphData()->m_nodes, *listeners);
|
||||
settings.m_keepDefaults = false;
|
||||
settings.m_serializeContext = serializeContext;
|
||||
|
||||
for (auto listener : *listeners)
|
||||
{
|
||||
listener->OnSerialize();
|
||||
}
|
||||
|
||||
auto saveOutcome = JSRU::SaveObjectToStream<ScriptCanvas::ScriptCanvasData>(graphData.get(), stream, nullptr, &settings);
|
||||
if (!saveOutcome.IsSuccess())
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("JSON serialization failed to save source: %s", saveOutcome.GetError().c_str()));
|
||||
}
|
||||
|
||||
return AZ::Success();
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,7 @@
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
ScriptCanvasMemoryAsset::ScriptCanvasMemoryAsset()
|
||||
: m_isSaving(false)
|
||||
, m_sourceInError(false)
|
||||
: m_sourceInError(false)
|
||||
{
|
||||
m_undoState = AZStd::make_unique<SceneUndoState>(this);
|
||||
}
|
||||
@@ -279,14 +278,11 @@ namespace ScriptCanvasEditor
|
||||
|
||||
EditorGraphNotificationBus::Handler::BusDisconnect();
|
||||
EditorGraphNotificationBus::Handler::BusConnect(m_scriptCanvasId);
|
||||
|
||||
m_undoHelper = AZStd::make_unique<UndoHelper>(*this);
|
||||
}
|
||||
|
||||
ScriptCanvasEditor::Widget::CanvasWidget* ScriptCanvasMemoryAsset::CreateView(QWidget* parent)
|
||||
ScriptCanvasEditor::Widget::CanvasWidget* ScriptCanvasMemoryAsset::CreateView(QWidget* /*parent*/)
|
||||
{
|
||||
m_canvasWidget = new Widget::CanvasWidget(m_fileAssetId, parent);
|
||||
return m_canvasWidget;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ScriptCanvasMemoryAsset::ClearView()
|
||||
@@ -430,68 +426,13 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCanvasMemoryAsset::SourceFileFailed(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid)
|
||||
void ScriptCanvasMemoryAsset::SourceFileFailed(AZStd::string /*relativePath*/, AZStd::string /*scanFolder*/, AZ::Uuid)
|
||||
{
|
||||
AZStd::string fullPath;
|
||||
AzFramework::StringFunc::Path::Join(scanFolder.data(), relativePath.data(), fullPath);
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePath, fullPath);
|
||||
|
||||
auto assetPathIdIt = AZStd::find(m_pendingSave.begin(), m_pendingSave.end(), fullPath);
|
||||
|
||||
if (assetPathIdIt != m_pendingSave.end())
|
||||
{
|
||||
if (m_onSaveCallback)
|
||||
{
|
||||
m_onSaveCallback(false, m_inMemoryAsset.Get(), AZ::Data::AssetId());
|
||||
m_onSaveCallback = nullptr;
|
||||
}
|
||||
|
||||
m_pendingSave.erase(assetPathIdIt);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCanvasMemoryAsset::SavingComplete(const AZStd::string& streamName, AZ::Uuid sourceAssetId)
|
||||
void ScriptCanvasMemoryAsset::SavingComplete(const AZStd::string& /*streamName*/, AZ::Uuid /*sourceAssetId*/)
|
||||
{
|
||||
AZStd::string normPath = streamName;
|
||||
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePath, normPath);
|
||||
|
||||
auto assetPathIdIt = AZStd::find(m_pendingSave.begin(), m_pendingSave.end(), normPath);
|
||||
if (assetPathIdIt != m_pendingSave.end())
|
||||
{
|
||||
AZ::Data::AssetId previousFileAssetId;
|
||||
|
||||
if (sourceAssetId != m_fileAssetId.m_guid)
|
||||
{
|
||||
previousFileAssetId = m_fileAssetId;
|
||||
|
||||
// The source file has changed, store the AssetId to the canonical asset on file
|
||||
SetFileAssetId(sourceAssetId);
|
||||
|
||||
}
|
||||
else if (!m_fileAssetId.IsValid())
|
||||
{
|
||||
SetFileAssetId(sourceAssetId);
|
||||
}
|
||||
|
||||
m_formerGraphIdPair = AZStd::make_pair(m_scriptCanvasId, m_graphId);
|
||||
|
||||
m_fileState = Tracker::ScriptCanvasFileState::UNMODIFIED;
|
||||
|
||||
m_pendingSave.erase(assetPathIdIt);
|
||||
|
||||
m_absolutePath = m_saveAsPath;
|
||||
m_saveAsPath.clear();
|
||||
|
||||
// Connect to the source asset's bus to monitor for situations we may need to handle
|
||||
AZ::Data::AssetBus::MultiHandler::BusConnect(m_inMemoryAsset.GetId());
|
||||
AZ::Data::AssetBus::MultiHandler::BusConnect(m_fileAssetId);
|
||||
|
||||
if (m_onSaveCallback)
|
||||
{
|
||||
m_onSaveCallback(true, m_inMemoryAsset.Get(), previousFileAssetId);
|
||||
m_onSaveCallback = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCanvasMemoryAsset::FinalizeAssetSave(bool, const AzToolsFramework::SourceControlFileInfo& fileInfo, const AZ::Data::AssetStreamInfo& saveInfo, Callbacks::OnSave onSaveCallback)
|
||||
@@ -525,19 +466,13 @@ namespace ScriptCanvasEditor
|
||||
UndoNotificationBus::Broadcast(&UndoNotifications::OnCanRedoChanged, m_undoState->m_undoStack->CanRedo());
|
||||
}
|
||||
|
||||
void ScriptCanvasMemoryAsset::SetFileAssetId(const AZ::Data::AssetId& fileAssetId)
|
||||
void ScriptCanvasMemoryAsset::SetFileAssetId(const AZ::Data::AssetId& /*fileAssetId*/)
|
||||
{
|
||||
m_fileAssetId = fileAssetId;
|
||||
|
||||
if (m_canvasWidget)
|
||||
{
|
||||
m_canvasWidget->SetAssetId(fileAssetId);
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptCanvasMemoryAsset::SignalFileStateChanged()
|
||||
{
|
||||
MemoryAssetNotificationBus::Event(m_fileAssetId, &MemoryAssetNotifications::OnFileStateChanged, GetFileState());
|
||||
}
|
||||
|
||||
AZStd::string ScriptCanvasMemoryAsset::MakeTemporaryFilePathForSave(AZStd::string_view targetFilename)
|
||||
@@ -604,27 +539,8 @@ namespace ScriptCanvasEditor
|
||||
// AssetSaveFinalizer
|
||||
//////////////////////////////////////
|
||||
|
||||
bool AssetSaveFinalizer::ValidateStatus(const AzToolsFramework::SourceControlFileInfo& fileInfo)
|
||||
bool AssetSaveFinalizer::ValidateStatus(const AzToolsFramework::SourceControlFileInfo& /*fileInfo*/)
|
||||
{
|
||||
auto fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
if (fileInfo.IsLockedByOther())
|
||||
{
|
||||
AZ_Error("Script Canvas", !fileInfo.IsLockedByOther(), "The file is already exclusively opened by another user: %s", fileInfo.m_filePath.data());
|
||||
AZStd::invoke(m_onSave, false, m_inMemoryAsset, m_fileAssetId);
|
||||
return false;
|
||||
}
|
||||
else if (fileInfo.IsReadOnly() && fileIO->Exists(fileInfo.m_filePath.c_str()))
|
||||
{
|
||||
AZ_Error("Script Canvas", !fileInfo.IsReadOnly(), "File %s is read-only. It cannot be saved."
|
||||
" If this file is in Perforce it may not have been checked out by the Source Control API.", fileInfo.m_filePath.data());
|
||||
AZStd::invoke(m_onSave, false, m_inMemoryAsset, m_fileAssetId);
|
||||
return false;
|
||||
}
|
||||
else if (m_saving)
|
||||
{
|
||||
AZ_Warning("Script Canvas", false, "Trying to save the same file twice. Will result in one save callback being ignored.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
|
||||
#include <Editor/View/Widgets/CanvasWidget.h>
|
||||
#include <Editor/Undo/ScriptCanvasUndoManager.h>
|
||||
#include <ScriptCanvas/Bus/RequestBus.h>
|
||||
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
@@ -172,7 +174,6 @@ namespace ScriptCanvasEditor
|
||||
|
||||
bool IsSourceInError() const;
|
||||
|
||||
void OnSourceAssetFinalized(const AZStd::string& fullPath, AZ::Uuid sourceAssetId);
|
||||
void SavingComplete(const AZStd::string& fullPath, AZ::Uuid sourceAssetId);
|
||||
|
||||
AZ::Data::AssetId GetSourceUuid() const { return m_sourceUuid; }
|
||||
@@ -320,7 +321,6 @@ namespace ScriptCanvasEditor
|
||||
//! The undo helper is an object that implements the Undo behaviors
|
||||
AZStd::unique_ptr<UndoHelper> m_undoHelper;
|
||||
|
||||
bool m_isSaving;
|
||||
bool m_sourceInError;
|
||||
|
||||
AZ::Data::AssetId m_sourceUuid;
|
||||
|
||||
@@ -9,13 +9,19 @@
|
||||
#include "ScriptCanvasUndoHelper.h"
|
||||
#include "ScriptCanvasMemoryAsset.h"
|
||||
#include <Undo/ScriptCanvasGraphCommand.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
UndoHelper::UndoHelper(ScriptCanvasMemoryAsset& memoryAsset)
|
||||
: m_memoryAsset(memoryAsset)
|
||||
UndoHelper::UndoHelper()
|
||||
: m_undoState(this)
|
||||
{
|
||||
UndoRequestBus::Handler::BusConnect(memoryAsset.GetScriptCanvasId());
|
||||
}
|
||||
|
||||
UndoHelper::UndoHelper(Graph* graph)
|
||||
: m_undoState(this)
|
||||
{
|
||||
SetSource(graph);
|
||||
}
|
||||
|
||||
UndoHelper::~UndoHelper()
|
||||
@@ -23,15 +29,21 @@ namespace ScriptCanvasEditor
|
||||
UndoRequestBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
void UndoHelper::SetSource(Graph* graph)
|
||||
{
|
||||
m_graph = graph;
|
||||
UndoRequestBus::Handler::BusConnect(graph->GetScriptCanvasId());
|
||||
}
|
||||
|
||||
ScriptCanvasEditor::UndoCache* UndoHelper::GetSceneUndoCache()
|
||||
{
|
||||
return m_memoryAsset.GetUndoState()->m_undoCache.get();
|
||||
return m_undoState.m_undoCache.get();
|
||||
}
|
||||
|
||||
ScriptCanvasEditor::UndoData UndoHelper::CreateUndoData()
|
||||
{
|
||||
AZ::EntityId graphCanvasGraphId = m_memoryAsset.GetGraphId();
|
||||
ScriptCanvas::ScriptCanvasId scriptCanvasId = m_memoryAsset.GetScriptCanvasId();
|
||||
AZ::EntityId graphCanvasGraphId = m_graph->GetGraphCanvasGraphId();
|
||||
ScriptCanvas::ScriptCanvasId scriptCanvasId = m_graph->GetScriptCanvasId();
|
||||
|
||||
GraphCanvas::GraphModelRequestBus::Event(graphCanvasGraphId, &GraphCanvas::GraphModelRequests::OnSaveDataDirtied, graphCanvasGraphId);
|
||||
|
||||
@@ -56,17 +68,17 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void UndoHelper::BeginUndoBatch(AZStd::string_view label)
|
||||
{
|
||||
m_memoryAsset.GetUndoState()->BeginUndoBatch(label);
|
||||
m_undoState.BeginUndoBatch(label);
|
||||
}
|
||||
|
||||
void UndoHelper::EndUndoBatch()
|
||||
{
|
||||
m_memoryAsset.GetUndoState()->EndUndoBatch();
|
||||
m_undoState.EndUndoBatch();
|
||||
}
|
||||
|
||||
void UndoHelper::AddUndo(AzToolsFramework::UndoSystem::URSequencePoint* sequencePoint)
|
||||
{
|
||||
if (SceneUndoState* sceneUndoState = m_memoryAsset.GetUndoState())
|
||||
if (SceneUndoState* sceneUndoState = &m_undoState)
|
||||
{
|
||||
if (!sceneUndoState->m_currentUndoBatch)
|
||||
{
|
||||
@@ -82,22 +94,22 @@ namespace ScriptCanvasEditor
|
||||
void UndoHelper::AddGraphItemChangeUndo(AZStd::string_view undoLabel)
|
||||
{
|
||||
GraphItemChangeCommand* command = aznew GraphItemChangeCommand(undoLabel);
|
||||
command->Capture(m_memoryAsset, true);
|
||||
command->Capture(m_memoryAsset, false);
|
||||
command->Capture(m_graph, true);
|
||||
command->Capture(m_graph, false);
|
||||
AddUndo(command);
|
||||
}
|
||||
|
||||
void UndoHelper::AddGraphItemAdditionUndo(AZStd::string_view undoLabel)
|
||||
{
|
||||
GraphItemAddCommand* command = aznew GraphItemAddCommand(undoLabel);
|
||||
command->Capture(m_memoryAsset, false);
|
||||
command->Capture(m_graph, false);
|
||||
AddUndo(command);
|
||||
}
|
||||
|
||||
void UndoHelper::AddGraphItemRemovalUndo(AZStd::string_view undoLabel)
|
||||
{
|
||||
GraphItemRemovalCommand* command = aznew GraphItemRemovalCommand(undoLabel);
|
||||
command->Capture(m_memoryAsset, true);
|
||||
command->Capture(m_graph, true);
|
||||
AddUndo(command);
|
||||
}
|
||||
|
||||
@@ -105,7 +117,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(ScriptCanvas);
|
||||
|
||||
SceneUndoState* sceneUndoState = m_memoryAsset.GetUndoState();
|
||||
SceneUndoState* sceneUndoState = &m_undoState;
|
||||
if (sceneUndoState)
|
||||
{
|
||||
AZ_Warning("Script Canvas", !sceneUndoState->m_currentUndoBatch, "Script Canvas Editor has an open undo batch when performing a redo operation");
|
||||
@@ -125,7 +137,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
AZ_PROFILE_FUNCTION(ScriptCanvas);
|
||||
|
||||
SceneUndoState* sceneUndoState = m_memoryAsset.GetUndoState();
|
||||
SceneUndoState* sceneUndoState = &m_undoState;
|
||||
if (sceneUndoState)
|
||||
{
|
||||
AZ_Warning("Script Canvas", !sceneUndoState->m_currentUndoBatch, "Script Canvas Editor has an open undo batch when performing a redo operation");
|
||||
@@ -143,7 +155,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void UndoHelper::Reset()
|
||||
{
|
||||
if (SceneUndoState* sceneUndoState = m_memoryAsset.GetUndoState())
|
||||
if (SceneUndoState* sceneUndoState = &m_undoState)
|
||||
{
|
||||
AZ_Warning("Script Canvas", !sceneUndoState->m_currentUndoBatch, "Script Canvas Editor has an open undo batch when resetting the undo stack");
|
||||
sceneUndoState->m_undoStack->Reset();
|
||||
@@ -162,17 +174,23 @@ namespace ScriptCanvasEditor
|
||||
|
||||
bool UndoHelper::CanUndo() const
|
||||
{
|
||||
return m_memoryAsset.GetUndoState()->m_undoStack->CanUndo();
|
||||
return m_undoState.m_undoStack->CanUndo();
|
||||
}
|
||||
|
||||
bool UndoHelper::CanRedo() const
|
||||
{
|
||||
return m_memoryAsset.GetUndoState()->m_undoStack->CanRedo();
|
||||
return m_undoState.m_undoStack->CanRedo();
|
||||
}
|
||||
|
||||
void UndoHelper::OnUndoStackChanged()
|
||||
{
|
||||
UndoNotificationBus::Broadcast(&UndoNotifications::OnCanUndoChanged, m_undoState.m_undoStack->CanUndo());
|
||||
UndoNotificationBus::Broadcast(&UndoNotifications::OnCanRedoChanged, m_undoState.m_undoStack->CanRedo());
|
||||
}
|
||||
|
||||
void UndoHelper::UpdateCache()
|
||||
{
|
||||
ScriptCanvas::ScriptCanvasId scriptCanvasId = m_memoryAsset.GetScriptCanvasId();
|
||||
ScriptCanvas::ScriptCanvasId scriptCanvasId = m_graph->GetScriptCanvasId();
|
||||
|
||||
UndoCache* undoCache = nullptr;
|
||||
UndoRequestBus::EventResult(undoCache, scriptCanvasId, &UndoRequests::GetSceneUndoCache);
|
||||
|
||||
@@ -8,22 +8,27 @@
|
||||
|
||||
#pragma once
|
||||
#include <ScriptCanvas/Bus/UndoBus.h>
|
||||
#include <Editor/Undo/ScriptCanvasUndoManager.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
class ScriptCanvasMemoryAsset;
|
||||
|
||||
// Helper class that provides the implementation for UndoRequestBus
|
||||
class UndoHelper : UndoRequestBus::Handler
|
||||
class UndoHelper
|
||||
: public UndoRequestBus::Handler
|
||||
, public AzToolsFramework::UndoSystem::IUndoNotify
|
||||
{
|
||||
public:
|
||||
|
||||
UndoHelper(ScriptCanvasMemoryAsset& memoryAsset);
|
||||
UndoHelper();
|
||||
UndoHelper(Graph* source);
|
||||
~UndoHelper();
|
||||
|
||||
UndoCache* GetSceneUndoCache() override;
|
||||
UndoData CreateUndoData() override;
|
||||
|
||||
void SetSource(Graph* source);
|
||||
|
||||
void BeginUndoBatch(AZStd::string_view label) override;
|
||||
void EndUndoBatch() override;
|
||||
void AddUndo(AzToolsFramework::UndoSystem::URSequencePoint* seqPoint) override;
|
||||
@@ -41,6 +46,7 @@ namespace ScriptCanvasEditor
|
||||
bool CanRedo() const override;
|
||||
|
||||
private:
|
||||
void OnUndoStackChanged() override;
|
||||
|
||||
void UpdateCache();
|
||||
|
||||
@@ -51,7 +57,7 @@ namespace ScriptCanvasEditor
|
||||
};
|
||||
|
||||
Status m_status = Status::Idle;
|
||||
|
||||
ScriptCanvasMemoryAsset& m_memoryAsset;
|
||||
SceneUndoState m_undoState;
|
||||
Graph* m_graph = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <Libraries/Core/EBusEventHandler.h>
|
||||
#include <Libraries/Core/ReceiveScriptEvent.h>
|
||||
#include <Libraries/Core/ScriptEventBase.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
|
||||
#include <Libraries/Core/SendScriptEvent.h>
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Core/Connection.h>
|
||||
@@ -480,6 +481,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
ScriptCanvas::Graph::Activate();
|
||||
PostActivate();
|
||||
m_undoHelper.SetSource(this);
|
||||
}
|
||||
|
||||
void Graph::Deactivate()
|
||||
@@ -489,7 +491,7 @@ namespace ScriptCanvasEditor
|
||||
EditorGraphRequestBus::Handler::BusDisconnect();
|
||||
SceneCounterRequestBus::Handler::BusDisconnect();
|
||||
NodeCreationNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
GraphCanvas::SceneNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
GraphCanvas::GraphModelRequestBus::Handler::BusDisconnect();
|
||||
@@ -1029,18 +1031,50 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
AZStd::any* connectionUserData = nullptr;
|
||||
GraphCanvas::ConnectionRequestBus::EventResult(connectionUserData, connectionId, &GraphCanvas::ConnectionRequests::GetUserData);
|
||||
auto scConnectionId = connectionUserData && connectionUserData->is<AZ::EntityId>() ? *AZStd::any_cast<AZ::EntityId>(connectionUserData) : AZ::EntityId();
|
||||
auto scConnectionId = connectionUserData && connectionUserData->is<AZ::EntityId>()
|
||||
? *AZStd::any_cast<AZ::EntityId>(connectionUserData)
|
||||
: AZ::EntityId();
|
||||
|
||||
ScriptCanvas::Connection* connection = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Connection>(scConnectionId);
|
||||
|
||||
if (connection)
|
||||
if (ScriptCanvas::Connection* connection = AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Connection>(scConnectionId))
|
||||
{
|
||||
ScriptCanvas::GraphNotificationBus::Event(GetScriptCanvasId(), &ScriptCanvas::GraphNotifications::OnDisonnectionComplete, connectionId);
|
||||
|
||||
ScriptCanvas::GraphNotificationBus::Event
|
||||
( GetScriptCanvasId()
|
||||
, &ScriptCanvas::GraphNotifications::OnDisonnectionComplete
|
||||
, connectionId);
|
||||
DisconnectById(scConnectionId);
|
||||
}
|
||||
}
|
||||
|
||||
ScriptCanvas::DataPtr Graph::Create()
|
||||
{
|
||||
if (AZ::Entity* entity = aznew AZ::Entity("Script Canvas Graph"))
|
||||
{
|
||||
auto graph = entity->CreateComponent<ScriptCanvasEditor::Graph>();
|
||||
entity->CreateComponent<EditorGraphVariableManagerComponent>(graph->GetScriptCanvasId());
|
||||
|
||||
if (ScriptCanvas::DataPtr data = aznew ScriptCanvas::ScriptCanvasData())
|
||||
{
|
||||
data->m_scriptCanvasEntity.reset(entity);
|
||||
graph->MarkOwnership(*data);
|
||||
entity->Init();
|
||||
entity->Activate();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Graph::MarkOwnership(ScriptCanvas::ScriptCanvasData& owner)
|
||||
{
|
||||
m_owner = &owner;
|
||||
}
|
||||
|
||||
ScriptCanvas::DataPtr Graph::GetOwnership() const
|
||||
{
|
||||
return const_cast<Graph*>(this)->m_owner;
|
||||
}
|
||||
|
||||
bool Graph::CreateConnection(const GraphCanvas::ConnectionId& connectionId, const GraphCanvas::Endpoint& sourcePoint, const GraphCanvas::Endpoint& targetPoint)
|
||||
{
|
||||
if (!sourcePoint.IsValid() || !targetPoint.IsValid())
|
||||
@@ -1323,7 +1357,8 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void Graph::SignalDirty()
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::SignalSceneDirty, GetAssetId());
|
||||
SourceHandle handle(m_owner, {}, {});
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::SignalSceneDirty, handle);
|
||||
}
|
||||
|
||||
void Graph::HighlightNodesByType(const ScriptCanvas::NodeTypeIdentifier& nodeTypeIdentifier)
|
||||
@@ -3354,11 +3389,6 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void Graph::SetAssetType(AZ::Data::AssetType assetType)
|
||||
{
|
||||
m_assetType = assetType;
|
||||
}
|
||||
|
||||
void Graph::ReportError(const ScriptCanvas::Node& node, const AZStd::string& errorSource, const AZStd::string& errorMessage)
|
||||
{
|
||||
AzQtComponents::ToastConfiguration toastConfiguration(AzQtComponents::ToastType::Error, errorSource.c_str(), errorMessage.c_str());
|
||||
@@ -3463,7 +3493,7 @@ namespace ScriptCanvasEditor
|
||||
m_focusHelper.SetActiveGraph(GetGraphCanvasGraphId());
|
||||
}
|
||||
|
||||
bool Graph::UpgradeGraph(const AZ::Data::Asset<AZ::Data::AssetData>& asset, UpgradeRequest request, bool isVerbose)
|
||||
bool Graph::UpgradeGraph(SourceHandle& asset, UpgradeRequest request, bool isVerbose)
|
||||
{
|
||||
m_upgradeSM.SetAsset(asset);
|
||||
m_upgradeSM.SetVerbose(isVerbose);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Component/NamedEntityId.h>
|
||||
@@ -14,6 +13,7 @@
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/IdUtils.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
#include <AzFramework/Asset/AssetSystemBus.h>
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
@@ -21,23 +21,26 @@
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
#include <Core/ScriptCanvasBus.h>
|
||||
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
|
||||
#include <LyViewPaneNames.h>
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
#include <ScriptCanvas/Bus/RequestBus.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <ScriptCanvas/Components/EditorGraphVariableManagerComponent.h>
|
||||
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
|
||||
#include <ScriptCanvas/Components/EditorUtils.h>
|
||||
#include <ScriptCanvas/Core/Node.h>
|
||||
#include <ScriptCanvas/PerformanceStatisticsBus.h>
|
||||
|
||||
|
||||
namespace EditorScriptCanvasComponentCpp
|
||||
{
|
||||
enum Version
|
||||
{
|
||||
PrefabIntegration = 10,
|
||||
|
||||
InternalDev,
|
||||
AddSourceHandle,
|
||||
// add description above
|
||||
Current
|
||||
};
|
||||
@@ -128,7 +131,7 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
|
||||
ScriptCanvasBuilder::BuildVariableOverrides overrides;
|
||||
overrides.m_source = AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset>(assetHolder.GetAssetId(), assetHolder.GetAssetType(), assetHolder.GetAssetHint());;
|
||||
overrides.m_source = SourceHandle(nullptr, assetHolder.GetAssetId().m_guid, {});
|
||||
|
||||
for (auto& variable : editableData.GetVariables())
|
||||
{
|
||||
@@ -142,6 +145,25 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
if (rootElement.GetVersion() < EditorScriptCanvasComponentCpp::Version::AddSourceHandle)
|
||||
{
|
||||
ScriptCanvasAssetHolder assetHolder;
|
||||
if (!rootElement.FindSubElementAndGetData(AZ_CRC_CE("m_assetHolder"), assetHolder))
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_assetHolder'");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto assetId = assetHolder.GetAssetId();
|
||||
auto path = assetHolder.GetAssetHint();
|
||||
|
||||
if (!rootElement.AddElementWithData(serializeContext, "runtimeDataOverrides", SourceHandle(nullptr, assetId.m_guid, path)))
|
||||
{
|
||||
AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'sourceHandle'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -153,9 +175,9 @@ namespace ScriptCanvasEditor
|
||||
serializeContext->Class<EditorScriptCanvasComponent, EditorComponentBase>()
|
||||
->Version(EditorScriptCanvasComponentCpp::Version::Current, &EditorScriptCanvasComponentVersionConverter)
|
||||
->Field("m_name", &EditorScriptCanvasComponent::m_name)
|
||||
->Field("m_assetHolder", &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder)
|
||||
->Field("runtimeDataIsValid", &EditorScriptCanvasComponent::m_runtimeDataIsValid)
|
||||
->Field("runtimeDataOverrides", &EditorScriptCanvasComponent::m_variableOverrides)
|
||||
->Field("sourceHandle", &EditorScriptCanvasComponent::m_sourceHandle)
|
||||
;
|
||||
|
||||
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
|
||||
@@ -171,29 +193,34 @@ namespace ScriptCanvasEditor
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("UI", 0x27ff46b0))
|
||||
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Level", 0x9aeacc13))
|
||||
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/scripting/script-canvas/")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder, "Script Canvas Asset", "Script Canvas asset associated with this component")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_sourceHandle, "Script Canvas Source File", "Script Canvas source file associated with this component")
|
||||
->Attribute("BrowseIcon", ":/stylesheet/img/UI20/browse-edit-select-files.svg")
|
||||
->Attribute("EditButton", "")
|
||||
->Attribute("EditDescription", "Open in Script Canvas Editor")
|
||||
->Attribute("EditCallback", &EditorScriptCanvasComponent::OpenEditor)
|
||||
->Attribute(AZ::Edit::Attributes::AssetPickerTitle, "Script Canvas")
|
||||
->Attribute(AZ::Edit::Attributes::SourceAssetFilterPattern, "*.scriptcanvas")
|
||||
->Attribute(AZ::Edit::Attributes::ChangeNotify, &EditorScriptCanvasComponent::OnFileSelectionChanged)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_variableOverrides, "Properties", "Script Canvas Graph Properties")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast<AZ::JsonRegistrationContext*>(context))
|
||||
{
|
||||
jsonContext->Serializer<AZ::EditorScriptCanvasComponentSerializer>()->HandlesType<EditorScriptCanvasComponent>();
|
||||
}
|
||||
}
|
||||
|
||||
EditorScriptCanvasComponent::EditorScriptCanvasComponent()
|
||||
: EditorScriptCanvasComponent(AZ::Data::Asset<ScriptCanvasAsset>())
|
||||
: EditorScriptCanvasComponent(SourceHandle())
|
||||
{
|
||||
}
|
||||
|
||||
EditorScriptCanvasComponent::EditorScriptCanvasComponent(AZ::Data::Asset<ScriptCanvasAsset> asset)
|
||||
: m_scriptCanvasAssetHolder()
|
||||
EditorScriptCanvasComponent::EditorScriptCanvasComponent(const SourceHandle& sourceHandle)
|
||||
: m_sourceHandle(sourceHandle)
|
||||
{
|
||||
if (asset.GetId().IsValid())
|
||||
{
|
||||
m_scriptCanvasAssetHolder.SetAsset(asset.GetId());
|
||||
}
|
||||
|
||||
m_scriptCanvasAssetHolder.SetScriptChangedCB([this](AZ::Data::AssetId assetId) { OnScriptCanvasAssetChanged(assetId); });
|
||||
}
|
||||
|
||||
EditorScriptCanvasComponent::~EditorScriptCanvasComponent()
|
||||
@@ -209,50 +236,34 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void EditorScriptCanvasComponent::UpdateName()
|
||||
{
|
||||
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
|
||||
if (assetId.IsValid())
|
||||
SetName(m_sourceHandle.Path().Filename().Native());
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OpenEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&)
|
||||
{
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
|
||||
if (m_sourceHandle.IsDescriptionValid())
|
||||
{
|
||||
// Pathname from the asset doesn't seem to return a value unless the asset has been loaded up once(which isn't done until we try to show it).
|
||||
// Using the Job system to determine the asset name instead.
|
||||
AZ::Outcome<AzToolsFramework::AssetSystem::JobInfoContainer> jobOutcome = AZ::Failure();
|
||||
AzToolsFramework::AssetSystemJobRequestBus::BroadcastResult(jobOutcome, &AzToolsFramework::AssetSystemJobRequestBus::Events::GetAssetJobsInfoByAssetID, assetId, false, false);
|
||||
|
||||
AZStd::string assetPath;
|
||||
AZStd::string assetName;
|
||||
|
||||
if (jobOutcome.IsSuccess())
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_sourceHandle, Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
|
||||
if (!openOutcome)
|
||||
{
|
||||
AzToolsFramework::AssetSystem::JobInfoContainer& jobs = jobOutcome.GetValue();
|
||||
|
||||
// Get the asset relative path
|
||||
if (!jobs.empty())
|
||||
{
|
||||
assetPath = jobs[0].m_sourceFile;
|
||||
}
|
||||
|
||||
// Get the asset file name
|
||||
assetName = assetPath;
|
||||
|
||||
if (!assetPath.empty())
|
||||
{
|
||||
AzFramework::StringFunc::Path::GetFileName(assetPath.c_str(), assetName);
|
||||
SetName(assetName);
|
||||
}
|
||||
AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OpenEditor()
|
||||
{
|
||||
m_scriptCanvasAssetHolder.OpenEditor();
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::CloseGraph()
|
||||
{
|
||||
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
|
||||
if (assetId.IsValid())
|
||||
else if (GetEntityId().IsValid())
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::CloseScriptCanvasAsset, assetId);
|
||||
AzToolsFramework::EntityIdList selectedEntityIds;
|
||||
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(selectedEntityIds, &AzToolsFramework::ToolsApplicationRequests::GetSelectedEntities);
|
||||
|
||||
// Going to bypass the multiple selected entities flow for right now.
|
||||
if (selectedEntityIds.size() == 1)
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::CreateScriptCanvasAssetFor, AZStd::make_pair(GetEntityId(), GetId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +272,11 @@ namespace ScriptCanvasEditor
|
||||
EditorComponentBase::Init();
|
||||
AzFramework::AssetCatalogEventBus::Handler::BusConnect();
|
||||
AzToolsFramework::EditorEntityContextNotificationBus::Handler::BusConnect();
|
||||
m_scriptCanvasAssetHolder.Init(GetEntityId(), GetId());
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::InitializeSource(const SourceHandle& sourceHandle)
|
||||
{
|
||||
m_sourceHandle = sourceHandle;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -269,6 +284,8 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
EditorComponentBase::Activate();
|
||||
|
||||
AzToolsFramework::AssetSystemBus::Handler::BusConnect();
|
||||
|
||||
AZ::EntityId entityId = GetEntityId();
|
||||
|
||||
EditorContextMenuRequestBus::Handler::BusConnect(entityId);
|
||||
@@ -277,19 +294,15 @@ namespace ScriptCanvasEditor
|
||||
EditorScriptCanvasComponentLoggingBus::Handler::BusConnect(entityId);
|
||||
EditorLoggingComponentNotificationBus::Broadcast(&EditorLoggingComponentNotifications::OnEditorScriptCanvasComponentActivated, GetNamedEntityId(), GetGraphIdentifier());
|
||||
|
||||
AZ::Data::AssetId fileAssetId = m_scriptCanvasAssetHolder.GetAssetId();
|
||||
CompleteDescriptionInPlace(m_sourceHandle);
|
||||
|
||||
if (fileAssetId.IsValid())
|
||||
{
|
||||
AssetTrackerNotificationBus::Handler::BusConnect(fileAssetId);
|
||||
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
|
||||
}
|
||||
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
void EditorScriptCanvasComponent::Deactivate()
|
||||
{
|
||||
AssetTrackerNotificationBus::Handler::BusDisconnect();
|
||||
AzToolsFramework::AssetSystemBus::Handler::BusDisconnect();
|
||||
|
||||
EditorScriptCanvasComponentLoggingBus::Handler::BusDisconnect();
|
||||
EditorLoggingComponentNotificationBus::Broadcast(&EditorLoggingComponentNotifications::OnEditorScriptCanvasComponentDeactivated, GetNamedEntityId(), GetGraphIdentifier());
|
||||
@@ -303,10 +316,11 @@ namespace ScriptCanvasEditor
|
||||
void EditorScriptCanvasComponent::BuildGameEntityData()
|
||||
{
|
||||
using namespace ScriptCanvasBuilder;
|
||||
CompleteDescriptionInPlace(m_sourceHandle);
|
||||
|
||||
m_runtimeDataIsValid = false;
|
||||
|
||||
auto assetTreeOutcome = LoadEditorAssetTree(m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetHint());
|
||||
auto assetTreeOutcome = LoadEditorAssetTree(m_sourceHandle);
|
||||
if (!assetTreeOutcome.IsSuccess())
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", false, "EditorScriptCanvasComponent::BuildGameEntityData failed: %s", assetTreeOutcome.GetError().c_str());
|
||||
@@ -344,7 +358,8 @@ namespace ScriptCanvasEditor
|
||||
|
||||
if (!m_runtimeDataIsValid)
|
||||
{
|
||||
AZ_Error("ScriptCanvasBuilder", false, "Runtime information did not build for ScriptCanvas Component using asset: %s", m_scriptCanvasAssetHolder.GetAssetId().ToString<AZStd::string>().c_str());
|
||||
AZ_Error("ScriptCanvasBuilder", false, "Runtime information did not build for ScriptCanvas Component using asset: %s"
|
||||
, m_sourceHandle.ToString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,168 +367,132 @@ namespace ScriptCanvasEditor
|
||||
runtimeComponent->TakeRuntimeDataOverrides(ConvertToRuntime(m_variableOverrides));
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
if (m_removedCatalogId == assetId)
|
||||
{
|
||||
if (!m_scriptCanvasAssetHolder.GetAssetId().IsValid())
|
||||
{
|
||||
SetPrimaryAsset(assetId);
|
||||
m_removedCatalogId.SetInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
void EditorScriptCanvasComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& removedAssetId, const AZ::Data::AssetInfo& /*assetInfo*/)
|
||||
{
|
||||
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
|
||||
if (assetId == removedAssetId)
|
||||
{
|
||||
m_removedCatalogId = assetId;
|
||||
SetPrimaryAsset({});
|
||||
}
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::SetPrimaryAsset(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
m_scriptCanvasAssetHolder.ClearAsset();
|
||||
m_sourceHandle = SourceHandle(nullptr, assetId.m_guid, {});
|
||||
|
||||
if (assetId.IsValid())
|
||||
auto completeAsset = CompleteDescription(m_sourceHandle);
|
||||
if (completeAsset)
|
||||
{
|
||||
ScriptCanvasMemoryAsset::pointer memoryAsset;
|
||||
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetId);
|
||||
|
||||
if (memoryAsset)
|
||||
{
|
||||
m_scriptCanvasAssetHolder.SetAsset(memoryAsset->GetFileAssetId());
|
||||
OnScriptCanvasAssetChanged(memoryAsset->GetFileAssetId());
|
||||
SetName(memoryAsset->GetTabName());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto scriptCanvasAsset = AZ::Data::AssetManager::Instance().FindAsset(assetId, AZ::Data::AssetLoadBehavior::Default);
|
||||
if (scriptCanvasAsset)
|
||||
{
|
||||
m_scriptCanvasAssetHolder.SetAsset(assetId);
|
||||
}
|
||||
}
|
||||
m_sourceHandle = *completeAsset;
|
||||
}
|
||||
|
||||
OnScriptCanvasAssetChanged(SourceChangeDescription::SelectionChanged);
|
||||
SetName(m_sourceHandle.Path().Filename().Native());
|
||||
AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues);
|
||||
}
|
||||
|
||||
AZ::Data::AssetId EditorScriptCanvasComponent::GetAssetId() const
|
||||
{
|
||||
return m_scriptCanvasAssetHolder.GetAssetId();
|
||||
return m_sourceHandle.Id();
|
||||
}
|
||||
|
||||
AZ::EntityId EditorScriptCanvasComponent::GetGraphEntityId() const
|
||||
AZ::u32 EditorScriptCanvasComponent::OnFileSelectionChanged()
|
||||
{
|
||||
AZ::EntityId scriptCanvasEntityId;
|
||||
AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId();
|
||||
|
||||
if (assetId.IsValid())
|
||||
{
|
||||
AssetTrackerRequestBus::BroadcastResult(scriptCanvasEntityId, &AssetTrackerRequests::GetScriptCanvasId, assetId);
|
||||
}
|
||||
|
||||
return scriptCanvasEntityId;
|
||||
m_sourceHandle = SourceHandle(nullptr, m_sourceHandle.Path());
|
||||
CompleteDescriptionInPlace(m_sourceHandle);
|
||||
m_previousHandle = {};
|
||||
m_removedHandle = {};
|
||||
OnScriptCanvasAssetChanged(SourceChangeDescription::SelectionChanged);
|
||||
return AZ::Edit::PropertyRefreshLevels::EntireTree;
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset)
|
||||
|
||||
void EditorScriptCanvasComponent::OnScriptCanvasAssetChanged(SourceChangeDescription changeDescription)
|
||||
{
|
||||
OnScriptCanvasAssetReady(asset);
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnAssetSaved(const ScriptCanvasMemoryAsset::pointer asset, bool isSuccessful)
|
||||
{
|
||||
if (isSuccessful)
|
||||
{
|
||||
OnScriptCanvasAssetReady(asset);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnAssetReloaded(const ScriptCanvasMemoryAsset::pointer asset)
|
||||
{
|
||||
OnScriptCanvasAssetReady(asset);
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnScriptCanvasAssetChanged(AZ::Data::AssetId assetId)
|
||||
{
|
||||
AssetTrackerNotificationBus::Handler::BusDisconnect();
|
||||
ScriptCanvas::GraphIdentifier newIdentifier = GetGraphIdentifier();
|
||||
newIdentifier.m_assetId = assetId;
|
||||
newIdentifier.m_assetId = m_sourceHandle.Id();
|
||||
|
||||
ScriptCanvas::GraphIdentifier oldIdentifier = GetGraphIdentifier();
|
||||
oldIdentifier.m_assetId = m_previousAssetId;
|
||||
oldIdentifier.m_assetId = m_previousHandle.Id();
|
||||
|
||||
EditorLoggingComponentNotificationBus::Broadcast(&EditorLoggingComponentNotifications::OnAssetSwitched, GetNamedEntityId(), newIdentifier, oldIdentifier);
|
||||
|
||||
m_previousAssetId = m_scriptCanvasAssetHolder.GetAssetId();
|
||||
m_previousHandle = m_sourceHandle.Describe();
|
||||
|
||||
// Only clear our variables when we are given a new asset id
|
||||
// or when the asset was explicitly set to empty.
|
||||
//
|
||||
// i.e. do not clear variables when we lose the catalog asset.
|
||||
if ((assetId.IsValid() && assetId != m_removedCatalogId)
|
||||
|| (!assetId.IsValid() && !m_removedCatalogId.IsValid()))
|
||||
if (changeDescription == SourceChangeDescription::SelectionChanged)
|
||||
{
|
||||
ClearVariables();
|
||||
}
|
||||
|
||||
if (assetId.IsValid())
|
||||
if (m_sourceHandle.IsDescriptionValid())
|
||||
{
|
||||
AssetTrackerNotificationBus::Handler::BusConnect(assetId);
|
||||
|
||||
ScriptCanvasMemoryAsset::pointer memoryAsset;
|
||||
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetId);
|
||||
if (memoryAsset && memoryAsset->GetAsset().GetStatus() == AZ::Data::AssetData::AssetStatus::Ready)
|
||||
if (!m_sourceHandle.Get())
|
||||
{
|
||||
OnScriptCanvasAssetReady(memoryAsset);
|
||||
if (auto loaded = LoadFromFile(m_sourceHandle.Path().c_str()); loaded.IsSuccess())
|
||||
{
|
||||
m_sourceHandle = SourceHandle(loaded.TakeValue(), m_sourceHandle.Id(), m_sourceHandle.Path().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_sourceHandle.Get())
|
||||
{
|
||||
UpdatePropertyDisplay(m_sourceHandle);
|
||||
}
|
||||
}
|
||||
|
||||
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnStartPlayInEditor()
|
||||
void EditorScriptCanvasComponent::SetAssetId(const SourceHandle& assetId)
|
||||
{
|
||||
ScriptCanvas::Execution::PerformanceStatisticsEBus::Broadcast(&ScriptCanvas::Execution::PerformanceStatisticsBus::ClearSnaphotStatistics);
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnStopPlayInEditor()
|
||||
{
|
||||
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::SetAssetId(const AZ::Data::AssetId& assetId)
|
||||
{
|
||||
if (m_scriptCanvasAssetHolder.GetAssetId() != assetId)
|
||||
if (m_sourceHandle.Describe() != assetId.Describe())
|
||||
{
|
||||
// Invalidate the previously removed catalog id if we are setting a new asset id
|
||||
m_removedCatalogId.SetInvalid();
|
||||
SetPrimaryAsset(assetId);
|
||||
m_removedHandle = {};
|
||||
SetPrimaryAsset(assetId.Id());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::SourceFileChanged([[maybe_unused]] AZStd::string relativePath
|
||||
, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
|
||||
{
|
||||
if (fileAssetId == m_sourceHandle.Id())
|
||||
{
|
||||
if (auto handle = CompleteDescription(SourceHandle(nullptr, fileAssetId, {})))
|
||||
{
|
||||
m_sourceHandle = *handle;
|
||||
// consider queueing on tick bus
|
||||
OnScriptCanvasAssetChanged(SourceChangeDescription::Modified);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::SourceFileRemoved([[maybe_unused]] AZStd::string relativePath
|
||||
, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
|
||||
{
|
||||
if (fileAssetId == m_sourceHandle.Id())
|
||||
{
|
||||
m_removedHandle = m_sourceHandle;
|
||||
OnScriptCanvasAssetChanged(SourceChangeDescription::Removed);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::SourceFileFailed([[maybe_unused]] AZStd::string relativePath
|
||||
, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
|
||||
{
|
||||
if (fileAssetId == m_sourceHandle.Id())
|
||||
{
|
||||
m_removedHandle = m_sourceHandle;
|
||||
OnScriptCanvasAssetChanged(SourceChangeDescription::Error);
|
||||
}
|
||||
}
|
||||
|
||||
bool EditorScriptCanvasComponent::HasAssetId() const
|
||||
{
|
||||
return m_scriptCanvasAssetHolder.GetAssetId().IsValid();
|
||||
return !m_sourceHandle.Id().IsNull();
|
||||
}
|
||||
|
||||
ScriptCanvas::GraphIdentifier EditorScriptCanvasComponent::GetGraphIdentifier() const
|
||||
{
|
||||
// For now we don't want to deal with disambiguating duplicates of the same script running on one entity.
|
||||
// Should that change we need to add the component id back into this.
|
||||
return ScriptCanvas::GraphIdentifier(m_scriptCanvasAssetHolder.GetAssetId(), 0);
|
||||
return ScriptCanvas::GraphIdentifier(m_sourceHandle.Id(), 0);
|
||||
}
|
||||
|
||||
void EditorScriptCanvasComponent::OnScriptCanvasAssetReady(const ScriptCanvasMemoryAsset::pointer memoryAsset)
|
||||
void EditorScriptCanvasComponent::UpdatePropertyDisplay(const SourceHandle& sourceHandle)
|
||||
{
|
||||
if (memoryAsset->GetFileAssetId() == m_scriptCanvasAssetHolder.GetAssetId())
|
||||
if (sourceHandle.IsGraphValid())
|
||||
{
|
||||
auto assetData = memoryAsset->GetAsset();
|
||||
[[maybe_unused]] AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
|
||||
AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity");
|
||||
BuildGameEntityData();
|
||||
UpdateName();
|
||||
AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
|
||||
|
||||
@@ -17,6 +17,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <ScriptCanvas/Libraries/Core/EBusEventHandler.h>
|
||||
#include <ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h>
|
||||
#include <ScriptCanvas/Utils/NodeUtils.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
|
||||
#include <Editor/GraphCanvas/GraphCanvasEditorNotificationBusId.h>
|
||||
#include <Editor/Include/ScriptCanvas/GraphCanvas/NodeDescriptorBus.h>
|
||||
@@ -30,6 +31,62 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
AZStd::optional<SourceHandle> CompleteDescription(const SourceHandle& source)
|
||||
{
|
||||
if (source.IsDescriptionValid())
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetSystemRequestBus::Events* assetSystem = AzToolsFramework::AssetSystemRequestBus::FindFirstHandler();
|
||||
if (assetSystem)
|
||||
{
|
||||
AZStd::string watchFolder;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
|
||||
if (!source.Id().IsNull())
|
||||
{
|
||||
if (assetSystem->GetSourceInfoBySourceUUID(source.Id(), assetInfo, watchFolder))
|
||||
{
|
||||
AZ::IO::Path watchPath(watchFolder);
|
||||
AZ::IO::Path assetInfoPath(assetInfo.m_relativePath);
|
||||
SourceHandle fullPathHandle(nullptr, assetInfo.m_assetId.m_guid, watchPath / assetInfoPath);
|
||||
|
||||
if (assetSystem->GetSourceInfoBySourcePath(fullPathHandle.Path().c_str(), assetInfo, watchFolder) && assetInfo.m_assetId.IsValid())
|
||||
{
|
||||
AZ_Warning("ScriptCanvas", assetInfo.m_assetId.m_guid == source.Id(), "SourceHandle completion produced conflicting AssetId.");
|
||||
auto path = fullPathHandle.Path();
|
||||
return SourceHandle(source, assetInfo.m_assetId.m_guid, path.MakePreferred());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!source.Path().empty())
|
||||
{
|
||||
if (assetSystem->GetSourceInfoBySourcePath(source.Path().c_str(), assetInfo, watchFolder) && assetInfo.m_assetId.IsValid())
|
||||
{
|
||||
return SourceHandle(source, assetInfo.m_assetId.m_guid, source.Path());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
bool CompleteDescriptionInPlace(SourceHandle& source)
|
||||
{
|
||||
if (auto completed = CompleteDescription(source))
|
||||
{
|
||||
source = *completed;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
// NodeIdentifierFactory
|
||||
//////////////////////////
|
||||
|
||||
@@ -438,10 +438,11 @@ namespace ScriptCanvasEditor
|
||||
if (nodeConfig.IsValid())
|
||||
{
|
||||
ScriptCanvas::NodeUpdateSlotReport nodeUpdateSlotReport;
|
||||
auto nodeEntity = node->GetEntityId();
|
||||
auto nodeOutcome = graph->ReplaceNodeByConfig(node, nodeConfig, nodeUpdateSlotReport);
|
||||
if (nodeOutcome.IsSuccess())
|
||||
{
|
||||
ScriptCanvas::MergeUpdateSlotReport(node->GetEntityId(), sm->m_updateReport, nodeUpdateSlotReport);
|
||||
ScriptCanvas::MergeUpdateSlotReport(nodeEntity, sm->m_updateReport, nodeUpdateSlotReport);
|
||||
|
||||
sm->m_allNodes.erase(node);
|
||||
sm->m_outOfDateNodes.erase(node);
|
||||
@@ -675,20 +676,20 @@ namespace ScriptCanvasEditor
|
||||
RegisterState(ParseGraph);
|
||||
}
|
||||
|
||||
void EditorGraphUpgradeMachine::SetAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset)
|
||||
void EditorGraphUpgradeMachine::SetAsset(SourceHandle& asset)
|
||||
{
|
||||
if (m_asset != asset)
|
||||
{
|
||||
m_asset = asset;
|
||||
SetDebugPrefix(asset.GetHint());
|
||||
SetDebugPrefix(asset.Path().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void EditorGraphUpgradeMachine::OnComplete(IState::ExitStatus exitStatus)
|
||||
{
|
||||
UpgradeNotificationsBus::Broadcast(&UpgradeNotifications::OnGraphUpgradeComplete, m_asset, exitStatus == IState::ExitStatus::Skipped);
|
||||
|
||||
m_asset = {};
|
||||
// releasing the asset at this stage of the system tick causes a memory crash
|
||||
// m_asset = {};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Script/ScriptSystemBus.h>
|
||||
#include <Editor/Framework/ScriptCanvasTraceUtilities.h>
|
||||
#include <Editor/Framework/ScriptCanvasReporter.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace ScriptCanvasEditor
|
||||
AZ_Assert(loadResult.m_runtimeAsset, "failed to load dependent asset");
|
||||
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> luaAssetOutcome = AZ::Failure(AZStd::string("lua asset creation for function failed"));
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_graphPath);
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_editorAsset.Path().c_str());
|
||||
AZ_Assert(luaAssetOutcome.IsSuccess(), "failed to create Lua asset");
|
||||
|
||||
AZStd::string modulePath = namespacePath[0].data();
|
||||
@@ -112,18 +112,19 @@ namespace ScriptCanvasEditor
|
||||
|
||||
AZ_INLINE LoadTestGraphResult LoadTestGraph(AZStd::string_view graphPath)
|
||||
{
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> editorAsset;
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(editorAsset, &ScriptCanvasEditor::EditorAssetConversionBusTraits::LoadAsset, graphPath);
|
||||
|
||||
if (editorAsset.GetData())
|
||||
if (auto loadFileOutcome = LoadFromFile(graphPath); loadFileOutcome.IsSuccess())
|
||||
{
|
||||
AZ::Outcome< AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> assetOutcome = AZ::Failure(AZStd::string("asset creation failed"));
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(assetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateRuntimeAsset, editorAsset);
|
||||
auto& source = loadFileOutcome.GetValue();
|
||||
auto testableSource = SourceHandle(source, AZ::Uuid::CreateRandom(), source.Path().c_str());
|
||||
|
||||
AZ::Outcome<AZ::Data::Asset<ScriptCanvas::RuntimeAsset>, AZStd::string> assetOutcome(AZ::Failure(AZStd::string("asset create failed")));
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(assetOutcome
|
||||
, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateRuntimeAsset, testableSource);
|
||||
|
||||
if (assetOutcome.IsSuccess())
|
||||
{
|
||||
LoadTestGraphResult result;
|
||||
result.m_graphPath = graphPath;
|
||||
result.m_editorAsset = editorAsset;
|
||||
result.m_editorAsset = AZStd::move(testableSource);
|
||||
result.m_runtimeAsset = assetOutcome.GetValue();
|
||||
result.m_entity = AZStd::make_unique<AZ::Entity>("Loaded Graph");
|
||||
return result;
|
||||
@@ -164,8 +165,7 @@ namespace ScriptCanvasEditor
|
||||
reporter.SetExecutionMode(mode);
|
||||
|
||||
LoadTestGraphResult loadResult;
|
||||
loadResult.m_graphPath = asset.GetHint().c_str();
|
||||
loadResult.m_editorAsset = asset;
|
||||
loadResult.m_editorAsset = SourceHandle(nullptr, assetId.m_guid, asset.GetHint());
|
||||
AZ::EntityId scriptCanvasId;
|
||||
loadResult.m_entity = AZStd::make_unique<AZ::Entity>("Loaded test graph");
|
||||
loadResult.m_runtimeAsset = runtimeAsset;
|
||||
@@ -206,7 +206,8 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
ScopedOutputSuppression outputSuppressor;
|
||||
AZ::Outcome<ScriptCanvas::Translation::LuaAssetResult, AZStd::string> luaAssetOutcome = AZ::Failure(AZStd::string("lua asset creation failed"));
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_graphPath);
|
||||
ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome
|
||||
, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_editorAsset.Path().c_str());
|
||||
reporter.MarkParseAttemptMade();
|
||||
|
||||
if (luaAssetOutcome.IsSuccess())
|
||||
@@ -220,6 +221,8 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
RuntimeDataOverrides runtimeDataOverrides;
|
||||
runtimeDataOverrides.m_runtimeAsset = loadResult.m_runtimeAsset;
|
||||
runtimeDataOverrides.m_runtimeAsset.SetHint("original");
|
||||
runtimeDataOverrides.m_runtimeAsset.Get()->m_runtimeData.m_script.SetHint("original");
|
||||
|
||||
#if defined(LINUX) //////////////////////////////////////////////////////////////////////////
|
||||
// Temporarily disable testing on the Linux build until the file name casing discrepancy
|
||||
@@ -265,6 +268,10 @@ namespace ScriptCanvasEditor
|
||||
|
||||
RuntimeDataOverrides dependencyRuntimeDataOverrides;
|
||||
dependencyRuntimeDataOverrides.m_runtimeAsset = dependency.runtimeAsset;
|
||||
AZStd::string dependencyHint = AZStd::string::format("dependency_%d", index);
|
||||
dependencyRuntimeDataOverrides.m_runtimeAsset.SetHint(dependencyHint);
|
||||
dependencyRuntimeDataOverrides.m_runtimeAsset.Get()->m_runtimeData.m_script.SetHint(dependencyHint);
|
||||
|
||||
runtimeDataOverrides.m_dependencies.push_back(dependencyRuntimeDataOverrides);
|
||||
|
||||
RuntimeData& dependencyData = dependencyDataBuffer[index];
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <ScriptCanvas/Libraries/Logic/Logic.h>
|
||||
#include <ScriptCanvas/Libraries/Math/Math.h>
|
||||
#include <ScriptCanvas/Variable/VariableBus.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -45,11 +46,10 @@ namespace ScriptCanvasEditor
|
||||
|
||||
struct LoadTestGraphResult
|
||||
{
|
||||
AZStd::string_view m_graphPath;
|
||||
AZStd::unique_ptr<AZ::Entity> m_entity;
|
||||
ScriptCanvas::RuntimeComponent* m_runtimeComponent = nullptr;
|
||||
bool m_nativeFunctionFound = false;
|
||||
AZ::Data::Asset<ScriptCanvasEditor::ScriptCanvasAsset> m_editorAsset;
|
||||
SourceHandle m_editorAsset;
|
||||
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> m_runtimeAsset;
|
||||
AZ::Data::Asset<AZ::ScriptAsset> m_scriptAsset;
|
||||
};
|
||||
@@ -161,7 +161,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
struct ScopedOutputSuppression
|
||||
{
|
||||
ScopedOutputSuppression(bool suppressState = true)
|
||||
ScopedOutputSuppression([[maybe_unused]] bool suppressState = true)
|
||||
{
|
||||
AZ::Debug::TraceMessageBus::BroadcastResult(m_oldSuppression, &AZ::Debug::TraceMessageEvents::OnOutput, "", "");
|
||||
TraceSuppressionBus::Broadcast(&TraceSuppressionRequests::SuppressAllOutput, suppressState);
|
||||
|
||||
+2
-1
@@ -97,7 +97,8 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, assetInfo.m_assetId, -1);
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset
|
||||
, SourceHandle( nullptr, assetInfo.m_assetId.m_guid, {} ), Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
return openOutcome.IsSuccess();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -190,7 +190,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
scriptCanvasSlot = eventHandler->GetSlot(slotId);
|
||||
|
||||
int& index = (scriptCanvasSlot->IsData() && scriptCanvasSlot->IsInput()) ? paramIndex : outputIndex;
|
||||
int& index = (scriptCanvasSlot && scriptCanvasSlot->IsData() && scriptCanvasSlot->IsInput()) ? paramIndex : outputIndex;
|
||||
|
||||
if (scriptCanvasSlot && scriptCanvasSlot->IsVisible())
|
||||
{
|
||||
|
||||
@@ -20,11 +20,6 @@ namespace AZ
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
AZ::Outcome<void, AZStd::string> LoadScriptCanvasDataFromJson
|
||||
( ScriptCanvas::ScriptCanvasData& dataTarget
|
||||
, AZStd::string_view source
|
||||
, AZ::SerializeContext& serializeContext);
|
||||
|
||||
/**
|
||||
* Manages editor Script Canvas graph assets.
|
||||
*/
|
||||
|
||||
-13
@@ -7,17 +7,4 @@
|
||||
*/
|
||||
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
Graph* ScriptCanvasData::ModGraph()
|
||||
{
|
||||
return AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Graph>(m_scriptCanvasEntity.get());
|
||||
}
|
||||
|
||||
const Graph* ScriptCanvasData::GetGraph() const
|
||||
{
|
||||
return AZ::EntityUtils::FindFirstDerivedComponent<ScriptCanvas::Graph>(m_scriptCanvasEntity.get());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-23
@@ -13,27 +13,5 @@
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
class ScriptCanvasData
|
||||
{
|
||||
public:
|
||||
|
||||
AZ_RTTI(ScriptCanvasData, "{1072E894-0C67-4091-8B64-F7DB324AD13C}");
|
||||
AZ_CLASS_ALLOCATOR(ScriptCanvasData, AZ::SystemAllocator, 0);
|
||||
ScriptCanvasData() {}
|
||||
virtual ~ScriptCanvasData() {}
|
||||
ScriptCanvasData(ScriptCanvasData&& other);
|
||||
ScriptCanvasData& operator=(ScriptCanvasData&& other);
|
||||
|
||||
static void Reflect(AZ::ReflectContext* reflectContext);
|
||||
|
||||
AZ::Entity* GetScriptCanvasEntity() const { return m_scriptCanvasEntity.get(); }
|
||||
|
||||
Graph* ModGraph();
|
||||
|
||||
const Graph* GetGraph() const;
|
||||
|
||||
AZStd::unique_ptr<AZ::Entity> m_scriptCanvasEntity;
|
||||
private:
|
||||
ScriptCanvasData(const ScriptCanvasData&) = delete;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetTypeInfoBus.h>
|
||||
#include <AzCore/Serialization/ObjectStream.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class SerializeContext;
|
||||
}
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
class ScriptCanvasData;
|
||||
}
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
class EditorAssetTree
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(EditorAssetTree, AZ::SystemAllocator, 0);
|
||||
|
||||
EditorAssetTree* m_parent = nullptr;
|
||||
AZStd::vector<EditorAssetTree> m_dependencies;
|
||||
SourceHandle m_asset;
|
||||
|
||||
EditorAssetTree* ModRoot();
|
||||
|
||||
void SetParent(EditorAssetTree& parent);
|
||||
|
||||
AZStd::string ToString(size_t depth = 0) const;
|
||||
};
|
||||
|
||||
AZ::Outcome<SourceHandle, AZStd::string> LoadFromFile(AZStd::string_view path);
|
||||
|
||||
AZ::Outcome<void, AZStd::string> LoadDataFromJson
|
||||
( ScriptCanvas::ScriptCanvasData& dataTarget
|
||||
, AZStd::string_view source
|
||||
, AZ::SerializeContext& serializeContext);
|
||||
|
||||
AZ::Outcome<EditorAssetTree, AZStd::string> LoadEditorAssetTree(SourceHandle handle, EditorAssetTree* parent = nullptr);
|
||||
|
||||
AZ::Outcome<void, AZStd::string> SaveToStream(const SourceHandle& source, AZ::IO::GenericStream& stream);
|
||||
}
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <ScriptCanvas/Variable/VariableCore.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
|
||||
namespace GraphCanvas
|
||||
{
|
||||
class GraphCanvasTreeItem;
|
||||
@@ -70,7 +72,7 @@ namespace ScriptCanvasEditor
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AZ::EntityId;
|
||||
|
||||
virtual void SetAssetId(const AZ::Data::AssetId& assetId) = 0;
|
||||
virtual void SetAssetId(const SourceHandle& assetId) = 0;
|
||||
virtual bool HasAssetId() const = 0;
|
||||
};
|
||||
|
||||
@@ -89,40 +91,13 @@ namespace ScriptCanvasEditor
|
||||
};
|
||||
|
||||
using EditorContextMenuRequestBus = AZ::EBus<EditorContextMenuRequests>;
|
||||
|
||||
class EditorScriptCanvasAssetNotifications : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AZ::Data::AssetId;
|
||||
|
||||
//! Notification which fires after an EditorGraph has received it's on AssetReady callback
|
||||
//! \param scriptCanvasAsset Script Canvas asset which is now ready for use in the Editor
|
||||
virtual void OnScriptCanvasAssetReady(const AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>& /*scriptCanvasAsset*/) {};
|
||||
|
||||
//! Notification which fires after an EditorGraph has received it's on AssetReloaded callback
|
||||
//! \param scriptCanvasAsset Script Canvas asset which is now ready for use in the Editor
|
||||
virtual void OnScriptCanvasAssetReloaded(const AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>& /*scriptCanvaAsset */) {};
|
||||
|
||||
//! Notification which fires after an EditorGraph has received it's on AssetReady callback
|
||||
//! \param AssetId AssetId of unloaded ScriptCanvas
|
||||
virtual void OnScriptCanvasAssetUnloaded(const AZ::Data::AssetId& /*assetId*/) {};
|
||||
|
||||
//! Notification which fires after an EditorGraph has received an onAssetSaved callback
|
||||
//! \param scriptCanvasAsset Script Canvas asset which was attempted to be saved
|
||||
//! \param isSuccessful specified where the Script Canvas asset was successfully saved
|
||||
virtual void OnScriptCanvasAssetSaved(const AZ::Data::AssetId) {};
|
||||
};
|
||||
using EditorScriptCanvasAssetNotificationBus = AZ::EBus<EditorScriptCanvasAssetNotifications>;
|
||||
|
||||
|
||||
class EditorGraphRequests : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = ScriptCanvas::ScriptCanvasId;
|
||||
|
||||
virtual void SetAssetId(const AZ::Data::AssetId& assetId) = 0;
|
||||
|
||||
virtual void CreateGraphCanvasScene() = 0;
|
||||
virtual void ClearGraphCanvasScene() = 0;
|
||||
virtual GraphCanvas::GraphId GetGraphCanvasGraphId() const = 0;
|
||||
@@ -225,7 +200,7 @@ namespace ScriptCanvasEditor
|
||||
virtual void OnUpgradeStart() {}
|
||||
virtual void OnUpgradeCancelled() {}
|
||||
|
||||
virtual void OnGraphUpgradeComplete(AZ::Data::Asset<AZ::Data::AssetData>&, bool skipped = false) { (void)skipped; }
|
||||
virtual void OnGraphUpgradeComplete(SourceHandle&, bool skipped = false) { (void)skipped; }
|
||||
};
|
||||
|
||||
using UpgradeNotificationsBus = AZ::EBus<UpgradeNotifications>;
|
||||
|
||||
@@ -8,18 +8,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <GraphCanvas/Types/Types.h>
|
||||
|
||||
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Bus/NodeIdPair.h>
|
||||
|
||||
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <ScriptCanvas/Data/Data.h>
|
||||
|
||||
class QLineEdit;
|
||||
@@ -49,6 +47,17 @@ namespace ScriptCanvasEditor
|
||||
struct CategoryInformation;
|
||||
struct NodePaletteModelInformation;
|
||||
|
||||
namespace Tracker
|
||||
{
|
||||
enum class ScriptCanvasFileState : AZ::s32
|
||||
{
|
||||
NEW,
|
||||
MODIFIED,
|
||||
UNMODIFIED,
|
||||
SOURCE_REMOVED,
|
||||
INVALID = -1
|
||||
};
|
||||
}
|
||||
|
||||
namespace Widget
|
||||
{
|
||||
@@ -70,16 +79,16 @@ namespace ScriptCanvasEditor
|
||||
//! Opens an existing graph and returns the tab index in which it was open in.
|
||||
//! \param File AssetId
|
||||
//! \return index of open tab if the asset was able to be open successfully or error message of why the open failed
|
||||
virtual AZ::Outcome<int, AZStd::string> OpenScriptCanvasAsset(AZ::Data::AssetId scriptCanvasAssetId, int tabIndex = -1) = 0;
|
||||
virtual AZ::Outcome<int, AZStd::string> OpenScriptCanvasAssetId(const AZ::Data::AssetId& scriptCanvasAsset) = 0;
|
||||
virtual AZ::Outcome<int, AZStd::string> OpenScriptCanvasAsset(SourceHandle scriptCanvasAssetId, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1) = 0;
|
||||
virtual AZ::Outcome<int, AZStd::string> OpenScriptCanvasAssetId(const SourceHandle& scriptCanvasAsset, Tracker::ScriptCanvasFileState fileState) = 0;
|
||||
|
||||
virtual int CloseScriptCanvasAsset(const AZ::Data::AssetId&) = 0;
|
||||
virtual int CloseScriptCanvasAsset(const SourceHandle&) = 0;
|
||||
|
||||
virtual bool CreateScriptCanvasAssetFor(const TypeDefs::EntityComponentId& requestingComponent) = 0;
|
||||
|
||||
virtual bool IsScriptCanvasAssetOpen(const AZ::Data::AssetId& assetId) const = 0;
|
||||
virtual bool IsScriptCanvasAssetOpen(const SourceHandle& assetId) const = 0;
|
||||
|
||||
virtual void OnChangeActiveGraphTab(AZ::Data::AssetId) {}
|
||||
virtual void OnChangeActiveGraphTab(SourceHandle) {}
|
||||
|
||||
virtual void CreateNewRuntimeAsset() = 0;
|
||||
|
||||
@@ -103,12 +112,12 @@ namespace ScriptCanvasEditor
|
||||
return ScriptCanvas::ScriptCanvasId();
|
||||
}
|
||||
|
||||
virtual GraphCanvas::GraphId FindGraphCanvasGraphIdByAssetId([[maybe_unused]] const AZ::Data::AssetId& assetId) const
|
||||
virtual GraphCanvas::GraphId FindGraphCanvasGraphIdByAssetId([[maybe_unused]] const SourceHandle& assetId) const
|
||||
{
|
||||
return GraphCanvas::GraphId();
|
||||
}
|
||||
|
||||
virtual ScriptCanvas::ScriptCanvasId FindScriptCanvasIdByAssetId([[maybe_unused]] const AZ::Data::AssetId& assetId) const
|
||||
virtual ScriptCanvas::ScriptCanvasId FindScriptCanvasIdByAssetId([[maybe_unused]] const SourceHandle& assetId) const
|
||||
{
|
||||
return ScriptCanvas::ScriptCanvasId();
|
||||
}
|
||||
@@ -126,7 +135,7 @@ namespace ScriptCanvasEditor
|
||||
virtual void DisconnectEndpoints(const AZ::EntityId& /*sceneId*/, const AZStd::vector<GraphCanvas::Endpoint>& /*endpoints*/) {}
|
||||
|
||||
virtual void PostUndoPoint(ScriptCanvas::ScriptCanvasId) = 0;
|
||||
virtual void SignalSceneDirty(AZ::Data::AssetId) = 0;
|
||||
virtual void SignalSceneDirty(SourceHandle) = 0;
|
||||
|
||||
// Increment the value of the ignore undo point tracker
|
||||
virtual void PushPreventUndoStateUpdate() = 0;
|
||||
@@ -165,7 +174,7 @@ namespace ScriptCanvasEditor
|
||||
public:
|
||||
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
|
||||
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
|
||||
using BusIdType = AZ::Data::AssetId;
|
||||
using BusIdType = SourceHandle;
|
||||
|
||||
virtual void OnAssetVisualized() {};
|
||||
virtual void OnAssetUnloaded() {};
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <GraphCanvas/Widgets/NodePropertyBus.h>
|
||||
|
||||
#include <Editor/Include/ScriptCanvas/Components/GraphUpgrade.h>
|
||||
#include <Editor/Assets/ScriptCanvasUndoHelper.h>
|
||||
|
||||
namespace ScriptCanvas
|
||||
{
|
||||
@@ -101,6 +102,8 @@ namespace ScriptCanvasEditor
|
||||
public:
|
||||
AZ_COMPONENT(Graph, "{4D755CA9-AB92-462C-B24F-0B3376F19967}", ScriptCanvas::Graph);
|
||||
|
||||
static ScriptCanvas::DataPtr Create();
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
Graph(const ScriptCanvas::ScriptCanvasId& scriptCanvasId = AZ::Entity::MakeId())
|
||||
@@ -138,10 +141,6 @@ namespace ScriptCanvasEditor
|
||||
void ReleaseVariableCounter(AZ::u32 variableCounter) override;
|
||||
////
|
||||
|
||||
// RuntimeBus
|
||||
AZ::Data::AssetId GetAssetId() const override { return m_assetId; }
|
||||
////
|
||||
|
||||
// GraphCanvas::GraphModelRequestBus
|
||||
void RequestUndoPoint() override;
|
||||
|
||||
@@ -221,9 +220,6 @@ namespace ScriptCanvasEditor
|
||||
void OnGraphCanvasNodeCreated(const AZ::EntityId& nodeId) override;
|
||||
///////////////////////////
|
||||
|
||||
// EditorGraphRequestBus
|
||||
void SetAssetId(const AZ::Data::AssetId& assetId) override { m_assetId = assetId; }
|
||||
|
||||
void CreateGraphCanvasScene() override;
|
||||
void ClearGraphCanvasScene() override;
|
||||
void DisplayGraphCanvasScene() override;
|
||||
@@ -235,7 +231,7 @@ namespace ScriptCanvasEditor
|
||||
IfOutOfDate,
|
||||
Forced
|
||||
};
|
||||
bool UpgradeGraph(const AZ::Data::Asset<AZ::Data::AssetData>& asset, UpgradeRequest request, bool isVerbose = true);
|
||||
bool UpgradeGraph(SourceHandle& asset, UpgradeRequest request, bool isVerbose = true);
|
||||
void ConnectGraphCanvasBuses();
|
||||
void DisconnectGraphCanvasBuses();
|
||||
///////
|
||||
@@ -302,12 +298,13 @@ namespace ScriptCanvasEditor
|
||||
void OnUndoRedoEnd() override;
|
||||
////
|
||||
|
||||
void SetAssetType(AZ::Data::AssetType);
|
||||
|
||||
void ReportError(const ScriptCanvas::Node& node, const AZStd::string& errorSource, const AZStd::string& errorMessage) override;
|
||||
|
||||
const GraphStatisticsHelper& GetNodeUsageStatistics() const;
|
||||
|
||||
void MarkOwnership(ScriptCanvas::ScriptCanvasData& owner);
|
||||
ScriptCanvas::DataPtr GetOwnership() const;
|
||||
|
||||
// Finds and returns all nodes within the graph that are of the specified type
|
||||
template <typename NodeType>
|
||||
AZStd::vector<const NodeType*> GetNodesOfType() const
|
||||
@@ -384,12 +381,15 @@ namespace ScriptCanvasEditor
|
||||
|
||||
GraphCanvas::NodeFocusCyclingHelper m_focusHelper;
|
||||
GraphStatisticsHelper m_statisticsHelper;
|
||||
UndoHelper m_undoHelper;
|
||||
|
||||
bool m_ignoreSaveRequests;
|
||||
|
||||
//! Defaults to true to signal that this graph does not have the GraphCanvas stuff intermingled
|
||||
bool m_saveFormatConverted = true;
|
||||
|
||||
AZ::Data::AssetId m_assetId;
|
||||
ScriptCanvasEditor::SourceHandle m_assetId;
|
||||
// temporary step in cleaning up the graph / asset class structure. This reference is deliberately weak.
|
||||
ScriptCanvas::ScriptCanvasData* m_owner;
|
||||
};
|
||||
}
|
||||
|
||||
+37
-26
@@ -9,12 +9,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Asset/AssetCatalogBus.h>
|
||||
#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
#include <AzToolsFramework/ToolsComponents/EditorComponentBase.h>
|
||||
#include <Builder/ScriptCanvasBuilder.h>
|
||||
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
|
||||
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Components/EditorScriptCanvasComponentSerializer.h>
|
||||
#include <ScriptCanvas/Execution/RuntimeComponent.h>
|
||||
#include <ScriptCanvas/Variable/VariableBus.h>
|
||||
|
||||
@@ -34,19 +36,23 @@ namespace ScriptCanvasEditor
|
||||
: public AzToolsFramework::Components::EditorComponentBase
|
||||
, private EditorContextMenuRequestBus::Handler
|
||||
, private AzFramework::AssetCatalogEventBus::Handler
|
||||
, private AzToolsFramework::AssetSystemBus::Handler
|
||||
, private EditorScriptCanvasComponentLoggingBus::Handler
|
||||
, private EditorScriptCanvasComponentRequestBus::Handler
|
||||
, private AssetTrackerNotificationBus::Handler
|
||||
, private AzToolsFramework::EditorEntityContextNotificationBus::Handler
|
||||
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(EditorScriptCanvasComponent, "{C28E2D29-0746-451D-A639-7F113ECF5D72}", AzToolsFramework::Components::EditorComponentBase);
|
||||
|
||||
friend class AZ::EditorScriptCanvasComponentSerializer;
|
||||
|
||||
EditorScriptCanvasComponent();
|
||||
EditorScriptCanvasComponent(AZ::Data::Asset<ScriptCanvasAsset> asset);
|
||||
EditorScriptCanvasComponent(const SourceHandle& sourceHandle);
|
||||
~EditorScriptCanvasComponent() override;
|
||||
|
||||
// sets the soure but does not attempt to load anything;
|
||||
void InitializeSource(const SourceHandle& sourceHandle);
|
||||
|
||||
//=====================================================================
|
||||
// AZ::Component
|
||||
void Init() override;
|
||||
@@ -66,17 +72,16 @@ namespace ScriptCanvasEditor
|
||||
ScriptCanvas::GraphIdentifier GetGraphIdentifier() const override;
|
||||
//=====================================================================
|
||||
|
||||
void OpenEditor();
|
||||
void CloseGraph();
|
||||
|
||||
void SetName(const AZStd::string& name) { m_name = name; }
|
||||
void OpenEditor(const AZ::Data::AssetId&, const AZ::Data::AssetType&);
|
||||
|
||||
void SetName(AZStd::string_view name) { m_name = name; }
|
||||
const AZStd::string& GetName() const;
|
||||
AZ::EntityId GetEditorEntityId() const { return GetEntity() ? GetEntityId() : AZ::EntityId(); }
|
||||
AZ::NamedEntityId GetNamedEditorEntityId() const { return GetEntity() ? GetNamedEntityId() : AZ::NamedEntityId(); }
|
||||
|
||||
//=====================================================================
|
||||
// EditorScriptCanvasComponentRequestBus
|
||||
void SetAssetId(const AZ::Data::AssetId& assetId) override;
|
||||
void SetAssetId(const SourceHandle& assetId) override;
|
||||
bool HasAssetId() const override;
|
||||
//=====================================================================
|
||||
|
||||
@@ -84,23 +89,23 @@ namespace ScriptCanvasEditor
|
||||
// EditorContextMenuRequestBus
|
||||
AZ::Data::AssetId GetAssetId() const override;
|
||||
//=====================================================================
|
||||
AZ::EntityId GetGraphEntityId() const;
|
||||
|
||||
//=====================================================================
|
||||
// AssetTrackerNotificationBus
|
||||
void OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset) override;
|
||||
void OnAssetSaved(const ScriptCanvasMemoryAsset::pointer asset, bool isSuccessful) override;
|
||||
void OnAssetReloaded(const ScriptCanvasMemoryAsset::pointer asset) override;
|
||||
//=====================================================================
|
||||
|
||||
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// EditorEntityContextNotificationBus
|
||||
void OnStartPlayInEditor() override;
|
||||
|
||||
void OnStopPlayInEditor() override;
|
||||
|
||||
|
||||
protected:
|
||||
enum class SourceChangeDescription : AZ::u8
|
||||
{
|
||||
Error,
|
||||
Modified,
|
||||
Removed,
|
||||
SelectionChanged,
|
||||
};
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
|
||||
@@ -118,25 +123,31 @@ namespace ScriptCanvasEditor
|
||||
(void)incompatible;
|
||||
}
|
||||
|
||||
void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override;
|
||||
void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override;
|
||||
void OnScriptCanvasAssetChanged(AZ::Data::AssetId assetId);
|
||||
// complete the id, load call OnScriptCanvasAssetChanged
|
||||
void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
|
||||
// update the display icon for failure, save the values in the graph
|
||||
void SourceFileRemoved(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
|
||||
void SourceFileFailed(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
|
||||
|
||||
AZ::u32 OnFileSelectionChanged();
|
||||
|
||||
void OnScriptCanvasAssetChanged(SourceChangeDescription changeDescription);
|
||||
|
||||
void UpdateName();
|
||||
|
||||
//=====================================================================
|
||||
void OnScriptCanvasAssetReady(const ScriptCanvasMemoryAsset::pointer asset);
|
||||
void UpdatePropertyDisplay(const SourceHandle& sourceHandle);
|
||||
//=====================================================================
|
||||
|
||||
void BuildGameEntityData();
|
||||
void ClearVariables();
|
||||
|
||||
private:
|
||||
AZ::Data::AssetId m_removedCatalogId;
|
||||
AZ::Data::AssetId m_previousAssetId;
|
||||
AZStd::string m_name;
|
||||
ScriptCanvasAssetHolder m_scriptCanvasAssetHolder;
|
||||
bool m_runtimeDataIsValid = false;
|
||||
ScriptCanvasBuilder::BuildVariableOverrides m_variableOverrides;
|
||||
SourceHandle m_sourceHandle;
|
||||
SourceHandle m_previousHandle;
|
||||
SourceHandle m_removedHandle;
|
||||
};
|
||||
}
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Components/EditorScriptCanvasComponentSerializer.h>
|
||||
#include <ScriptCanvas/Components/EditorScriptCanvasComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_CLASS_ALLOCATOR_IMPL(EditorScriptCanvasComponentSerializer, SystemAllocator, 0);
|
||||
|
||||
JsonSerializationResult::Result EditorScriptCanvasComponentSerializer::Load
|
||||
( void* outputValue
|
||||
, const Uuid& outputValueTypeId
|
||||
, const rapidjson::Value& inputValue
|
||||
, JsonDeserializerContext& context)
|
||||
{
|
||||
namespace JSR = JsonSerializationResult;
|
||||
|
||||
AZ_Assert(outputValueTypeId == azrtti_typeid<ScriptCanvasEditor::EditorScriptCanvasComponent>()
|
||||
, "EditorScriptCanvasComponentSerializer Load against output typeID that was not EditorScriptCanvasComponent");
|
||||
AZ_Assert(outputValue, "EditorScriptCanvasComponentSerializer Load against null output");
|
||||
|
||||
// load as parent class
|
||||
auto outputComponent = reinterpret_cast<ScriptCanvasEditor::EditorScriptCanvasComponent*>(outputValue);
|
||||
JsonSerializationResult::ResultCode result = BaseJsonSerializer::Load(outputValue
|
||||
, azrtti_typeid<AzToolsFramework::Components::EditorComponentBase>(), inputValue, context);
|
||||
|
||||
// load child data one by one...
|
||||
result.Combine(BaseJsonSerializer::Load(outputValue, outputValueTypeId, inputValue, context));
|
||||
|
||||
if (result.GetProcessing() != JSR::Processing::Halted)
|
||||
{
|
||||
result.Combine(ContinueLoadingFromJsonObjectField
|
||||
( &outputComponent->m_name
|
||||
, azrtti_typeid(outputComponent->m_name)
|
||||
, inputValue
|
||||
, "m_name"
|
||||
, context));
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField
|
||||
( &outputComponent->m_runtimeDataIsValid
|
||||
, azrtti_typeid(outputComponent->m_runtimeDataIsValid)
|
||||
, inputValue
|
||||
, "runtimeDataIsValid"
|
||||
, context));
|
||||
|
||||
result.Combine(ContinueLoadingFromJsonObjectField
|
||||
( &outputComponent->m_variableOverrides
|
||||
, azrtti_typeid(outputComponent->m_variableOverrides)
|
||||
, inputValue
|
||||
, "runtimeDataOverrides"
|
||||
, context));
|
||||
|
||||
auto assetHolderMember = inputValue.FindMember("m_assetHolder");
|
||||
if (assetHolderMember == inputValue.MemberEnd())
|
||||
{
|
||||
// file was saved with SourceHandle data
|
||||
result.Combine(ContinueLoadingFromJsonObjectField
|
||||
( &outputComponent->m_sourceHandle
|
||||
, azrtti_typeid(outputComponent->m_sourceHandle)
|
||||
, inputValue
|
||||
, "sourceHandle"
|
||||
, context));
|
||||
}
|
||||
else
|
||||
{
|
||||
// manually load the old asset info data
|
||||
const rapidjson::Value& assetHolderValue = assetHolderMember->value;
|
||||
if (auto assetMember = assetHolderValue.FindMember("m_asset"); assetMember != assetHolderValue.MemberEnd())
|
||||
{
|
||||
const rapidjson::Value& assetValue = assetMember->value;
|
||||
|
||||
AZ::Data::AssetId assetId{};
|
||||
if (auto assetIdMember = assetValue.FindMember("assetId"); assetIdMember != assetValue.MemberEnd())
|
||||
{
|
||||
result.Combine(ContinueLoading(&assetId, azrtti_typeid(assetId), assetIdMember->value, context));
|
||||
}
|
||||
|
||||
AZStd::string path{};
|
||||
if (auto pathMember = assetValue.FindMember("assetHint"); pathMember != assetValue.MemberEnd())
|
||||
{
|
||||
result.Combine(ContinueLoading(&path, azrtti_typeid(path), pathMember->value, context));
|
||||
}
|
||||
|
||||
if (result.GetProcessing() != JSR::Processing::Halted)
|
||||
{
|
||||
outputComponent->InitializeSource(ScriptCanvasEditor::SourceHandle(nullptr, assetId.m_guid, path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
|
||||
? "EditorScriptCanvasComponentSerializer Load finished loading EditorScriptCanvasComponent"
|
||||
: "EditorScriptCanvasComponentSerializer Load failed to load EditorScriptCanvasComponent");
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class EditorScriptCanvasComponentSerializer
|
||||
: public BaseJsonSerializer
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(EditorScriptCanvasComponentSerializer, "{80B497B3-ABC1-4991-A3C4-047A8CB2C26C}", BaseJsonSerializer);
|
||||
AZ_CLASS_ALLOCATOR_DECL;
|
||||
|
||||
private:
|
||||
JsonSerializationResult::Result Load
|
||||
( void* outputValue
|
||||
, const Uuid& outputValueTypeId
|
||||
, const rapidjson::Value& inputValue
|
||||
, JsonDeserializerContext& context) override;
|
||||
};
|
||||
}
|
||||
@@ -21,6 +21,13 @@ namespace GraphCanvas
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
// If only the Path or the Id is valid, attempts to fill in the missing piece.
|
||||
// If both Path and Id is valid, including after correction, returns the handle including source Data,
|
||||
// otherwise, returns null
|
||||
AZStd::optional<SourceHandle> CompleteDescription(const SourceHandle& source);
|
||||
// if CompleteDescription() succeeds, sets the handle to the result, else does nothing
|
||||
bool CompleteDescriptionInPlace(SourceHandle& source);
|
||||
|
||||
class Graph;
|
||||
class NodePaletteModel;
|
||||
|
||||
|
||||
@@ -102,9 +102,6 @@ namespace ScriptCanvasEditor
|
||||
void Log(const char* format, ...);
|
||||
|
||||
private:
|
||||
|
||||
bool m_verbose = true;
|
||||
|
||||
StateMachine* m_stateMachine;
|
||||
};
|
||||
|
||||
@@ -184,9 +181,9 @@ namespace ScriptCanvasEditor
|
||||
bool m_graphNeedsDirtying = false;
|
||||
|
||||
Graph* m_graph = nullptr;
|
||||
AZ::Data::Asset<AZ::Data::AssetData> m_asset;
|
||||
SourceHandle m_asset;
|
||||
|
||||
void SetAsset(const AZ::Data::Asset<AZ::Data::AssetData>& asset);
|
||||
void SetAsset(SourceHandle& assetasset);
|
||||
|
||||
void OnComplete(IState::ExitStatus exitStatus) override;
|
||||
|
||||
@@ -363,7 +360,7 @@ namespace ScriptCanvasEditor
|
||||
template <typename Traits>
|
||||
void ScriptCanvasEditor::State<Traits>::Log(const char* format, ...)
|
||||
{
|
||||
if (m_verbose)
|
||||
if (m_stateMachine->GetVerbose())
|
||||
{
|
||||
char sBuffer[2048];
|
||||
va_list ArgList;
|
||||
|
||||
@@ -393,7 +393,7 @@ namespace ScriptCanvasEditor::Nodes
|
||||
|
||||
if (methodNode->HasBusID() && busId == slot.GetId() && slot.GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn())
|
||||
{
|
||||
key = Translation::GlobalKeys::EBusSenderIDKey;
|
||||
key = ::Translation::GlobalKeys::EBusSenderIDKey;
|
||||
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key + ".details", details);
|
||||
}
|
||||
else
|
||||
@@ -508,7 +508,7 @@ namespace ScriptCanvasEditor::Nodes
|
||||
if (busNode->IsIDRequired() && slot->GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn())
|
||||
{
|
||||
GraphCanvas::TranslationKey key;
|
||||
key << Translation::GlobalKeys::EBusHandlerIDKey << "details";
|
||||
key << ::Translation::GlobalKeys::EBusHandlerIDKey << "details";
|
||||
GraphCanvas::TranslationRequests::Details details;
|
||||
details.m_name = slot->GetName();
|
||||
details.m_tooltip = slot->GetToolTip();
|
||||
@@ -726,7 +726,7 @@ namespace ScriptCanvasEditor::Nodes
|
||||
if (busNode->IsIDRequired() && slot->GetDescriptor() == ScriptCanvas::SlotDescriptors::DataIn())
|
||||
{
|
||||
GraphCanvas::TranslationKey key;
|
||||
key << Translation::GlobalKeys::EBusHandlerIDKey << "details";
|
||||
key << ::Translation::GlobalKeys::EBusHandlerIDKey << "details";
|
||||
GraphCanvas::TranslationRequests::Details details;
|
||||
GraphCanvas::TranslationRequestBus::BroadcastResult(details, &GraphCanvas::TranslationRequests::GetDetails, key, details);
|
||||
GraphCanvas::SlotRequestBus::Event(gcSlotId, &GraphCanvas::SlotRequests::SetDetails, details.m_name, details.m_tooltip);
|
||||
|
||||
@@ -11,11 +11,13 @@ AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option")
|
||||
#include <QMetaType>
|
||||
AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <ScriptCanvas/Data/Data.h>
|
||||
#include <ScriptCanvas/Variable/VariableCore.h>
|
||||
|
||||
// VariableId is a UUID typedef for now. So we don't want to double reflect the UUID.
|
||||
Q_DECLARE_METATYPE(AZ::Uuid);
|
||||
Q_DECLARE_METATYPE(AZ::Data::AssetId);
|
||||
Q_DECLARE_METATYPE(ScriptCanvas::Data::Type);
|
||||
Q_DECLARE_METATYPE(ScriptCanvas::VariableId);
|
||||
Q_DECLARE_METATYPE(ScriptCanvasEditor::SourceHandle);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
void ReflectComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
SourceHandle::Reflect(context);
|
||||
ScriptCanvas::ScriptCanvasData::Reflect(context);
|
||||
ScriptCanvasAssetHolder::Reflect(context);
|
||||
EditorSettings::EditorWorkspace::Reflect(context);
|
||||
|
||||
@@ -92,13 +92,11 @@ namespace ScriptCanvasEditor
|
||||
|
||||
// WorkspaceAssetSaveData
|
||||
EditorWorkspace::WorkspaceAssetSaveData::WorkspaceAssetSaveData()
|
||||
: m_assetType(azrtti_typeid<ScriptCanvasAsset>())
|
||||
{
|
||||
}
|
||||
|
||||
EditorWorkspace::WorkspaceAssetSaveData::WorkspaceAssetSaveData(const AZ::Data::AssetId& assetId)
|
||||
EditorWorkspace::WorkspaceAssetSaveData::WorkspaceAssetSaveData(SourceHandle assetId)
|
||||
: m_assetId(assetId)
|
||||
, m_assetType(azrtti_typeid<ScriptCanvasAsset>())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -108,7 +106,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
AZStd::vector<WorkspaceAssetSaveData> assetSaveData;
|
||||
AZStd::vector<AZ::Data::AssetId> assetIds;
|
||||
auto subElement = rootDataElementNode.FindSubElement(AZ_CRC("ActiveAssetIds", 0xe445268a));
|
||||
auto subElement = rootDataElementNode.FindSubElement(AZ_CRC_CE("ActiveAssetIds"));
|
||||
|
||||
if (subElement)
|
||||
{
|
||||
@@ -117,15 +115,21 @@ namespace ScriptCanvasEditor
|
||||
assetSaveData.reserve(assetIds.size());
|
||||
for (const AZ::Data::AssetId& assetId : assetIds)
|
||||
{
|
||||
assetSaveData.emplace_back(assetId);
|
||||
assetSaveData.emplace_back(SourceHandle( nullptr, assetId.m_guid, "" ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootDataElementNode.RemoveElementByName(AZ_CRC("ActiveAssetIds", 0xe445268a));
|
||||
rootDataElementNode.RemoveElementByName(AZ_CRC_CE("ActiveAssetIds"));
|
||||
rootDataElementNode.AddElementWithData(context, "ActiveAssetData", assetSaveData);
|
||||
}
|
||||
|
||||
if (rootDataElementNode.GetVersion() < 4)
|
||||
{
|
||||
rootDataElementNode.RemoveElementByName(AZ_CRC_CE("ActiveAssetIds"));
|
||||
rootDataElementNode.RemoveElementByName(AZ_CRC_CE("FocusedAssetId"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -135,13 +139,12 @@ namespace ScriptCanvasEditor
|
||||
if (serialize)
|
||||
{
|
||||
serialize->Class<WorkspaceAssetSaveData>()
|
||||
->Version(1)
|
||||
->Version(2)
|
||||
->Field("AssetId", &WorkspaceAssetSaveData::m_assetId)
|
||||
->Field("AssetType", &WorkspaceAssetSaveData::m_assetType)
|
||||
;
|
||||
|
||||
serialize->Class<EditorWorkspace>()
|
||||
->Version(3, &EditorWorkspace::VersionConverter)
|
||||
->Version(4, &EditorWorkspace::VersionConverter)
|
||||
->Field("m_storedWindowState", &EditorWorkspace::m_storedWindowState)
|
||||
->Field("m_windowGeometry", &EditorWorkspace::m_windowGeometry)
|
||||
->Field("FocusedAssetId", &EditorWorkspace::m_focusedAssetId)
|
||||
@@ -150,13 +153,13 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void EditorWorkspace::ConfigureActiveAssets(AZ::Data::AssetId focussedAssetId, const AZStd::vector< WorkspaceAssetSaveData >& activeAssetData)
|
||||
void EditorWorkspace::ConfigureActiveAssets(SourceHandle focussedAssetId, const AZStd::vector< WorkspaceAssetSaveData >& activeAssetData)
|
||||
{
|
||||
m_focusedAssetId = focussedAssetId;
|
||||
m_activeAssetData = activeAssetData;
|
||||
}
|
||||
|
||||
AZ::Data::AssetId EditorWorkspace::GetFocusedAssetId() const
|
||||
SourceHandle EditorWorkspace::GetFocusedAssetId() const
|
||||
{
|
||||
return m_focusedAssetId;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/UserSettings/UserSettings.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
|
||||
// qdatastream.h(173): warning C4251: 'QDataStream::d': class 'QScopedPointer<QDataStreamPrivate,QScopedPointerDeleter<T>>' needs to have dll-interface to be used by clients of class 'QDataStream'
|
||||
// qwidget.h(858): warning C4800: 'uint': forcing value to bool 'true' or 'false' (performance warning)
|
||||
@@ -53,11 +54,10 @@ namespace ScriptCanvasEditor
|
||||
AZ_RTTI(WorkspaceAssetSaveData, "{927368CA-096F-4CF1-B2E0-1B9E4A93EA57}");
|
||||
|
||||
WorkspaceAssetSaveData();
|
||||
WorkspaceAssetSaveData(const AZ::Data::AssetId& assetId);
|
||||
WorkspaceAssetSaveData(SourceHandle assetId);
|
||||
virtual ~WorkspaceAssetSaveData() = default;
|
||||
|
||||
AZ::Data::AssetId m_assetId;
|
||||
AZ::Data::AssetType m_assetType;
|
||||
SourceHandle m_assetId;
|
||||
};
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ namespace ScriptCanvasEditor
|
||||
|
||||
EditorWorkspace() = default;
|
||||
|
||||
void ConfigureActiveAssets(AZ::Data::AssetId focusedAssetId, const AZStd::vector< WorkspaceAssetSaveData >& activeAssetIds);
|
||||
void ConfigureActiveAssets(SourceHandle focusedAsset, const AZStd::vector< WorkspaceAssetSaveData >& activeAssetIds);
|
||||
|
||||
AZ::Data::AssetId GetFocusedAssetId() const;
|
||||
SourceHandle GetFocusedAssetId() const;
|
||||
AZStd::vector< WorkspaceAssetSaveData > GetActiveAssetData() const;
|
||||
|
||||
void Init(const QByteArray& windowState, const QByteArray& windowGeometry);
|
||||
@@ -79,7 +79,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void Clear()
|
||||
{
|
||||
m_focusedAssetId.SetInvalid();
|
||||
m_focusedAssetId.Clear();
|
||||
m_activeAssetData.clear();
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ScriptCanvasEditor
|
||||
AZStd::vector<AZ::u8> m_windowGeometry;
|
||||
AZStd::vector<AZ::u8> m_windowState;
|
||||
|
||||
AZ::Data::AssetId m_focusedAssetId;
|
||||
SourceHandle m_focusedAssetId;
|
||||
AZStd::vector< WorkspaceAssetSaveData > m_activeAssetData;
|
||||
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <Editor/SystemComponent.h>
|
||||
#include <Editor/View/Dialogs/NewGraphDialog.h>
|
||||
#include <Editor/View/Dialogs/SettingsDialog.h>
|
||||
#include <Editor/View/Widgets/SourceHandlePropertyAssetCtrl.h>
|
||||
#include <Editor/View/Windows/MainWindow.h>
|
||||
#include <GraphCanvas/GraphCanvasBus.h>
|
||||
#include <LyViewPaneNames.h>
|
||||
@@ -33,6 +34,7 @@
|
||||
#include <ScriptCanvas/Core/Datum.h>
|
||||
#include <ScriptCanvas/Data/DataRegistry.h>
|
||||
#include <ScriptCanvas/Libraries/Libraries.h>
|
||||
#include <ScriptCanvas/PerformanceStatisticsBus.h>
|
||||
#include <ScriptCanvas/Variable/VariableCore.h>
|
||||
#include <ScriptCanvas/View/EditCtrls/GenericLineEditCtrl.h>
|
||||
|
||||
@@ -119,6 +121,10 @@ namespace ScriptCanvasEditor
|
||||
PopulateEditorCreatableTypes();
|
||||
|
||||
AzToolsFramework::RegisterGenericComboBoxHandler<ScriptCanvas::VariableId>();
|
||||
if (AzToolsFramework::PropertyTypeRegistrationMessages::Bus::FindFirstHandler())
|
||||
{
|
||||
AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, aznew SourceHandlePropertyHandler());
|
||||
}
|
||||
|
||||
SystemRequestBus::Handler::BusConnect();
|
||||
ScriptCanvasExecutionBus::Handler::BusConnect();
|
||||
@@ -173,13 +179,11 @@ namespace ScriptCanvasEditor
|
||||
outCreatableTypes.insert(m_creatableTypes.begin(), m_creatableTypes.end());
|
||||
}
|
||||
|
||||
void SystemComponent::CreateEditorComponentsOnEntity(AZ::Entity* entity, const AZ::Data::AssetType& assetType)
|
||||
void SystemComponent::CreateEditorComponentsOnEntity(AZ::Entity* entity, [[maybe_unused]] const AZ::Data::AssetType& assetType)
|
||||
{
|
||||
if (entity)
|
||||
{
|
||||
auto graph = entity->CreateComponent<Graph>();
|
||||
graph->SetAssetType(assetType);
|
||||
|
||||
entity->CreateComponent<EditorGraphVariableManagerComponent>(graph->GetScriptCanvasId());
|
||||
}
|
||||
}
|
||||
@@ -248,23 +252,25 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
entityMenu->setEnabled(true);
|
||||
|
||||
|
||||
usedIds.insert(assetId);
|
||||
|
||||
|
||||
AZStd::string rootPath;
|
||||
AZ::Data::AssetInfo assetInfo = AssetHelpers::GetAssetInfo(assetId, rootPath);
|
||||
|
||||
|
||||
AZStd::string displayName;
|
||||
AZ::StringFunc::Path::GetFileName(assetInfo.m_relativePath.c_str(), displayName);
|
||||
|
||||
|
||||
action = entityMenu->addAction(QString("%1").arg(QString(displayName.c_str())));
|
||||
|
||||
|
||||
QObject::connect(action, &QAction::triggered, [assetId]
|
||||
{
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, assetId, -1);
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset
|
||||
, SourceHandle(nullptr, assetId.m_guid, "")
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -301,7 +307,10 @@ namespace ScriptCanvasEditor
|
||||
return AzToolsFramework::AssetBrowser::SourceFileDetails();
|
||||
}
|
||||
|
||||
void SystemComponent::AddSourceFileOpeners(const char* fullSourceFileName, [[maybe_unused]] const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers)
|
||||
void SystemComponent::AddSourceFileOpeners
|
||||
( [[maybe_unused]] const char* fullSourceFileName
|
||||
, [[maybe_unused]] const AZ::Uuid& sourceUUID
|
||||
, [[maybe_unused]] AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers)
|
||||
{
|
||||
using namespace AzToolsFramework;
|
||||
using namespace AzToolsFramework::AssetBrowser;
|
||||
@@ -322,16 +331,28 @@ namespace ScriptCanvasEditor
|
||||
if (fullDetails)
|
||||
{
|
||||
AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas);
|
||||
|
||||
|
||||
AzToolsFramework::EditorRequests::Bus::Broadcast(&AzToolsFramework::EditorRequests::OpenViewPane, "Script Canvas");
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, sourceUUIDInCall, -1);
|
||||
GeneralRequestBus::BroadcastResult(openOutcome
|
||||
, &GeneralRequests::OpenScriptCanvasAsset
|
||||
, SourceHandle(nullptr, sourceUUIDInCall, ""), Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
}
|
||||
};
|
||||
|
||||
openers.push_back({ "O3DE_ScriptCanvasEditor", "Open In Script Canvas Editor...", QIcon(), scriptCanvasEditorCallback });
|
||||
openers.push_back({ "O3DE_ScriptCanvasEditor", "Open In Script Canvas Editor...", QIcon(ScriptCanvasAssetDescription().GetIconPathImpl()), scriptCanvasEditorCallback });
|
||||
}
|
||||
}
|
||||
|
||||
void SystemComponent::OnStartPlayInEditor()
|
||||
{
|
||||
ScriptCanvas::Execution::PerformanceStatisticsEBus::Broadcast(&ScriptCanvas::Execution::PerformanceStatisticsBus::ClearSnaphotStatistics);
|
||||
}
|
||||
|
||||
void SystemComponent::OnStopPlayInEditor()
|
||||
{
|
||||
AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::GarbageCollect);
|
||||
}
|
||||
|
||||
void SystemComponent::OnUserSettingsActivated()
|
||||
{
|
||||
PopulateEditorCreatableTypes();
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/Model.h>
|
||||
#include <ScriptCanvas/Bus/ScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Bus/ScriptCanvasExecutionBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
@@ -36,6 +37,8 @@ namespace ScriptCanvasEditor
|
||||
, private AZ::Data::AssetBus::MultiHandler
|
||||
, private AzToolsFramework::AssetSeedManagerRequests::Bus::Handler
|
||||
, private AzToolsFramework::EditorContextMenuBus::Handler
|
||||
, private AzToolsFramework::EditorEntityContextNotificationBus::Handler
|
||||
|
||||
{
|
||||
public:
|
||||
AZ_COMPONENT(SystemComponent, "{1DE7A120-4371-4009-82B5-8140CB1D7B31}");
|
||||
@@ -97,7 +100,12 @@ namespace ScriptCanvasEditor
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
protected:
|
||||
void OnStartPlayInEditor() override;
|
||||
|
||||
void OnStopPlayInEditor() override;
|
||||
|
||||
private:
|
||||
SystemComponent(const SystemComponent&) = delete;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Serialization/Utils.h>
|
||||
|
||||
#include <ScriptCanvas/Core/Graph.h>
|
||||
#include <ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <ScriptCanvas/Variable/VariableBus.h>
|
||||
|
||||
#include <GraphCanvas/Components/SceneBus.h>
|
||||
@@ -19,7 +20,6 @@
|
||||
|
||||
#include <Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h>
|
||||
#include <Editor/Assets/ScriptCanvasAssetTrackerBus.h>
|
||||
#include <Editor/Assets/ScriptCanvasMemoryAsset.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
@@ -36,7 +36,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
}
|
||||
|
||||
void GraphItemCommand::Capture(ScriptCanvasMemoryAsset&, bool)
|
||||
void GraphItemCommand::Capture(Graph*, bool)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -105,10 +105,10 @@ namespace ScriptCanvasEditor
|
||||
RestoreItem(m_redoState);
|
||||
}
|
||||
|
||||
void GraphItemChangeCommand::Capture(ScriptCanvasMemoryAsset& memoryAsset, bool captureUndo)
|
||||
void GraphItemChangeCommand::Capture(Graph* graph, bool captureUndo)
|
||||
{
|
||||
m_scriptCanvasId = memoryAsset.GetScriptCanvasId();
|
||||
m_graphCanvasGraphId = memoryAsset.GetGraphId();
|
||||
m_scriptCanvasId = graph->GetScriptCanvasId();
|
||||
m_graphCanvasGraphId = graph->GetGraphCanvasGraphId();
|
||||
|
||||
UndoCache* undoCache = nullptr;
|
||||
UndoRequestBus::EventResult(undoCache, m_scriptCanvasId, &UndoRequests::GetSceneUndoCache);
|
||||
@@ -204,9 +204,9 @@ namespace ScriptCanvasEditor
|
||||
RestoreItem(m_redoState);
|
||||
}
|
||||
|
||||
void GraphItemAddCommand::Capture(ScriptCanvasMemoryAsset& memoryAsset, bool)
|
||||
void GraphItemAddCommand::Capture(Graph* graph, bool)
|
||||
{
|
||||
GraphItemChangeCommand::Capture(memoryAsset, false);
|
||||
GraphItemChangeCommand::Capture(graph, false);
|
||||
}
|
||||
|
||||
//// Graph Item Removal Command
|
||||
@@ -225,8 +225,8 @@ namespace ScriptCanvasEditor
|
||||
RestoreItem(m_redoState);
|
||||
}
|
||||
|
||||
void GraphItemRemovalCommand::Capture(ScriptCanvasMemoryAsset& memoryAsset, bool)
|
||||
void GraphItemRemovalCommand::Capture(Graph* graph, bool)
|
||||
{
|
||||
GraphItemChangeCommand::Capture(memoryAsset, true);
|
||||
GraphItemChangeCommand::Capture(graph, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace ScriptCanvasEditor
|
||||
void Undo() override;
|
||||
void Redo() override;
|
||||
|
||||
virtual void Capture(ScriptCanvasMemoryAsset& memoryAsset, bool captureUndo);
|
||||
virtual void Capture(Graph* graph, bool captureUndo);
|
||||
|
||||
bool Changed() const override;
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void Undo() override;
|
||||
void Redo() override;
|
||||
void Capture(ScriptCanvasMemoryAsset& memoryAsset, bool captureUndo) override;
|
||||
void Capture(Graph* graph, bool captureUndo) override;
|
||||
|
||||
void RestoreItem(const AZStd::vector<AZ::u8>& restoreBuffer) override;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace ScriptCanvasEditor
|
||||
void Undo() override;
|
||||
void Redo() override;
|
||||
|
||||
void Capture(ScriptCanvasMemoryAsset& memoryAsset, bool captureUndo) override;
|
||||
void Capture(Graph* graph, bool captureUndo) override;
|
||||
|
||||
protected:
|
||||
GraphItemAddCommand(const GraphItemAddCommand&) = delete;
|
||||
@@ -124,7 +124,7 @@ namespace ScriptCanvasEditor
|
||||
void Undo() override;
|
||||
void Redo() override;
|
||||
|
||||
void Capture(ScriptCanvasMemoryAsset& memoryAsset, bool captureUndo) override;
|
||||
void Capture(Graph* graph, bool captureUndo) override;
|
||||
|
||||
protected:
|
||||
GraphItemRemovalCommand(const GraphItemRemovalCommand&) = delete;
|
||||
|
||||
@@ -28,9 +28,9 @@ namespace ScriptCanvasEditor
|
||||
// SceneUndoState
|
||||
|
||||
SceneUndoState::SceneUndoState(AzToolsFramework::UndoSystem::IUndoNotify* undoNotify)
|
||||
: m_undoStack(AZStd::make_unique<AzToolsFramework::UndoSystem::UndoStack>(c_undoLimit, undoNotify))
|
||||
, m_undoCache(AZStd::make_unique<UndoCache>())
|
||||
{
|
||||
m_undoStack = AZStd::make_unique<AzToolsFramework::UndoSystem::UndoStack>(c_undoLimit, undoNotify);
|
||||
m_undoCache = AZStd::make_unique<UndoCache>();
|
||||
}
|
||||
|
||||
void SceneUndoState::BeginUndoBatch(AZStd::string_view label)
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace ScriptCanvasEditor
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(SceneUndoState, AZ::SystemAllocator, 0);
|
||||
|
||||
SceneUndoState() = default;
|
||||
SceneUndoState(AzToolsFramework::UndoSystem::IUndoNotify* undoNotify);
|
||||
~SceneUndoState();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
AZ::Data::AssetId ReadRecentAssetId()
|
||||
SourceHandle ReadRecentAssetId()
|
||||
{
|
||||
QSettings settings(QSettings::IniFormat, QSettings::UserScope,
|
||||
SCRIPTCANVASEDITOR_AZ_QCOREAPPLICATION_SETTINGS_ORGANIZATION_NAME);
|
||||
@@ -26,20 +26,15 @@ namespace ScriptCanvasEditor
|
||||
recentOpenFileLocation = settings.value(SCRIPTCANVASEDITOR_SETTINGS_RECENT_OPEN_FILE_LOCATION_KEY).toString();
|
||||
settings.endGroup();
|
||||
|
||||
if (recentOpenFileLocation.isEmpty())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
AZ::Data::AssetId assetId(recentOpenFileLocation.toUtf8().constData());
|
||||
return assetId;
|
||||
return { nullptr, {}, recentOpenFileLocation.toUtf8().constData() };
|
||||
}
|
||||
|
||||
void SetRecentAssetId(const AZ::Data::AssetId& assetId)
|
||||
void SetRecentAssetId(SourceHandle assetId)
|
||||
{
|
||||
QSettings settings(QSettings::IniFormat, QSettings::UserScope,
|
||||
SCRIPTCANVASEDITOR_AZ_QCOREAPPLICATION_SETTINGS_ORGANIZATION_NAME);
|
||||
|
||||
AZStd::string guidStr = assetId.m_guid.ToString<AZStd::string>();
|
||||
AZStd::string guidStr = assetId.Id().ToString<AZStd::string>();
|
||||
|
||||
settings.beginGroup(SCRIPTCANVASEDITOR_NAME_SHORT);
|
||||
settings.setValue(SCRIPTCANVASEDITOR_SETTINGS_RECENT_OPEN_FILE_LOCATION_KEY,
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
AZ::Data::AssetId ReadRecentAssetId();
|
||||
void SetRecentAssetId(const AZ::Data::AssetId& assetId);
|
||||
SourceHandle ReadRecentAssetId();
|
||||
void SetRecentAssetId(SourceHandle assetId);
|
||||
void ClearRecentAssetId();
|
||||
}
|
||||
|
||||
@@ -11,14 +11,16 @@
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <Core/Core.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
// #sc-editor-asset remove this
|
||||
class AssetGraphScene : public AZ::EBusTraits
|
||||
{
|
||||
public:
|
||||
virtual AZ::EntityId FindEditorNodeIdByAssetNodeId(const AZ::Data::AssetId& assetId, AZ::EntityId assetNodeId) const = 0;
|
||||
virtual AZ::EntityId FindAssetNodeIdByEditorNodeId(const AZ::Data::AssetId& assetId, AZ::EntityId editorNodeId) const = 0;
|
||||
virtual AZ::EntityId FindEditorNodeIdByAssetNodeId(const SourceHandle& assetId, AZ::EntityId assetNodeId) const = 0;
|
||||
virtual AZ::EntityId FindAssetNodeIdByEditorNodeId(const SourceHandle& assetId, AZ::EntityId editorNodeId) const = 0;
|
||||
};
|
||||
|
||||
using AssetGraphSceneBus = AZ::EBus<AssetGraphScene>;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
namespace Widget
|
||||
{
|
||||
CanvasWidget::CanvasWidget(const AZ::Data::AssetId& assetId, QWidget* parent)
|
||||
CanvasWidget::CanvasWidget(const ScriptCanvasEditor::SourceHandle& assetId, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::CanvasWidget())
|
||||
, m_attached(false)
|
||||
@@ -69,25 +69,15 @@ namespace ScriptCanvasEditor
|
||||
void CanvasWidget::ShowScene(const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
|
||||
{
|
||||
EditorGraphRequests* editorGraphRequests = EditorGraphRequestBus::FindFirstHandler(scriptCanvasId);
|
||||
|
||||
editorGraphRequests->SetAssetId(m_assetId);
|
||||
editorGraphRequests->CreateGraphCanvasScene();
|
||||
|
||||
AZ::EntityId graphCanvasSceneId = editorGraphRequests->GetGraphCanvasGraphId();
|
||||
|
||||
m_graphicsView->SetScene(graphCanvasSceneId);
|
||||
|
||||
m_scriptCanvasId = scriptCanvasId;
|
||||
}
|
||||
|
||||
void CanvasWidget::SetAssetId(const AZ::Data::AssetId& assetId)
|
||||
void CanvasWidget::SetAssetId(const ScriptCanvasEditor::SourceHandle& assetId)
|
||||
{
|
||||
m_assetId = assetId;
|
||||
|
||||
if (EditorGraphRequests* editorGraphRequests = EditorGraphRequestBus::FindFirstHandler(m_scriptCanvasId))
|
||||
{
|
||||
editorGraphRequests->SetAssetId(m_assetId);
|
||||
}
|
||||
}
|
||||
|
||||
const GraphCanvas::ViewId& CanvasWidget::GetViewId() const
|
||||
|
||||
@@ -21,6 +21,7 @@ AZ_POP_DISABLE_WARNING
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
|
||||
#include <GraphCanvas/Components/ViewBus.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#endif
|
||||
|
||||
class QVBoxLayout;
|
||||
@@ -46,13 +47,13 @@ namespace ScriptCanvasEditor
|
||||
Q_OBJECT
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(CanvasWidget, AZ::SystemAllocator, 0);
|
||||
CanvasWidget(const AZ::Data::AssetId& assetId, QWidget* parent = nullptr);
|
||||
CanvasWidget(const ScriptCanvasEditor::SourceHandle& assetId, QWidget* parent = nullptr);
|
||||
~CanvasWidget() override;
|
||||
|
||||
void SetDefaultBorderColor(AZ::Color defaultBorderColor);
|
||||
void ShowScene(const ScriptCanvas::ScriptCanvasId& scriptCanvasId);
|
||||
|
||||
void SetAssetId(const AZ::Data::AssetId& assetId);
|
||||
void SetAssetId(const ScriptCanvasEditor::SourceHandle& assetId);
|
||||
|
||||
const GraphCanvas::ViewId& GetViewId() const;
|
||||
|
||||
@@ -69,7 +70,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void SetupGraphicsView();
|
||||
|
||||
AZ::Data::AssetId m_assetId;
|
||||
ScriptCanvasEditor::SourceHandle m_assetId;
|
||||
|
||||
AZStd::unique_ptr<Ui::CanvasWidget> ui;
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <ScriptCanvas/Asset/AssetDescription.h>
|
||||
|
||||
#include <Editor/Include/ScriptCanvas/Components/EditorGraph.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
namespace Widget
|
||||
@@ -31,7 +33,7 @@ namespace ScriptCanvasEditor
|
||||
// GraphTabBar
|
||||
////////////////
|
||||
|
||||
GraphTabBar::GraphTabBar(QWidget* parent /*= nullptr*/)
|
||||
GraphTabBar::GraphTabBar(QWidget* parent)
|
||||
: AzQtComponents::TabBar(parent)
|
||||
{
|
||||
setTabsClosable(true);
|
||||
@@ -44,49 +46,128 @@ namespace ScriptCanvasEditor
|
||||
connect(this, &QTabBar::customContextMenuRequested, this, &GraphTabBar::OnContextMenu);
|
||||
}
|
||||
|
||||
void GraphTabBar::AddGraphTab(const AZ::Data::AssetId& assetId)
|
||||
void GraphTabBar::AddGraphTab(ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState)
|
||||
{
|
||||
InsertGraphTab(count(), assetId);
|
||||
InsertGraphTab(count(), assetId, fileState);
|
||||
}
|
||||
|
||||
int GraphTabBar::InsertGraphTab(int tabIndex, const AZ::Data::AssetId& assetId)
|
||||
void GraphTabBar::ClearTabView(int tabIndex)
|
||||
{
|
||||
if (tabIndex < count())
|
||||
{
|
||||
if (QVariant tabDataVariant = tabData(tabIndex); tabDataVariant.isValid())
|
||||
{
|
||||
GraphTabMetadata replacement = tabDataVariant.value<GraphTabMetadata>();
|
||||
if (replacement.m_canvasWidget)
|
||||
{
|
||||
delete replacement.m_canvasWidget;
|
||||
replacement.m_canvasWidget = nullptr;
|
||||
tabDataVariant.setValue(replacement);
|
||||
setTabData(tabIndex, tabDataVariant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CanvasWidget* GraphTabBar::ModOrCreateTabView(int tabIndex)
|
||||
{
|
||||
if (tabIndex < count())
|
||||
{
|
||||
if (QVariant tabDataVariant = tabData(tabIndex); tabDataVariant.isValid())
|
||||
{
|
||||
if (!tabDataVariant.value<GraphTabMetadata>().m_canvasWidget)
|
||||
{
|
||||
CanvasWidget* canvasWidget = new CanvasWidget(tabDataVariant.value<GraphTabMetadata>().m_assetId, this);
|
||||
canvasWidget->SetDefaultBorderColor(ScriptCanvasAssetDescription().GetDisplayColorImpl());
|
||||
GraphTabMetadata replacement = tabDataVariant.value<GraphTabMetadata>();
|
||||
replacement.m_canvasWidget = canvasWidget;
|
||||
tabDataVariant.setValue(replacement);
|
||||
setTabData(tabIndex, tabDataVariant);
|
||||
}
|
||||
|
||||
return tabDataVariant.value<GraphTabMetadata>().m_canvasWidget;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CanvasWidget* GraphTabBar::ModTabView(int tabIndex)
|
||||
{
|
||||
if (tabIndex < count())
|
||||
{
|
||||
if (QVariant tabDataVariant = tabData(tabIndex); tabDataVariant.isValid())
|
||||
{
|
||||
return tabDataVariant.value<GraphTabMetadata>().m_canvasWidget;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AZStd::optional<GraphTabMetadata> GraphTabBar::GetTabData(int tabIndex) const
|
||||
{
|
||||
if (tabIndex < count())
|
||||
{
|
||||
if (QVariant tabDataVariant = tabData(tabIndex); tabDataVariant.isValid())
|
||||
{
|
||||
return tabDataVariant.value<GraphTabMetadata>();
|
||||
}
|
||||
}
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
AZStd::optional<GraphTabMetadata> GraphTabBar::GetTabData(ScriptCanvasEditor::SourceHandle assetId) const
|
||||
{
|
||||
return GetTabData(FindTab(assetId));
|
||||
}
|
||||
|
||||
void GraphTabBar::SetTabData(const GraphTabMetadata& metadata, int tabIndex)
|
||||
{
|
||||
if (tabIndex < count())
|
||||
{
|
||||
setTabData(tabIndex, QVariant::fromValue(metadata));
|
||||
}
|
||||
}
|
||||
|
||||
void GraphTabBar::SetTabData(const GraphTabMetadata& metadata, ScriptCanvasEditor::SourceHandle assetId)
|
||||
{
|
||||
auto index = FindTab(assetId);
|
||||
auto replacement = GetTabData(assetId);
|
||||
|
||||
if (index >= 0 && replacement)
|
||||
{
|
||||
replacement->m_assetId = assetId;
|
||||
SetTabData(metadata, index);
|
||||
}
|
||||
}
|
||||
|
||||
int GraphTabBar::InsertGraphTab(int tabIndex, ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState)
|
||||
{
|
||||
if (!SelectTab(assetId))
|
||||
{
|
||||
AZStd::shared_ptr<ScriptCanvasMemoryAsset> memoryAsset;
|
||||
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetId);
|
||||
QIcon tabIcon = QIcon(ScriptCanvasAssetDescription().GetIconPathImpl());
|
||||
tabIndex = qobject_cast<AzQtComponents::TabWidget*>(parent())->insertTab(tabIndex, new QWidget(), tabIcon, "");
|
||||
GraphTabMetadata metaData;
|
||||
CanvasWidget* canvasWidget = new CanvasWidget(assetId, this);
|
||||
canvasWidget->SetDefaultBorderColor(ScriptCanvasAssetDescription().GetDisplayColorImpl());
|
||||
metaData.m_canvasWidget = canvasWidget;
|
||||
metaData.m_assetId = assetId;
|
||||
metaData.m_fileState = fileState;
|
||||
|
||||
AZStd::string tabName;
|
||||
AzFramework::StringFunc::Path::GetFileName(assetId.Path().c_str(), tabName);
|
||||
|
||||
if (memoryAsset)
|
||||
{
|
||||
ScriptCanvas::AssetDescription assetDescription = memoryAsset->GetAsset().Get()->GetAssetDescription();
|
||||
|
||||
QIcon tabIcon = QIcon(assetDescription.GetIconPathImpl());
|
||||
int newTabIndex = qobject_cast<AzQtComponents::TabWidget*>(parent())->insertTab(tabIndex, new QWidget(), tabIcon, "");
|
||||
|
||||
CanvasWidget* canvasWidget = memoryAsset->CreateView(this);
|
||||
|
||||
canvasWidget->SetDefaultBorderColor(assetDescription.GetDisplayColorImpl());
|
||||
|
||||
AZStd::string tabName;
|
||||
AzFramework::StringFunc::Path::GetFileName(memoryAsset->GetAbsolutePath().c_str(), tabName);
|
||||
|
||||
ConfigureTab(newTabIndex, assetId, tabName);
|
||||
|
||||
// new graphs will need to use their in-memory assetid which we'll need to update
|
||||
// upon saving the asset
|
||||
if (!memoryAsset->GetFileAssetId().IsValid())
|
||||
{
|
||||
setTabData(newTabIndex, QVariant::fromValue(memoryAsset->GetId()));
|
||||
}
|
||||
|
||||
return newTabIndex;
|
||||
}
|
||||
SetTabText(tabIndex, tabName.c_str(), fileState);
|
||||
setTabData(tabIndex, QVariant::fromValue(metaData));
|
||||
return tabIndex;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool GraphTabBar::SelectTab(const AZ::Data::AssetId& assetId)
|
||||
bool GraphTabBar::SelectTab(ScriptCanvasEditor::SourceHandle assetId)
|
||||
{
|
||||
int tabIndex = FindTab(assetId);
|
||||
if (-1 != tabIndex)
|
||||
@@ -94,74 +175,119 @@ namespace ScriptCanvasEditor
|
||||
setCurrentIndex(tabIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GraphTabBar::ConfigureTab(int tabIndex, AZ::Data::AssetId fileAssetId, const AZStd::string& tabName)
|
||||
{
|
||||
if (fileAssetId.IsValid())
|
||||
{
|
||||
QVariant tabDataVariant = tabData(tabIndex);
|
||||
|
||||
if (tabDataVariant.isValid())
|
||||
{
|
||||
auto tabAssetId = tabDataVariant.value<AZ::Data::AssetId>();
|
||||
MemoryAssetNotificationBus::MultiHandler::BusDisconnect(tabAssetId);
|
||||
}
|
||||
|
||||
setTabData(tabIndex, QVariant::fromValue(fileAssetId));
|
||||
|
||||
MemoryAssetNotificationBus::MultiHandler::BusConnect(fileAssetId);
|
||||
}
|
||||
|
||||
Tracker::ScriptCanvasFileState fileState = Tracker::ScriptCanvasFileState::INVALID;
|
||||
AssetTrackerRequestBus::BroadcastResult(fileState, &AssetTrackerRequests::GetFileState, fileAssetId);
|
||||
|
||||
SetTabText(tabIndex, tabName.c_str(), fileState);
|
||||
}
|
||||
|
||||
int GraphTabBar::FindTab(const AZ::Data::AssetId& assetId) const
|
||||
int GraphTabBar::FindTab(ScriptCanvasEditor::SourceHandle assetId) const
|
||||
{
|
||||
for (int tabIndex = 0; tabIndex < count(); ++tabIndex)
|
||||
{
|
||||
QVariant tabDataVariant = tabData(tabIndex);
|
||||
if (tabDataVariant.isValid())
|
||||
{
|
||||
auto tabAssetId = tabDataVariant.value<AZ::Data::AssetId>();
|
||||
if (tabAssetId == assetId)
|
||||
auto tabAssetId = tabDataVariant.value<GraphTabMetadata>();
|
||||
if (tabAssetId.m_assetId.AnyEquals(assetId))
|
||||
{
|
||||
return tabIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
AZ::Data::AssetId GraphTabBar::FindAssetId(int tabIndex)
|
||||
int GraphTabBar::FindTab(ScriptCanvasEditor::GraphPtrConst graph) const
|
||||
{
|
||||
for (int tabIndex = 0; tabIndex < count(); ++tabIndex)
|
||||
{
|
||||
QVariant tabDataVariant = tabData(tabIndex);
|
||||
if (tabDataVariant.isValid())
|
||||
{
|
||||
auto tabAssetId = tabDataVariant.value<GraphTabMetadata>();
|
||||
if (tabAssetId.m_assetId.Get() == graph)
|
||||
{
|
||||
return tabIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GraphTabBar::FindSaveOverMatch(ScriptCanvasEditor::SourceHandle assetId) const
|
||||
{
|
||||
for (int tabIndex = 0; tabIndex < count(); ++tabIndex)
|
||||
{
|
||||
QVariant tabDataVariant = tabData(tabIndex);
|
||||
if (tabDataVariant.isValid())
|
||||
{
|
||||
auto tabAssetId = tabDataVariant.value<GraphTabMetadata>();
|
||||
if (tabAssetId.m_assetId.Get() != assetId.Get() && tabAssetId.m_assetId.PathEquals(assetId))
|
||||
{
|
||||
return tabIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ScriptCanvasEditor::SourceHandle GraphTabBar::FindTabByPath(AZStd::string_view path) const
|
||||
{
|
||||
ScriptCanvasEditor::SourceHandle candidate(nullptr, {}, path);
|
||||
|
||||
for (int index = 0; index < count(); ++index)
|
||||
{
|
||||
QVariant tabdata = tabData(index);
|
||||
if (tabdata.isValid())
|
||||
{
|
||||
auto tabAssetId = tabdata.value<GraphTabMetadata>();
|
||||
if (tabAssetId.m_assetId.AnyEquals(candidate))
|
||||
{
|
||||
return tabAssetId.m_assetId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ScriptCanvasEditor::SourceHandle GraphTabBar::FindAssetId(int tabIndex)
|
||||
{
|
||||
QVariant dataVariant = tabData(tabIndex);
|
||||
if (dataVariant.isValid())
|
||||
{
|
||||
auto tabAssetId = dataVariant.value<AZ::Data::AssetId>();
|
||||
return tabAssetId;
|
||||
auto tabAssetId = dataVariant.value<GraphTabMetadata>();
|
||||
return tabAssetId.m_assetId;
|
||||
}
|
||||
|
||||
return AZ::Data::AssetId();
|
||||
return ScriptCanvasEditor::SourceHandle();
|
||||
}
|
||||
|
||||
ScriptCanvas::ScriptCanvasId GraphTabBar::FindScriptCanvasIdFromGraphCanvasId(const GraphCanvas::GraphId& graphCanvasGraphId) const
|
||||
{
|
||||
for (int index = 0; index < count(); ++index)
|
||||
{
|
||||
QVariant tabdata = tabData(index);
|
||||
if (tabdata.isValid())
|
||||
{
|
||||
auto tabAssetId = tabdata.value<GraphTabMetadata>();
|
||||
if (tabAssetId.m_assetId.IsGraphValid()
|
||||
&& tabAssetId.m_assetId.Get()->GetGraphCanvasGraphId() == graphCanvasGraphId)
|
||||
{
|
||||
return tabAssetId.m_assetId.Get()->GetScriptCanvasId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ScriptCanvas::ScriptCanvasId{};
|
||||
}
|
||||
|
||||
void GraphTabBar::CloseTab(int index)
|
||||
{
|
||||
if (index >= 0 && index < count())
|
||||
{
|
||||
QVariant tabdata = tabData(index);
|
||||
if (tabdata.isValid())
|
||||
{
|
||||
auto tabAssetId = tabdata.value<AZ::Data::AssetId>();
|
||||
|
||||
MemoryAssetNotificationBus::MultiHandler::BusDisconnect(tabAssetId);
|
||||
AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::ClearView, tabAssetId);
|
||||
}
|
||||
|
||||
qobject_cast<AzQtComponents::TabWidget*>(parent())->removeTab(index);
|
||||
}
|
||||
}
|
||||
@@ -172,8 +298,6 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
Q_EMIT TabCloseNoButton(i);
|
||||
}
|
||||
|
||||
MemoryAssetNotificationBus::MultiHandler::BusDisconnect();
|
||||
}
|
||||
|
||||
void GraphTabBar::OnContextMenu(const QPoint& point)
|
||||
@@ -187,11 +311,9 @@ namespace ScriptCanvasEditor
|
||||
QVariant tabdata = tabData(tabIndex);
|
||||
if (tabdata.isValid())
|
||||
{
|
||||
auto tabAssetId = tabdata.value<AZ::Data::AssetId>();
|
||||
|
||||
Tracker::ScriptCanvasFileState fileState;
|
||||
AssetTrackerRequestBus::BroadcastResult(fileState , &AssetTrackerRequests::GetFileState, tabAssetId);
|
||||
auto tabAssetId = tabdata.value<GraphTabMetadata>();
|
||||
|
||||
Tracker::ScriptCanvasFileState fileState = Tracker::ScriptCanvasFileState::INVALID;
|
||||
isModified = fileState == Tracker::ScriptCanvasFileState::NEW || fileState == Tracker::ScriptCanvasFileState::MODIFIED;
|
||||
}
|
||||
|
||||
@@ -263,23 +385,14 @@ namespace ScriptCanvasEditor
|
||||
AzQtComponents::TabBar::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void GraphTabBar::OnFileStateChanged(Tracker::ScriptCanvasFileState fileState)
|
||||
{
|
||||
const AZ::Data::AssetId* fileAssetId = MemoryAssetNotificationBus::GetCurrentBusId();
|
||||
|
||||
if (fileAssetId)
|
||||
{
|
||||
SetFileState((*fileAssetId), fileState);
|
||||
|
||||
if (FindTab((*fileAssetId)) == currentIndex())
|
||||
{
|
||||
Q_EMIT OnActiveFileStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphTabBar::SetTabText(int tabIndex, const QString& path, Tracker::ScriptCanvasFileState fileState)
|
||||
{
|
||||
QString safePath = path;
|
||||
if (path.endsWith("^") || path.endsWith("*"))
|
||||
{
|
||||
safePath.chop(1);
|
||||
}
|
||||
|
||||
if (tabIndex >= 0 && tabIndex < count())
|
||||
{
|
||||
const char* fileStateTag = "";
|
||||
@@ -296,7 +409,7 @@ namespace ScriptCanvasEditor
|
||||
break;
|
||||
}
|
||||
|
||||
setTabText(tabIndex, QString("%1%2").arg(path).arg(fileStateTag));
|
||||
setTabText(tabIndex, QString("%1%2").arg(safePath).arg(fileStateTag));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +427,23 @@ namespace ScriptCanvasEditor
|
||||
Q_EMIT TabRemoved(index);
|
||||
}
|
||||
|
||||
void GraphTabBar::UpdateFileState(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState)
|
||||
{
|
||||
auto tabData = GetTabData(assetId);
|
||||
if (tabData && tabData->m_fileState != fileState)
|
||||
{
|
||||
int index = FindTab(assetId);
|
||||
tabData->m_fileState = fileState;
|
||||
SetTabData(*tabData, assetId);
|
||||
SetTabText(index, tabText(index), fileState);
|
||||
|
||||
if (index == currentIndex())
|
||||
{
|
||||
Q_EMIT OnActiveFileStateChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphTabBar::currentChangedTab(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
@@ -327,7 +457,7 @@ namespace ScriptCanvasEditor
|
||||
return;
|
||||
}
|
||||
|
||||
auto assetId = tabdata.value<AZ::Data::AssetId>();
|
||||
auto assetId = tabdata.value<GraphTabMetadata>().m_assetId;
|
||||
|
||||
ScriptCanvasEditor::GeneralRequestBus::Broadcast(&ScriptCanvasEditor::GeneralRequests::OnChangeActiveGraphTab, assetId);
|
||||
|
||||
@@ -338,24 +468,6 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void GraphTabBar::SetFileState(AZ::Data::AssetId assetId, Tracker::ScriptCanvasFileState fileState)
|
||||
{
|
||||
int index = FindTab(assetId);
|
||||
|
||||
if (index >= 0 && index < count())
|
||||
{
|
||||
QVariant tabdata = tabData(index);
|
||||
if (tabdata.isValid())
|
||||
{
|
||||
auto tabAssetId = tabdata.value<AZ::Data::AssetId>();
|
||||
|
||||
AZStd::string tabName;
|
||||
AssetTrackerRequestBus::BroadcastResult(tabName, &AssetTrackerRequests::GetTabName, tabAssetId);
|
||||
SetTabText(index, tabName.c_str(), fileState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <Editor/View/Widgets/moc_GraphTabBar.cpp>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
#include <Editor/Assets/ScriptCanvasAssetTracker.h>
|
||||
#include <ScriptCanvas/Bus/RequestBus.h>
|
||||
|
||||
#endif
|
||||
|
||||
class QGraphicsView;
|
||||
@@ -26,17 +29,18 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
namespace Widget
|
||||
{
|
||||
class CanvasWidget;
|
||||
|
||||
struct GraphTabMetadata
|
||||
{
|
||||
AZ::Data::AssetId m_assetId;
|
||||
SourceHandle m_assetId;
|
||||
QWidget* m_hostWidget = nullptr;
|
||||
QString m_tabName;
|
||||
CanvasWidget* m_canvasWidget = nullptr;
|
||||
Tracker::ScriptCanvasFileState m_fileState = Tracker::ScriptCanvasFileState::INVALID;
|
||||
};
|
||||
|
||||
class GraphTabBar
|
||||
: public AzQtComponents::TabBar
|
||||
, public MemoryAssetNotificationBus::MultiHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -45,30 +49,39 @@ namespace ScriptCanvasEditor
|
||||
GraphTabBar(QWidget* parent = nullptr);
|
||||
~GraphTabBar() override = default;
|
||||
|
||||
void AddGraphTab(const AZ::Data::AssetId& assetId);
|
||||
int InsertGraphTab(int tabIndex, const AZ::Data::AssetId& assetId);
|
||||
bool SelectTab(const AZ::Data::AssetId& assetId);
|
||||
|
||||
void ConfigureTab(int tabIndex, AZ::Data::AssetId fileAssetId, const AZStd::string& tabName);
|
||||
|
||||
int FindTab(const AZ::Data::AssetId& assetId) const;
|
||||
AZ::Data::AssetId FindAssetId(int tabIndex);
|
||||
AZStd::optional<GraphTabMetadata> GetTabData(int index) const;
|
||||
AZStd::optional<GraphTabMetadata> GetTabData(ScriptCanvasEditor::SourceHandle assetId) const;
|
||||
void SetTabData(const GraphTabMetadata& data, int index);
|
||||
void SetTabData(const GraphTabMetadata& data, ScriptCanvasEditor::SourceHandle assetId);
|
||||
|
||||
void AddGraphTab(ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState);
|
||||
void CloseTab(int index);
|
||||
void CloseAllTabs();
|
||||
|
||||
int InsertGraphTab(int tabIndex, ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState);
|
||||
bool SelectTab(ScriptCanvasEditor::SourceHandle assetId);
|
||||
|
||||
int FindTab(ScriptCanvasEditor::SourceHandle assetId) const;
|
||||
int FindTab(ScriptCanvasEditor::GraphPtrConst graph) const;
|
||||
int FindSaveOverMatch(ScriptCanvasEditor::SourceHandle assetId) const;
|
||||
ScriptCanvasEditor::SourceHandle FindTabByPath(AZStd::string_view path) const;
|
||||
ScriptCanvasEditor::SourceHandle FindAssetId(int tabIndex);
|
||||
ScriptCanvas::ScriptCanvasId FindScriptCanvasIdFromGraphCanvasId(const GraphCanvas::GraphId& graphCanvasGraphId) const;
|
||||
|
||||
void ClearTabView(int tabIndex);
|
||||
CanvasWidget* ModOrCreateTabView(int tabIndex);
|
||||
CanvasWidget* ModTabView(int tabIndex);
|
||||
|
||||
void OnContextMenu(const QPoint& point);
|
||||
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
|
||||
// MemoryAssetNotifications
|
||||
void OnFileStateChanged(Tracker::ScriptCanvasFileState fileState) override;
|
||||
////
|
||||
|
||||
// Updates the tab at the supplied index with the GraphTabMetadata
|
||||
// The host widget field of the tabMetadata is not used and will not overwrite the tab data
|
||||
void SetTabText(int tabIndex, const QString& path, Tracker::ScriptCanvasFileState fileState = Tracker::ScriptCanvasFileState::INVALID);
|
||||
|
||||
void UpdateFileState(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState);
|
||||
|
||||
Q_SIGNALS:
|
||||
void TabInserted(int index);
|
||||
void TabRemoved(int index);
|
||||
@@ -92,8 +105,6 @@ namespace ScriptCanvasEditor
|
||||
// Called when the selected tab changes
|
||||
void currentChangedTab(int index);
|
||||
|
||||
void SetFileState(AZ::Data::AssetId assetId, Tracker::ScriptCanvasFileState fileState);
|
||||
|
||||
int m_signalSaveOnChangeTo = -1;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -256,7 +256,8 @@ namespace ScriptCanvasEditor
|
||||
|
||||
const AZ::Data::AssetId& assetId = executionItem->GetAssetId();
|
||||
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, assetId);
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId
|
||||
, SourceHandle(nullptr, assetId.m_guid, {}), Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,12 +271,14 @@ namespace ScriptCanvasEditor
|
||||
const AZ::Data::AssetId& assetId = executionItem->GetAssetId();
|
||||
|
||||
bool isAssetOpen = false;
|
||||
GeneralRequestBus::BroadcastResult(isAssetOpen, &GeneralRequests::IsScriptCanvasAssetOpen, assetId);
|
||||
GeneralRequestBus::BroadcastResult(isAssetOpen, &GeneralRequests::IsScriptCanvasAssetOpen, SourceHandle(nullptr, assetId.m_guid, {}));
|
||||
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, assetId);
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId
|
||||
, SourceHandle(nullptr, assetId.m_guid, {}), Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
|
||||
AZ::EntityId graphCanvasGraphId;
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, assetId);
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId
|
||||
, SourceHandle(nullptr, assetId.m_guid, {}));
|
||||
|
||||
if (isAssetOpen)
|
||||
{
|
||||
@@ -348,7 +351,7 @@ namespace ScriptCanvasEditor
|
||||
GeneralRequestBus::BroadcastResult(activeGraphCanvasGraphId, &GeneralRequests::GetActiveGraphCanvasGraphId);
|
||||
|
||||
AZ::EntityId graphCanvasGraphId;
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, m_assetId);
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, m_assetId.m_guid, {}));
|
||||
|
||||
if (activeGraphCanvasGraphId == graphCanvasGraphId)
|
||||
{
|
||||
@@ -366,7 +369,7 @@ namespace ScriptCanvasEditor
|
||||
GraphCanvas::FocusConfig focusConfig;
|
||||
|
||||
AZ::EntityId scriptCanvasNodeId;
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, assetId, assetNodeId);
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, SourceHandle(nullptr, assetId.m_guid, {}), assetNodeId);
|
||||
|
||||
GraphCanvas::NodeId graphCanvasNodeId;
|
||||
SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
|
||||
@@ -403,12 +406,12 @@ namespace ScriptCanvasEditor
|
||||
void LoggingWindowSession::HighlightElement(const AZ::Data::AssetId& assetId, const AZ::EntityId& assetNodeId)
|
||||
{
|
||||
AZ::EntityId graphCanvasGraphId;
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, assetId);
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, assetId.m_guid, {}));
|
||||
|
||||
if (graphCanvasGraphId.IsValid())
|
||||
{
|
||||
AZ::EntityId scriptCanvasNodeId;
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, assetId, assetNodeId);
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, SourceHandle(nullptr, assetId.m_guid, {}), assetNodeId);
|
||||
|
||||
GraphCanvas::NodeId graphCanvasNodeId;
|
||||
SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
|
||||
@@ -447,7 +450,7 @@ namespace ScriptCanvasEditor
|
||||
if (effectIter != m_highlightEffects.end())
|
||||
{
|
||||
AZ::EntityId graphCanvasGraphId;
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, assetId);
|
||||
GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, assetId.m_guid, {}));
|
||||
|
||||
if (graphCanvasGraphId.IsValid())
|
||||
{
|
||||
|
||||
+27
-23
@@ -122,7 +122,11 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
}
|
||||
|
||||
ExecutionLogTreeItem* DebugLogRootItem::CreateExecutionItem(const LoggingDataId& loggingDataId, const ScriptCanvas::NodeTypeIdentifier& nodeType, const ScriptCanvas::GraphInfo& graphInfo, const ScriptCanvas::NamedNodeId& nodeId)
|
||||
ExecutionLogTreeItem* DebugLogRootItem::CreateExecutionItem
|
||||
( [[maybe_unused]] const LoggingDataId& loggingDataId
|
||||
, [[maybe_unused]] const ScriptCanvas::NodeTypeIdentifier& nodeType
|
||||
, [[maybe_unused]] const ScriptCanvas::GraphInfo& graphInfo
|
||||
, [[maybe_unused]] const ScriptCanvas::NamedNodeId& nodeId)
|
||||
{
|
||||
ExecutionLogTreeItem* treeItem = nullptr;
|
||||
|
||||
@@ -133,15 +137,6 @@ namespace ScriptCanvasEditor
|
||||
m_additionTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_updatePolicy == UpdatePolicy::SingleTime)
|
||||
{
|
||||
treeItem = CreateChildNodeWithoutAddSignal<ExecutionLogTreeItem>(loggingDataId, nodeType, graphInfo, nodeId);
|
||||
}
|
||||
else
|
||||
{
|
||||
treeItem = CreateChildNode<ExecutionLogTreeItem>(loggingDataId, nodeType, graphInfo, nodeId);
|
||||
}
|
||||
|
||||
return treeItem;
|
||||
}
|
||||
@@ -185,7 +180,11 @@ namespace ScriptCanvasEditor
|
||||
// ExecutionLogTreeItem
|
||||
/////////////////////////
|
||||
|
||||
ExecutionLogTreeItem::ExecutionLogTreeItem(const LoggingDataId& loggingDataId, const ScriptCanvas::NodeTypeIdentifier& nodeType, const ScriptCanvas::GraphInfo& graphInfo, const ScriptCanvas::NamedNodeId& nodeId)
|
||||
ExecutionLogTreeItem::ExecutionLogTreeItem
|
||||
( const LoggingDataId& loggingDataId
|
||||
, const ScriptCanvas::NodeTypeIdentifier& nodeType
|
||||
, const SourceHandle& graphInfo
|
||||
, const ScriptCanvas::NamedNodeId& nodeId)
|
||||
: m_loggingDataId(loggingDataId)
|
||||
, m_nodeType(nodeType)
|
||||
, m_graphInfo(graphInfo)
|
||||
@@ -196,7 +195,6 @@ namespace ScriptCanvasEditor
|
||||
m_paletteConfiguration.SetColorPalette("MethodNodeTitlePalette");
|
||||
|
||||
AZ::NamedEntityId entityName;
|
||||
LoggingDataRequestBus::EventResult(entityName, m_loggingDataId, &LoggingDataRequests::FindNamedEntityId, m_graphInfo.m_runtimeEntity);
|
||||
|
||||
m_sourceEntityName = entityName.ToString().c_str();
|
||||
m_displayName = nodeId.m_name.c_str();
|
||||
@@ -207,7 +205,7 @@ namespace ScriptCanvasEditor
|
||||
m_inputName = "---";
|
||||
m_outputName = "---";
|
||||
|
||||
GeneralAssetNotificationBus::Handler::BusConnect(GetAssetId());
|
||||
GeneralAssetNotificationBus::Handler::BusConnect(graphInfo);
|
||||
}
|
||||
|
||||
QVariant ExecutionLogTreeItem::Data(const QModelIndex& index, int role) const
|
||||
@@ -502,12 +500,12 @@ namespace ScriptCanvasEditor
|
||||
|
||||
const ScriptCanvas::GraphIdentifier& ExecutionLogTreeItem::GetGraphIdentifier() const
|
||||
{
|
||||
return m_graphInfo.m_graphIdentifier;
|
||||
return m_graphIdentifier;
|
||||
}
|
||||
|
||||
const AZ::Data::AssetId& ExecutionLogTreeItem::GetAssetId() const
|
||||
AZ::Data::AssetId ExecutionLogTreeItem::GetAssetId() const
|
||||
{
|
||||
return m_graphInfo.m_graphIdentifier.m_assetId;
|
||||
return m_graphInfo.Id();
|
||||
}
|
||||
|
||||
AZ::EntityId ExecutionLogTreeItem::GetScriptCanvasAssetNodeId() const
|
||||
@@ -623,12 +621,14 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
if (!m_graphCanvasGraphId.IsValid())
|
||||
{
|
||||
GeneralRequestBus::BroadcastResult(m_graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, GetAssetId());
|
||||
GeneralRequestBus::BroadcastResult(m_graphCanvasGraphId
|
||||
, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, GetAssetId().m_guid, ""));
|
||||
|
||||
if (!EditorGraphNotificationBus::Handler::BusIsConnected())
|
||||
{
|
||||
ScriptCanvas::ScriptCanvasId scriptCanvasId;
|
||||
GeneralRequestBus::BroadcastResult(scriptCanvasId, &GeneralRequests::FindScriptCanvasIdByAssetId, GetAssetId());
|
||||
GeneralRequestBus::BroadcastResult(scriptCanvasId
|
||||
, &GeneralRequests::FindScriptCanvasIdByAssetId, SourceHandle(nullptr, GetAssetId().m_guid, ""));
|
||||
|
||||
EditorGraphNotificationBus::Handler::BusConnect(scriptCanvasId);
|
||||
}
|
||||
@@ -638,7 +638,9 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
if (!m_graphCanvasNodeId.IsValid())
|
||||
{
|
||||
AssetGraphSceneBus::BroadcastResult(m_scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, GetAssetId(), m_scriptCanvasAssetNodeId);
|
||||
AssetGraphSceneBus::BroadcastResult(m_scriptCanvasNodeId
|
||||
, &AssetGraphScene::FindEditorNodeIdByAssetNodeId
|
||||
, SourceHandle(nullptr, GetAssetId().m_guid, ""), m_scriptCanvasAssetNodeId);
|
||||
SceneMemberMappingRequestBus::EventResult(m_graphCanvasNodeId, m_scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
|
||||
}
|
||||
|
||||
@@ -806,7 +808,8 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
if (!m_graphCanvasGraphId.IsValid())
|
||||
{
|
||||
GeneralRequestBus::BroadcastResult(m_graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, m_graphIdentifier.m_assetId);
|
||||
GeneralRequestBus::BroadcastResult(m_graphCanvasGraphId
|
||||
, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, m_graphIdentifier.m_assetId.m_guid, ""));
|
||||
}
|
||||
|
||||
ScrapeInputName();
|
||||
@@ -828,7 +831,7 @@ namespace ScriptCanvasEditor
|
||||
if (m_graphCanvasGraphId.IsValid() && m_assetInputEndpoint.IsValid())
|
||||
{
|
||||
AZ::EntityId scriptCanvasNodeId;
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, GetAssetId(), m_assetInputEndpoint.GetNodeId());
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, SourceHandle(nullptr, GetAssetId().m_guid, ""), m_assetInputEndpoint.GetNodeId());
|
||||
|
||||
GraphCanvas::NodeId graphCanvasNodeId;
|
||||
SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
|
||||
@@ -851,8 +854,9 @@ namespace ScriptCanvasEditor
|
||||
if (m_graphCanvasGraphId.IsValid() && m_assetOutputEndpoint.IsValid())
|
||||
{
|
||||
AZ::EntityId scriptCanvasNodeId;
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId, GetAssetId(), m_assetOutputEndpoint.GetNodeId());
|
||||
|
||||
AssetGraphSceneBus::BroadcastResult(scriptCanvasNodeId, &AssetGraphScene::FindEditorNodeIdByAssetNodeId
|
||||
, SourceHandle(nullptr, GetAssetId().m_guid, ""), m_assetOutputEndpoint.GetNodeId());
|
||||
|
||||
GraphCanvas::NodeId graphCanvasNodeId;
|
||||
SceneMemberMappingRequestBus::EventResult(graphCanvasNodeId, scriptCanvasNodeId, &SceneMemberMappingRequests::GetGraphCanvasEntityId);
|
||||
|
||||
|
||||
@@ -131,7 +131,12 @@ namespace ScriptCanvasEditor
|
||||
AZ_CLASS_ALLOCATOR(ExecutionLogTreeItem, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(ExecutionLogTreeItem, "{71139142-A30C-4A16-81CC-D51314AEAF7D}", DebugLogTreeItem);
|
||||
|
||||
ExecutionLogTreeItem(const LoggingDataId& loggingDataId, const ScriptCanvas::NodeTypeIdentifier& nodeType, const ScriptCanvas::GraphInfo& graphInfo, const ScriptCanvas::NamedNodeId& nodeId);
|
||||
ExecutionLogTreeItem
|
||||
( const LoggingDataId& loggingDataId
|
||||
, const ScriptCanvas::NodeTypeIdentifier& nodeType
|
||||
, const SourceHandle& graphInfo
|
||||
, const ScriptCanvas::NamedNodeId& nodeId);
|
||||
|
||||
~ExecutionLogTreeItem() override = default;
|
||||
|
||||
QVariant Data(const QModelIndex& index, int role) const override final;
|
||||
@@ -163,7 +168,7 @@ namespace ScriptCanvasEditor
|
||||
////
|
||||
|
||||
const ScriptCanvas::GraphIdentifier& GetGraphIdentifier() const;
|
||||
const AZ::Data::AssetId& GetAssetId() const;
|
||||
AZ::Data::AssetId GetAssetId() const;
|
||||
|
||||
AZ::EntityId GetScriptCanvasAssetNodeId() const;
|
||||
GraphCanvas::NodeId GetGraphCanvasNodeId() const;
|
||||
@@ -184,7 +189,8 @@ namespace ScriptCanvasEditor
|
||||
|
||||
LoggingDataId m_loggingDataId;
|
||||
ScriptCanvas::NodeTypeIdentifier m_nodeType;
|
||||
ScriptCanvas::GraphInfo m_graphInfo;
|
||||
SourceHandle m_graphInfo;
|
||||
ScriptCanvas::GraphIdentifier m_graphIdentifier;
|
||||
QString m_sourceEntityName;
|
||||
QString m_graphName;
|
||||
QString m_relativeGraphPath;
|
||||
|
||||
+6
-7
@@ -406,15 +406,14 @@ namespace ScriptCanvasEditor
|
||||
sourceIndex = proxyModel->mapToSource(modelIndex);
|
||||
}
|
||||
|
||||
PivotTreeItem* pivotTreeItem = static_cast<PivotTreeItem*>(sourceIndex.internalPointer());
|
||||
|
||||
if (pivotTreeItem)
|
||||
if (PivotTreeItem* pivotTreeItem = static_cast<PivotTreeItem*>(sourceIndex.internalPointer()))
|
||||
{
|
||||
PivotTreeGraphItem* graphItem = azrtti_cast<PivotTreeGraphItem*>(pivotTreeItem);
|
||||
|
||||
if (graphItem)
|
||||
if (PivotTreeGraphItem* graphItem = azrtti_cast<PivotTreeGraphItem*>(pivotTreeItem))
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, graphItem->GetAssetId());
|
||||
GeneralRequestBus::Broadcast
|
||||
( &GeneralRequests::OpenScriptCanvasAssetId
|
||||
, SourceHandle(nullptr, graphItem->GetAssetId().m_guid, "")
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -129,7 +129,10 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
if (row == NodePaletteTreeItem::Column::Customization)
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, GetSourceAssetId(), -1);
|
||||
GeneralRequestBus::Broadcast
|
||||
( &GeneralRequests::OpenScriptCanvasAssetId
|
||||
, SourceHandle(nullptr, GetSourceAssetId().m_guid, "")
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +140,10 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
if (row != NodePaletteTreeItem::Column::Customization)
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAsset, GetSourceAssetId(), -1);
|
||||
GeneralRequestBus::Broadcast
|
||||
( &GeneralRequests::OpenScriptCanvasAssetId
|
||||
, SourceHandle(nullptr, GetSourceAssetId().m_guid, "")
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ScriptCanvas/Components/EditorUtils.h>
|
||||
#include <Editor/View/Widgets/SourceHandlePropertyAssetCtrl.h>
|
||||
|
||||
#include <AzFramework/StringFunc/StringFunc.h>
|
||||
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/Model/AssetCompleterModel.h>
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
SourceHandlePropertyAssetCtrl::SourceHandlePropertyAssetCtrl(QWidget* parent)
|
||||
: AzToolsFramework::PropertyAssetCtrl(parent)
|
||||
{
|
||||
}
|
||||
|
||||
AzToolsFramework::AssetBrowser::AssetSelectionModel SourceHandlePropertyAssetCtrl::GetAssetSelectionModel()
|
||||
{
|
||||
auto selectionModel = AssetSelectionModel::SourceAssetTypeSelection(m_sourceAssetFilterPattern);
|
||||
selectionModel.SetTitle(m_title);
|
||||
return selectionModel;
|
||||
}
|
||||
|
||||
void SourceHandlePropertyAssetCtrl::PopupAssetPicker()
|
||||
{
|
||||
// Request the AssetBrowser Dialog and set a type filter
|
||||
AssetSelectionModel selection = GetAssetSelectionModel();
|
||||
selection.SetSelectedFilePath(m_selectedSourcePath.c_str());
|
||||
|
||||
AZStd::string defaultDirectory;
|
||||
if (m_defaultDirectoryCallback)
|
||||
{
|
||||
m_defaultDirectoryCallback->Invoke(m_editNotifyTarget, defaultDirectory);
|
||||
selection.SetDefaultDirectory(defaultDirectory);
|
||||
}
|
||||
|
||||
AssetBrowserComponentRequestBus::Broadcast(&AssetBrowserComponentRequests::PickAssets, selection, parentWidget());
|
||||
if (selection.IsValid())
|
||||
{
|
||||
const auto source = azrtti_cast<const SourceAssetBrowserEntry*>(selection.GetResult());
|
||||
AZ_Assert(source, "Incorrect entry type selected. Expected source.");
|
||||
if (source)
|
||||
{
|
||||
SetSelectedSourcePath(source->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SourceHandlePropertyAssetCtrl::ClearAssetInternal()
|
||||
{
|
||||
SetSelectedSourcePath("");
|
||||
|
||||
PropertyAssetCtrl::ClearAssetInternal();
|
||||
}
|
||||
|
||||
void SourceHandlePropertyAssetCtrl::ConfigureAutocompleter()
|
||||
{
|
||||
if (m_completerIsConfigured)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AzToolsFramework::PropertyAssetCtrl::ConfigureAutocompleter();
|
||||
|
||||
AssetSelectionModel selection = GetAssetSelectionModel();
|
||||
m_model->SetFetchEntryType(AssetBrowserEntry::AssetEntryType::Source);
|
||||
m_model->SetFilter(selection.GetDisplayFilter());
|
||||
}
|
||||
|
||||
void SourceHandlePropertyAssetCtrl::SetSourceAssetFilterPattern(const QString& filterPattern)
|
||||
{
|
||||
m_sourceAssetFilterPattern = filterPattern;
|
||||
}
|
||||
|
||||
AZ::IO::Path SourceHandlePropertyAssetCtrl::GetSelectedSourcePath() const
|
||||
{
|
||||
return m_selectedSourcePath;
|
||||
}
|
||||
|
||||
void SourceHandlePropertyAssetCtrl::SetSelectedSourcePath(const AZ::IO::Path& sourcePath)
|
||||
{
|
||||
m_selectedSourcePath = sourcePath;
|
||||
|
||||
AZStd::string displayText;
|
||||
if (!sourcePath.empty())
|
||||
{
|
||||
AzFramework::StringFunc::Path::GetFileName(sourcePath.c_str(), displayText);
|
||||
}
|
||||
m_browseEdit->setText(displayText.c_str());
|
||||
|
||||
// The AssetID gets ignored, the only important bit is triggering the change for the RequestWrite
|
||||
emit OnAssetIDChanged(AZ::Data::AssetId());
|
||||
}
|
||||
|
||||
void SourceHandlePropertyAssetCtrl::OnAutocomplete(const QModelIndex& index)
|
||||
{
|
||||
SetSelectedSourcePath(m_model->GetPathFromIndex(GetSourceIndex(index)));
|
||||
}
|
||||
|
||||
QWidget* SourceHandlePropertyHandler::CreateGUI(QWidget* pParent)
|
||||
{
|
||||
SourceHandlePropertyAssetCtrl* newCtrl = aznew SourceHandlePropertyAssetCtrl(pParent);
|
||||
connect(newCtrl, &SourceHandlePropertyAssetCtrl::OnAssetIDChanged, this, [newCtrl](AZ::Data::AssetId newAssetID)
|
||||
{
|
||||
(void)newAssetID;
|
||||
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::RequestWrite, newCtrl);
|
||||
AzToolsFramework::PropertyEditorGUIMessages::Bus::Broadcast(&AzToolsFramework::PropertyEditorGUIMessages::OnEditingFinished, newCtrl);
|
||||
});
|
||||
return newCtrl;
|
||||
}
|
||||
|
||||
void SourceHandlePropertyHandler::ConsumeAttribute(SourceHandlePropertyAssetCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName)
|
||||
{
|
||||
// Let the AssetPropertyHandlerDefault handle all of the common attributes
|
||||
AzToolsFramework::AssetPropertyHandlerDefault::ConsumeAttributeInternal(GUI, attrib, attrValue, debugName);
|
||||
|
||||
if (attrib == AZ::Edit::Attributes::SourceAssetFilterPattern)
|
||||
{
|
||||
AZStd::string filterPattern;
|
||||
if (attrValue->Read<AZStd::string>(filterPattern))
|
||||
{
|
||||
GUI->SetSourceAssetFilterPattern(filterPattern.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SourceHandlePropertyHandler::WriteGUIValuesIntoProperty(size_t index, SourceHandlePropertyAssetCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
(void)index;
|
||||
(void)node;
|
||||
|
||||
auto sourceHandle = SourceHandle(nullptr, GUI->GetSelectedSourcePath());
|
||||
auto completeSourceHandle = CompleteDescription(sourceHandle);
|
||||
if (completeSourceHandle)
|
||||
{
|
||||
instance = property_t(*CompleteDescription(sourceHandle));
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = property_t();
|
||||
}
|
||||
}
|
||||
|
||||
bool SourceHandlePropertyHandler::ReadValuesIntoGUI(size_t index, SourceHandlePropertyAssetCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node)
|
||||
{
|
||||
(void)index;
|
||||
(void)node;
|
||||
|
||||
GUI->blockSignals(true);
|
||||
|
||||
GUI->SetSelectedSourcePath(instance.Path());
|
||||
GUI->SetEditNotifyTarget(node->GetParent()->GetInstance(0));
|
||||
|
||||
GUI->blockSignals(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyAssetCtrl.hxx>
|
||||
|
||||
#include <Core/Core.h>
|
||||
#endif
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
class SourceHandlePropertyAssetCtrl
|
||||
: public AzToolsFramework::PropertyAssetCtrl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(SourceHandlePropertyAssetCtrl, AZ::SystemAllocator, 0);
|
||||
|
||||
SourceHandlePropertyAssetCtrl(QWidget* parent = nullptr);
|
||||
|
||||
AzToolsFramework::AssetBrowser::AssetSelectionModel GetAssetSelectionModel() override;
|
||||
void PopupAssetPicker() override;
|
||||
void ClearAssetInternal() override;
|
||||
void ConfigureAutocompleter() override;
|
||||
|
||||
void SetSourceAssetFilterPattern(const QString& filterPattern);
|
||||
|
||||
AZ::IO::Path GetSelectedSourcePath() const;
|
||||
void SetSelectedSourcePath(const AZ::IO::Path& sourcePath);
|
||||
|
||||
public Q_SLOTS:
|
||||
void OnAutocomplete(const QModelIndex& index) override;
|
||||
|
||||
private:
|
||||
//! A regular expression pattern for filtering by source assets
|
||||
//! If this is set, the PropertyAssetCtrl will be dealing with source assets
|
||||
//! instead of a specific asset type
|
||||
QString m_sourceAssetFilterPattern;
|
||||
|
||||
AZ::IO::Path m_selectedSourcePath;
|
||||
};
|
||||
|
||||
class SourceHandlePropertyHandler
|
||||
: QObject
|
||||
, public AzToolsFramework::PropertyHandler<SourceHandle, SourceHandlePropertyAssetCtrl>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(SourceHandlePropertyHandler, AZ::SystemAllocator, 0);
|
||||
|
||||
AZ::u32 GetHandlerName(void) const override { return AZ_CRC_CE("SourceHandle"); }
|
||||
bool IsDefaultHandler() const override { return true; }
|
||||
QWidget* GetFirstInTabOrder(SourceHandlePropertyAssetCtrl* widget) override { return widget->GetFirstInTabOrder(); }
|
||||
QWidget* GetLastInTabOrder(SourceHandlePropertyAssetCtrl* widget) override { return widget->GetLastInTabOrder(); }
|
||||
void UpdateWidgetInternalTabbing(SourceHandlePropertyAssetCtrl* widget) override { widget->UpdateTabOrder(); }
|
||||
|
||||
QWidget* CreateGUI(QWidget* pParent) override;
|
||||
void ConsumeAttribute(SourceHandlePropertyAssetCtrl* GUI, AZ::u32 attrib, AzToolsFramework::PropertyAttributeReader* attrValue, const char* debugName) override;
|
||||
void WriteGUIValuesIntoProperty(size_t index, SourceHandlePropertyAssetCtrl* GUI, property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
bool ReadValuesIntoGUI(size_t index, SourceHandlePropertyAssetCtrl* GUI, const property_t& instance, AzToolsFramework::InstanceDataNode* node) override;
|
||||
};
|
||||
}
|
||||
+4
-1
@@ -257,7 +257,10 @@ namespace ScriptCanvasEditor
|
||||
|
||||
if (treeItem->GetAssetId().IsValid())
|
||||
{
|
||||
GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, treeItem->GetAssetId());
|
||||
GeneralRequestBus::Broadcast
|
||||
( &GeneralRequests::OpenScriptCanvasAssetId
|
||||
, SourceHandle(nullptr, treeItem->GetAssetId().m_guid, "")
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,7 +433,10 @@ namespace ScriptCanvasEditor
|
||||
AZ::Data::AssetId sourceAssetId(sourceUuid, 0);
|
||||
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAssetId, sourceAssetId);
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAssetId
|
||||
, ScriptCanvasEditor::SourceHandle(nullptr, sourceUuid, {})
|
||||
, Tracker::ScriptCanvasFileState::UNMODIFIED);
|
||||
|
||||
if (!openOutcome)
|
||||
{
|
||||
AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data());
|
||||
|
||||
+1
-4
@@ -716,10 +716,7 @@ namespace ScriptCanvasEditor
|
||||
void GraphVariablesModel::SetActiveScene(const ScriptCanvas::ScriptCanvasId& scriptCanvasId)
|
||||
{
|
||||
ScriptCanvas::GraphVariableManagerNotificationBus::Handler::BusDisconnect();
|
||||
|
||||
m_assetType = AZ::Data::AssetType::CreateNull();
|
||||
ScriptCanvas::GraphRequestBus::EventResult(m_assetType, scriptCanvasId, &ScriptCanvas::GraphRequests::GetAssetType);
|
||||
|
||||
m_assetType = azrtti_typeid<ScriptCanvasAsset>();
|
||||
m_scriptCanvasId = scriptCanvasId;
|
||||
|
||||
if (m_scriptCanvasId.IsValid())
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,6 @@
|
||||
#include <ScriptCanvas/Bus/EditorScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Core/ScriptCanvasBus.h>
|
||||
#include <ScriptCanvas/Debugger/ClientTransceiver.h>
|
||||
|
||||
#include <Editor/Assets/ScriptCanvasAssetHolder.h>
|
||||
#include <Editor/Undo/ScriptCanvasGraphCommand.h>
|
||||
#include <Editor/Utilities/RecentFiles.h>
|
||||
@@ -51,8 +50,8 @@
|
||||
#include <Editor/View/Widgets/NodePalette/NodePaletteModel.h>
|
||||
|
||||
#include <Editor/View/Widgets/AssetGraphSceneDataBus.h>
|
||||
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/Controller.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/FileSaver.h>
|
||||
|
||||
#if SCRIPTCANVAS_EDITOR
|
||||
#include <Include/EditorCoreAPI.h>
|
||||
@@ -153,7 +152,7 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
};
|
||||
|
||||
//! Manages the Save/Restore operations of the user's las topened and focused graphs
|
||||
//! Manages the Save/Restore operations of the user's last opened and focused graphs
|
||||
class Workspace
|
||||
: AssetTrackerNotificationBus::MultiHandler
|
||||
{
|
||||
@@ -175,9 +174,9 @@ namespace ScriptCanvasEditor
|
||||
private:
|
||||
|
||||
void OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset) override;
|
||||
void SignalAssetComplete(const AZ::Data::AssetId& fileAssetId);
|
||||
void SignalAssetComplete(const ScriptCanvasEditor::SourceHandle& fileAssetId);
|
||||
|
||||
AZ::Data::AssetId GetSourceAssetId(const AZ::Data::AssetId& memoryAssetId) const;
|
||||
ScriptCanvasEditor::SourceHandle GetSourceAssetId(const ScriptCanvasEditor::SourceHandle& memoryAssetId) const;
|
||||
|
||||
bool m_rememberOpenCanvases;
|
||||
MainWindow* m_mainWindow;
|
||||
@@ -185,10 +184,10 @@ namespace ScriptCanvasEditor
|
||||
//! Setting focus is problematic unless it is done until after all currently loading graphs have finished loading
|
||||
//! This vector is used to track the list of graphs being opened to restore the workspace and as assets are fully
|
||||
//! ready and activated they are removed from this list.
|
||||
AZStd::vector<AZ::Data::AssetId> m_loadingAssets;
|
||||
AZStd::vector<ScriptCanvasEditor::SourceHandle> m_loadingAssets;
|
||||
|
||||
//! During restore we queue the asset Id to focus in order to do it last
|
||||
AZ::Data::AssetId m_queuedAssetFocus;
|
||||
ScriptCanvasEditor::SourceHandle m_queuedAssetFocus;
|
||||
};
|
||||
|
||||
enum class UnsavedChangesOptions;
|
||||
@@ -230,7 +229,6 @@ namespace ScriptCanvasEditor
|
||||
, private VariablePaletteRequestBus::Handler
|
||||
, private ScriptCanvas::BatchOperationNotificationBus::Handler
|
||||
, private AssetGraphSceneBus::Handler
|
||||
, private AssetTrackerNotificationBus::MultiHandler
|
||||
#if SCRIPTCANVAS_EDITOR
|
||||
//, public IEditorNotifyListener
|
||||
#endif
|
||||
@@ -239,6 +237,7 @@ namespace ScriptCanvasEditor
|
||||
, private GraphCanvas::ViewNotificationBus::Handler
|
||||
, public AZ::SystemTickBus::Handler
|
||||
, private AzToolsFramework::ToolsApplicationNotificationBus::Handler
|
||||
, private AzToolsFramework::AssetSystemBus::Handler
|
||||
, private ScriptCanvas::ScriptCanvasSettingsRequestBus::Handler
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -269,7 +268,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
// Undo Handlers
|
||||
void PostUndoPoint(ScriptCanvas::ScriptCanvasId scriptCanvasId) override;
|
||||
void SignalSceneDirty(AZ::Data::AssetId assetId) override;
|
||||
void SignalSceneDirty(ScriptCanvasEditor::SourceHandle assetId) override;
|
||||
|
||||
void PushPreventUndoStateUpdate() override;
|
||||
void PopPreventUndoStateUpdate() override;
|
||||
@@ -325,12 +324,17 @@ namespace ScriptCanvasEditor
|
||||
// File menu
|
||||
void OnFileNew();
|
||||
|
||||
bool OnFileSave(const Callbacks::OnSave& saveCB);
|
||||
bool OnFileSaveAs(const Callbacks::OnSave& saveCB);
|
||||
bool OnFileSaveCaller(){return OnFileSave(nullptr);};
|
||||
bool OnFileSaveAsCaller(){return OnFileSaveAs(nullptr);};
|
||||
bool SaveAssetImpl(const AZ::Data::AssetId& assetId, const Callbacks::OnSave& saveCB);
|
||||
bool SaveAssetAsImpl(const AZ::Data::AssetId& assetId, const Callbacks::OnSave& saveCB);
|
||||
bool OnFileSave();
|
||||
bool OnFileSaveAs();
|
||||
bool OnFileSaveCaller(){return OnFileSave();};
|
||||
bool OnFileSaveAsCaller(){return OnFileSaveAs();};
|
||||
bool SaveAssetImpl_OLD(const ScriptCanvasEditor::SourceHandle& assetId, const Callbacks::OnSave& saveCB);
|
||||
enum class Save
|
||||
{
|
||||
InPlace,
|
||||
As
|
||||
};
|
||||
bool SaveAssetImpl(const ScriptCanvasEditor::SourceHandle& assetId, Save save);
|
||||
void OnFileOpen();
|
||||
|
||||
// Edit menu
|
||||
@@ -415,30 +419,27 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void CloseNextTab();
|
||||
|
||||
bool IsTabOpen(const AZ::Data::AssetId& assetId, int& outTabIndex) const;
|
||||
QVariant GetTabData(const AZ::Data::AssetId& assetId);
|
||||
bool IsTabOpen(const SourceHandle& assetId, int& outTabIndex) const;
|
||||
QVariant GetTabData(const SourceHandle& assetId);
|
||||
|
||||
//! GeneralRequestBus
|
||||
AZ::Outcome<int, AZStd::string> OpenScriptCanvasAssetId(const AZ::Data::AssetId& assetId) override;
|
||||
AZ::Outcome<int, AZStd::string> OpenScriptCanvasAsset(AZ::Data::AssetId scriptCanvasAssetId, int tabIndex = -1) override;
|
||||
AZ::Outcome<int, AZStd::string> OpenScriptCanvasAsset(const ScriptCanvasMemoryAsset& scriptCanvasAsset, int tabIndex = -1);
|
||||
int CloseScriptCanvasAsset(const AZ::Data::AssetId& assetId) override;
|
||||
AZ::Outcome<int, AZStd::string> OpenScriptCanvasAssetId(const SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState) override;
|
||||
AZ::Outcome<int, AZStd::string> OpenScriptCanvasAsset(SourceHandle scriptCanvasAssetId, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1) override;
|
||||
AZ::Outcome<int, AZStd::string> OpenScriptCanvasAssetImplementation(const SourceHandle& sourceHandle, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1);
|
||||
int CloseScriptCanvasAsset(const SourceHandle& assetId) override;
|
||||
bool CreateScriptCanvasAssetFor(const TypeDefs::EntityComponentId& requestingEntityId) override;
|
||||
|
||||
bool IsScriptCanvasAssetOpen(const AZ::Data::AssetId& assetId) const override;
|
||||
bool IsScriptCanvasAssetOpen(const SourceHandle& assetId) const override;
|
||||
|
||||
const CategoryInformation* FindNodePaletteCategoryInformation(AZStd::string_view categoryPath) const override;
|
||||
const NodePaletteModelInformation* FindNodePaletteModelInformation(const ScriptCanvas::NodeTypeIdentifier& nodeType) const override;
|
||||
////
|
||||
|
||||
AZ::Outcome<int, AZStd::string> CreateScriptCanvasAsset(AZStd::string_view assetPath, AZ::Data::AssetType assetType, int tabIndex = -1);
|
||||
AZ::Outcome<int, AZStd::string> UpdateScriptCanvasAsset(const AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>& scriptCanvasAsset);
|
||||
AZ::Outcome<int, AZStd::string> CreateScriptCanvasAsset(AZStd::string_view assetPath, int tabIndex = -1);
|
||||
|
||||
void RefreshScriptCanvasAsset(const AZ::Data::Asset<ScriptCanvas::ScriptCanvasAssetBase>& scriptCanvasAsset);
|
||||
|
||||
//! Removes the assetId -> ScriptCanvasAsset mapping and disconnects from the asset tracker
|
||||
void RemoveScriptCanvasAsset(const AZ::Data::AssetId& assetId);
|
||||
void OnChangeActiveGraphTab(AZ::Data::AssetId) override;
|
||||
void RemoveScriptCanvasAsset(const ScriptCanvasEditor::SourceHandle& assetId);
|
||||
void OnChangeActiveGraphTab(ScriptCanvasEditor::SourceHandle) override;
|
||||
|
||||
void CreateNewRuntimeAsset() override { OnFileNew(); }
|
||||
|
||||
@@ -448,8 +449,8 @@ namespace ScriptCanvasEditor
|
||||
|
||||
GraphCanvas::GraphId GetGraphCanvasGraphId(const ScriptCanvas::ScriptCanvasId& scriptCanvasId) const override;
|
||||
|
||||
GraphCanvas::GraphId FindGraphCanvasGraphIdByAssetId(const AZ::Data::AssetId& assetId) const override;
|
||||
ScriptCanvas::ScriptCanvasId FindScriptCanvasIdByAssetId(const AZ::Data::AssetId& assetId) const override;
|
||||
GraphCanvas::GraphId FindGraphCanvasGraphIdByAssetId(const ScriptCanvasEditor::SourceHandle& assetId) const override;
|
||||
ScriptCanvas::ScriptCanvasId FindScriptCanvasIdByAssetId(const ScriptCanvasEditor::SourceHandle& assetId) const override;
|
||||
|
||||
bool IsInUndoRedo(const AZ::EntityId& graphCanvasGraphId) const override;
|
||||
bool IsScriptCanvasInUndoRedo(const ScriptCanvas::ScriptCanvasId& scriptCanvasId) const override;
|
||||
@@ -517,17 +518,18 @@ namespace ScriptCanvasEditor
|
||||
QObject* FindElementByName(QString elementName) override;
|
||||
////
|
||||
|
||||
AZ::EntityId FindEditorNodeIdByAssetNodeId(const AZ::Data::AssetId& assetId, AZ::EntityId assetNodeId) const override;
|
||||
AZ::EntityId FindAssetNodeIdByEditorNodeId(const AZ::Data::AssetId& assetId, AZ::EntityId editorNodeId) const override;
|
||||
AZ::EntityId FindEditorNodeIdByAssetNodeId(const ScriptCanvasEditor::SourceHandle& assetId, AZ::EntityId assetNodeId) const override;
|
||||
AZ::EntityId FindAssetNodeIdByEditorNodeId(const ScriptCanvasEditor::SourceHandle& assetId, AZ::EntityId editorNodeId) const override;
|
||||
|
||||
private:
|
||||
void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
|
||||
void SourceFileRemoved(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
|
||||
|
||||
void DeleteNodes(const AZ::EntityId& sceneId, const AZStd::vector<AZ::EntityId>& nodes) override;
|
||||
void DeleteConnections(const AZ::EntityId& sceneId, const AZStd::vector<AZ::EntityId>& connections) override;
|
||||
void DisconnectEndpoints(const AZ::EntityId& sceneId, const AZStd::vector<GraphCanvas::Endpoint>& endpoints) override;
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void UpdateWorkspaceStatus(const ScriptCanvasMemoryAsset& scriptCanvasAsset);
|
||||
|
||||
GraphCanvas::Endpoint HandleProposedConnection(const GraphCanvas::GraphId& graphId, const GraphCanvas::ConnectionId& connectionId, const GraphCanvas::Endpoint& endpoint, const GraphCanvas::NodeId& proposedNode, const QPoint& screenPoint);
|
||||
|
||||
//! UndoNotificationBus
|
||||
@@ -543,29 +545,20 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void OnAutoSave();
|
||||
|
||||
//! Helper function which serializes a file to disk
|
||||
//! \param filename name of file to serialize the Entity
|
||||
//! \param asset asset to save
|
||||
void GetSuggestedFullFilenameToSaveAs(const AZ::Data::AssetId& assetId, AZStd::string& filePath, AZStd::string& fileFilter);
|
||||
|
||||
void MarkAssetModified(const AZ::Data::AssetId& assetId);
|
||||
void UpdateFileState(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState);
|
||||
|
||||
// QMainWindow
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
UnsavedChangesOptions ShowSaveDialog(const QString& filename);
|
||||
|
||||
bool ActivateAndSaveAsset(const AZ::Data::AssetId& unsavedAssetId, const Callbacks::OnSave& onSave);
|
||||
bool ActivateAndSaveAsset(const ScriptCanvasEditor::SourceHandle& unsavedAssetId);
|
||||
|
||||
void SaveNewAsset(AZStd::string_view path, AZ::Data::AssetId assetId, const Callbacks::OnSave& onSave);
|
||||
void SaveAsset(AZ::Data::AssetId assetId, const Callbacks::OnSave& onSave);
|
||||
void SaveAs(AZStd::string_view path, ScriptCanvasEditor::SourceHandle assetId);
|
||||
|
||||
void OpenFile(const char* fullPath);
|
||||
void CreateMenus();
|
||||
|
||||
void SignalActiveSceneChanged(const AZ::Data::AssetId assetId);
|
||||
|
||||
void SaveWorkspace(bool updateAssetList = true);
|
||||
void RestoreWorkspace();
|
||||
void SignalActiveSceneChanged(const ScriptCanvasEditor::SourceHandle assetId);
|
||||
|
||||
void RunUpgradeTool();
|
||||
|
||||
@@ -593,29 +586,27 @@ namespace ScriptCanvasEditor
|
||||
void UpdateMenuState(bool enabledState);
|
||||
|
||||
void OnWorkspaceRestoreStart();
|
||||
void OnWorkspaceRestoreEnd(AZ::Data::AssetId lastFocusAsset);
|
||||
void OnWorkspaceRestoreEnd(ScriptCanvasEditor::SourceHandle lastFocusAsset);
|
||||
|
||||
void UpdateAssignToSelectionState();
|
||||
void UpdateUndoRedoState();
|
||||
void UpdateSaveState();
|
||||
void UpdateSaveState(bool enabled);
|
||||
|
||||
void CreateFunctionInput();
|
||||
void CreateFunctionOutput();
|
||||
|
||||
void CreateFunctionDefinitionNode(int positionOffset);
|
||||
|
||||
int CreateAssetTab(const AZ::Data::AssetId& assetId, int tabIndex = -1);
|
||||
int CreateAssetTab(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1);
|
||||
|
||||
//! \param asset The AssetId of the ScriptCanvas Asset.
|
||||
void SetActiveAsset(const AZ::Data::AssetId& assetId);
|
||||
void SetActiveAsset(const ScriptCanvasEditor::SourceHandle& assetId);
|
||||
void RefreshActiveAsset();
|
||||
|
||||
void ReconnectSceneBuses(AZ::Data::AssetId previousAssetId, AZ::Data::AssetId nextAssetId);
|
||||
|
||||
void SignalBatchOperationComplete(BatchOperatorTool* batchTool);
|
||||
void ReconnectSceneBuses(ScriptCanvasEditor::SourceHandle previousAssetId, ScriptCanvasEditor::SourceHandle nextAssetId);
|
||||
|
||||
void PrepareActiveAssetForSave();
|
||||
void PrepareAssetForSave(const AZ::Data::AssetId& asssetId);
|
||||
void PrepareAssetForSave(const ScriptCanvasEditor::SourceHandle& asssetId);
|
||||
|
||||
void RestartAutoTimerSave(bool forceTimer = false);
|
||||
|
||||
@@ -626,24 +617,16 @@ namespace ScriptCanvasEditor
|
||||
void AssignGraphToEntityImpl(const AZ::EntityId& entityId);
|
||||
////
|
||||
|
||||
Tracker::ScriptCanvasFileState GetAssetFileState(AZ::Data::AssetId assetId) const;
|
||||
Tracker::ScriptCanvasFileState GetAssetFileState(ScriptCanvasEditor::SourceHandle assetId) const;
|
||||
|
||||
AZ::Data::AssetId GetSourceAssetId(const AZ::Data::AssetId& memoryAssetId) const
|
||||
ScriptCanvasEditor::SourceHandle GetSourceAssetId(const ScriptCanvasEditor::SourceHandle& memoryAssetId) const
|
||||
{
|
||||
ScriptCanvasMemoryAsset::pointer memoryAsset;
|
||||
AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, memoryAssetId);
|
||||
|
||||
if (memoryAsset)
|
||||
{
|
||||
return memoryAsset->GetFileAssetId();
|
||||
}
|
||||
|
||||
return AZ::Data::AssetId();
|
||||
return memoryAssetId;
|
||||
}
|
||||
|
||||
int InsertTabForAsset(AZStd::string_view assetPath, AZ::Data::AssetId assetId, int tabIndex = -1);
|
||||
int InsertTabForAsset(AZStd::string_view assetPath, ScriptCanvasEditor::SourceHandle assetId, int tabIndex = -1);
|
||||
|
||||
void UpdateUndoCache(AZ::Data::AssetId assetId);
|
||||
void UpdateUndoCache(ScriptCanvasEditor::SourceHandle assetId);
|
||||
|
||||
|
||||
bool HasSystemTickAction(SystemTickActionFlag action);
|
||||
@@ -655,34 +638,9 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void OpenNextFile();
|
||||
|
||||
template <typename GraphAssetType, typename AssetHandler>
|
||||
void MakeNewFile()
|
||||
{
|
||||
static int scriptCanvasEditorDefaultNewNameCount = 0;
|
||||
|
||||
AZStd::string newAssetName = AZStd::string::format(ScriptCanvas::AssetDescription::GetAssetNamePattern<GraphAssetType>(), ++scriptCanvasEditorDefaultNewNameCount);
|
||||
|
||||
AZStd::array<char, AZ::IO::MaxPathLength> assetRootArray;
|
||||
if (!AZ::IO::FileIOBase::GetInstance()->ResolvePath(ScriptCanvas::AssetDescription::GetSuggestedSavePath<GraphAssetType>(), assetRootArray.data(), assetRootArray.size()))
|
||||
{
|
||||
AZ_ErrorOnce("Script Canvas", false, "Unable to resolve @projectroot@ path");
|
||||
}
|
||||
|
||||
AZStd::string assetPath;
|
||||
AzFramework::StringFunc::Path::Join(assetRootArray.data(), (newAssetName + ScriptCanvas::AssetDescription::GetExtension<GraphAssetType>()).data(), assetPath);
|
||||
|
||||
auto createOutcome = CreateScriptCanvasAsset(assetPath, azrtti_typeid<GraphAssetType>());
|
||||
if (createOutcome)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("Script Canvas", createOutcome, "%s", createOutcome.GetError().data());
|
||||
}
|
||||
}
|
||||
|
||||
void DisableAssetView(ScriptCanvasMemoryAsset::pointer memoryAsset);
|
||||
void EnableAssetView(ScriptCanvasMemoryAsset::pointer memoryAsset);
|
||||
void DisableAssetView(const ScriptCanvasEditor::SourceHandle& memoryAssetId);
|
||||
void EnableAssetView(const ScriptCanvasEditor::SourceHandle& memoryAssetId);
|
||||
|
||||
|
||||
QWidget* m_host = nullptr;
|
||||
@@ -741,22 +699,22 @@ namespace ScriptCanvasEditor
|
||||
GraphCanvas::GraphCanvasEditorEmptyDockWidget* m_emptyCanvas; // Displayed when there is no open graph
|
||||
QVBoxLayout* m_layout;
|
||||
|
||||
AZ::Data::AssetId m_activeAssetId;
|
||||
|
||||
ScriptCanvasEditor::SourceHandle m_activeGraph;
|
||||
|
||||
bool m_loadingNewlySavedFile;
|
||||
AZStd::string m_newlySavedFile;
|
||||
|
||||
AZStd::string m_errorFilePath;
|
||||
|
||||
bool m_isClosingTabs;
|
||||
AZ::Data::AssetId m_skipTabOnClose;
|
||||
ScriptCanvasEditor::SourceHandle m_skipTabOnClose;
|
||||
|
||||
bool m_enterState;
|
||||
bool m_ignoreSelection;
|
||||
AZ::s32 m_preventUndoStateUpdateCount;
|
||||
|
||||
bool m_isRestoringWorkspace;
|
||||
AZ::Data::AssetId m_queuedFocusOverride;
|
||||
ScriptCanvasEditor::SourceHandle m_queuedFocusOverride;
|
||||
|
||||
Ui::MainWindow* ui;
|
||||
AZStd::array<AZStd::pair<QAction*, QMetaObject::Connection>, c_scriptCanvasEditorSettingsRecentFilesCountMax> m_recentActions;
|
||||
@@ -778,17 +736,17 @@ namespace ScriptCanvasEditor
|
||||
AZStd::vector<AZ::EntityId> m_selectedVariableIds;
|
||||
|
||||
AZ::u32 m_systemTickActions;
|
||||
AZStd::unordered_set< AZ::Data::AssetId > m_processedClosedAssetIds;
|
||||
AZStd::unordered_set< ScriptCanvasEditor::SourceHandle > m_processedClosedAssetIds;
|
||||
|
||||
AZStd::unordered_set< AZ::Data::AssetId > m_loadingWorkspaceAssets;
|
||||
AZStd::unordered_set< AZ::Data::AssetId > m_loadingAssets;
|
||||
AZStd::unordered_set< ScriptCanvasEditor::SourceHandle > m_loadingWorkspaceAssets;
|
||||
AZStd::unordered_set< ScriptCanvasEditor::SourceHandle > m_loadingAssets;
|
||||
AZStd::unordered_set< AZ::Uuid > m_variablePaletteTypes;
|
||||
|
||||
AZStd::unordered_map< AZ::Crc32, QObject* > m_automationLookUpMap;
|
||||
|
||||
bool m_closeCurrentGraphAfterSave;
|
||||
|
||||
AZStd::unordered_map< AZ::Data::AssetId, TypeDefs::EntityComponentId > m_assetCreationRequests;
|
||||
AZStd::unordered_map< ScriptCanvasEditor::SourceHandle, TypeDefs::EntityComponentId > m_assetCreationRequests;
|
||||
|
||||
ScriptCanvas::Debugger::ClientTransceiver m_clientTRX;
|
||||
GraphCanvas::StyleManager m_styleManager;
|
||||
@@ -797,6 +755,14 @@ namespace ScriptCanvasEditor
|
||||
//! this object manages the Save/Restore operations
|
||||
Workspace* m_workspace;
|
||||
|
||||
void OnSaveCallback(bool saveSuccess, AZ::Data::AssetPtr, AZ::Data::AssetId previousFileAssetId);
|
||||
AZStd::unique_ptr<VersionExplorer::FileSaver> m_fileSaver;
|
||||
VersionExplorer::FileSaveResult m_fileSaveResult;
|
||||
void OnSaveCallBack(const VersionExplorer::FileSaveResult& result);
|
||||
|
||||
void ClearStaleSaves();
|
||||
bool IsRecentSave(const SourceHandle& handle) const;
|
||||
void MarkRecentSave(const SourceHandle& handle);
|
||||
AZStd::recursive_mutex m_mutex;
|
||||
AZStd::unordered_map <AZStd::string, AZStd::chrono::system_clock::time_point> m_saves;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace ScriptCanvasEditor
|
||||
m_view->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn);
|
||||
connect(m_view->scanButton, &QPushButton::pressed, this, &Controller::OnButtonPressScan);
|
||||
connect(m_view->closeButton, &QPushButton::pressed, this, &Controller::OnButtonPressClose);
|
||||
m_view->upgradeAllButton->setVisible(false);
|
||||
connect(m_view->upgradeAllButton, &QPushButton::pressed, this, &Controller::OnButtonPressUpgrade);
|
||||
m_view->progressBar->setValue(0);
|
||||
m_view->progressBar->setVisible(false);
|
||||
@@ -104,9 +103,9 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
QList<QTableWidgetItem*> Controller::FindTableItems(const AZ::Data::AssetInfo& info)
|
||||
QList<QTableWidgetItem*> Controller::FindTableItems(const SourceHandle& info)
|
||||
{
|
||||
return m_view->tableWidget->findItems(info.m_relativePath.c_str(), Qt::MatchFlag::MatchExactly);
|
||||
return m_view->tableWidget->findItems(info.Path().c_str(), Qt::MatchFlag::MatchExactly);
|
||||
}
|
||||
|
||||
void Controller::OnButtonPressClose()
|
||||
@@ -117,30 +116,20 @@ namespace ScriptCanvasEditor
|
||||
void Controller::OnButtonPressScan()
|
||||
{
|
||||
// \todo move to another file
|
||||
auto isUpToDate = [this](AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
auto isUpToDate = [this](const SourceHandle& asset)
|
||||
{
|
||||
AZ::Entity* scriptCanvasEntity = nullptr;
|
||||
auto graphComponent = asset.Get();
|
||||
|
||||
if (asset.GetType() == azrtti_typeid<ScriptCanvasAsset>())
|
||||
{
|
||||
ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs<ScriptCanvasAsset>();
|
||||
if (!scriptCanvasAsset)
|
||||
{
|
||||
AZ_Warning
|
||||
(ScriptCanvas::k_VersionExplorerWindow.data()
|
||||
, false
|
||||
, "InspectAsset: %s, AsestData failed to return ScriptCanvasAsset"
|
||||
, asset.GetHint().c_str());
|
||||
return true;
|
||||
}
|
||||
AZ_Warning
|
||||
( ScriptCanvas::k_VersionExplorerWindow.data()
|
||||
, asset.Get() != nullptr
|
||||
, "InspectAsset: %s, failed to load valid graph"
|
||||
, asset.Path().c_str());
|
||||
|
||||
scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity();
|
||||
AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity");
|
||||
}
|
||||
|
||||
auto graphComponent = scriptCanvasEntity->FindComponent<ScriptCanvasEditor::Graph>();
|
||||
AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component");
|
||||
return !m_view->forceUpgrade->isChecked() && graphComponent->GetVersion().IsLatest();
|
||||
return graphComponent
|
||||
&& (!graphComponent->GetVersion().IsLatest() || m_view->forceUpgrade->isChecked())
|
||||
? ScanConfiguration::Filter::Include
|
||||
: ScanConfiguration::Filter::Exclude;
|
||||
};
|
||||
|
||||
ScanConfiguration config;
|
||||
@@ -156,59 +145,19 @@ namespace ScriptCanvasEditor
|
||||
OnButtonPressUpgradeImplementation({});
|
||||
}
|
||||
|
||||
void Controller::OnButtonPressUpgradeImplementation(const AZ::Data::AssetInfo& assetInfo)
|
||||
void Controller::OnButtonPressUpgradeImplementation(const SourceHandle& assetInfo)
|
||||
{
|
||||
auto simpleUpdate = [this](AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
auto simpleUpdate = [this](SourceHandle& asset)
|
||||
{
|
||||
if (asset.GetType() == azrtti_typeid<ScriptCanvasAsset>())
|
||||
AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), asset.Get() != nullptr
|
||||
, "The Script Canvas asset must have a Graph component");
|
||||
|
||||
if (asset.Get())
|
||||
{
|
||||
ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs<ScriptCanvasAsset>();
|
||||
AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s"
|
||||
, azrtti_typeid<ScriptCanvasAsset>().template ToString<AZStd::string>().c_str());
|
||||
if (!scriptCanvasAsset)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity();
|
||||
AZ_Assert(scriptCanvasEntity, "View::UpgradeGraph The Script Canvas asset must have a valid entity");
|
||||
if (!scriptCanvasEntity)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AZ::Entity* queryEntity = nullptr;
|
||||
AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId());
|
||||
if (queryEntity)
|
||||
{
|
||||
if (queryEntity->GetState() == AZ::Entity::State::Active)
|
||||
{
|
||||
queryEntity->Deactivate();
|
||||
}
|
||||
|
||||
scriptCanvasEntity = queryEntity;
|
||||
}
|
||||
|
||||
if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed)
|
||||
{
|
||||
scriptCanvasEntity->Init();
|
||||
}
|
||||
|
||||
if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init)
|
||||
{
|
||||
scriptCanvasEntity->Activate();
|
||||
}
|
||||
|
||||
AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active");
|
||||
auto graphComponent = scriptCanvasEntity->FindComponent<ScriptCanvasEditor::Graph>();
|
||||
AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component");
|
||||
if (graphComponent)
|
||||
{
|
||||
graphComponent->UpgradeGraph
|
||||
(asset
|
||||
, m_view->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate
|
||||
, m_view->verbose->isChecked());
|
||||
}
|
||||
asset.Mod()->UpgradeGraph
|
||||
( asset
|
||||
, m_view->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate
|
||||
, m_view->verbose->isChecked());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -216,7 +165,7 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
int result = QMessageBox::No;
|
||||
QMessageBox mb
|
||||
(QMessageBox::Warning
|
||||
( QMessageBox::Warning
|
||||
, QObject::tr("Failed to Save Upgraded File")
|
||||
, QObject::tr("The upgraded file could not be saved because the file is read only.\n"
|
||||
"Do you want to make it writeable and overwrite it?")
|
||||
@@ -235,12 +184,17 @@ namespace ScriptCanvasEditor
|
||||
ModelRequestsBus::Broadcast(&ModelRequestsTraits::Modify, config);
|
||||
}
|
||||
|
||||
void Controller::OnButtonPressUpgradeSingle(const AZ::Data::AssetInfo& assetInfo)
|
||||
void Controller::OnButtonPressUpgradeSingle(const SourceHandle& info)
|
||||
{
|
||||
OnButtonPressUpgradeImplementation(assetInfo);
|
||||
OnButtonPressUpgradeImplementation(info);
|
||||
}
|
||||
|
||||
void Controller::OnUpgradeModificationBegin([[maybe_unused]] const ModifyConfiguration& config, const AZ::Data::AssetInfo& info)
|
||||
void Controller::OnUpgradeDependencyWaitInterval([[maybe_unused]] const SourceHandle& info)
|
||||
{
|
||||
AddLogEntries();
|
||||
}
|
||||
|
||||
void Controller::OnUpgradeModificationBegin([[maybe_unused]] const ModifyConfiguration& config, const SourceHandle& info)
|
||||
{
|
||||
for (auto* item : FindTableItems(info))
|
||||
{
|
||||
@@ -252,16 +206,18 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void Controller::OnUpgradeModificationEnd
|
||||
( [[maybe_unused]] const ModifyConfiguration& config
|
||||
, const AZ::Data::AssetInfo& info
|
||||
, const SourceHandle& info
|
||||
, ModificationResult result)
|
||||
{
|
||||
if (result.errorMessage.empty())
|
||||
{
|
||||
VE_LOG("Successfully modified %s", result.assetInfo.m_relativePath.c_str());
|
||||
VE_LOG("Successfully modified %s", result.asset.Path().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
VE_LOG("Failed to modify %s: %s", result.assetInfo.m_relativePath.c_str(), result.errorMessage.data());
|
||||
VE_LOG("Failed to modify %s: %s", result.asset.Path().c_str(), result.errorMessage.data());
|
||||
AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data()
|
||||
, false, "Failed to modify %s: %s", result.asset.Path().c_str(), result.errorMessage.data());
|
||||
}
|
||||
|
||||
for (auto* item : FindTableItems(info))
|
||||
@@ -289,12 +245,10 @@ namespace ScriptCanvasEditor
|
||||
AddLogEntries();
|
||||
}
|
||||
|
||||
void Controller::OnGraphUpgradeComplete(AZ::Data::Asset<AZ::Data::AssetData>& asset, bool skipped)
|
||||
void Controller::OnGraphUpgradeComplete(ScriptCanvasEditor::SourceHandle& asset, bool skipped)
|
||||
{
|
||||
ModificationResult result;
|
||||
result.asset = asset;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult
|
||||
( result.assetInfo, &AZ::Data::AssetCatalogRequests::GetAssetInfoById, asset.GetId());
|
||||
|
||||
if (skipped)
|
||||
{
|
||||
@@ -342,19 +296,19 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::OnScanFilteredGraph(const AZ::Data::AssetInfo& info)
|
||||
void Controller::OnScanFilteredGraph(const SourceHandle& info)
|
||||
{
|
||||
OnScannedGraph(info, Filtered::Yes);
|
||||
}
|
||||
|
||||
void Controller::OnScannedGraph(const AZ::Data::AssetInfo& assetInfo, [[maybe_unused]] Filtered filtered)
|
||||
void Controller::OnScannedGraph(const SourceHandle& assetInfo, [[maybe_unused]] Filtered filtered)
|
||||
{
|
||||
const int rowIndex = m_view->tableWidget->rowCount();
|
||||
|
||||
if (filtered == Filtered::No || !m_view->onlyShowOutdated->isChecked())
|
||||
{
|
||||
m_view->tableWidget->insertRow(rowIndex);
|
||||
QTableWidgetItem* rowName = new QTableWidgetItem(tr(assetInfo.m_relativePath.c_str()));
|
||||
QTableWidgetItem* rowName = new QTableWidgetItem(tr(assetInfo.Path().c_str()));
|
||||
m_view->tableWidget->setItem(rowIndex, static_cast<int>(ColumnAsset), rowName);
|
||||
SetRowSucceeded(rowIndex);
|
||||
|
||||
@@ -376,17 +330,11 @@ namespace ScriptCanvasEditor
|
||||
|
||||
m_view->tableWidget->setCellWidget(rowIndex, static_cast<int>(ColumnAction), upgradeButton);
|
||||
}
|
||||
|
||||
char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 };
|
||||
AZStd::string path = AZStd::string::format("@devroot@/%s", assetInfo.m_relativePath.c_str());
|
||||
AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN);
|
||||
AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path);
|
||||
AZ::StringFunc::Path::Normalize(path);
|
||||
|
||||
|
||||
bool result = false;
|
||||
AZ::Data::AssetInfo info;
|
||||
AZStd::string watchFolder;
|
||||
QByteArray assetNameUtf8 = assetInfo.m_relativePath.c_str();
|
||||
QByteArray assetNameUtf8 = assetInfo.Path().c_str();
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
|
||||
( result
|
||||
, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath
|
||||
@@ -413,41 +361,41 @@ namespace ScriptCanvasEditor
|
||||
OnScannedGraphResult(assetInfo);
|
||||
}
|
||||
|
||||
void Controller::OnScannedGraphResult([[maybe_unused]] const AZ::Data::AssetInfo& info)
|
||||
void Controller::OnScannedGraphResult([[maybe_unused]] const SourceHandle& info)
|
||||
{
|
||||
m_view->progressBar->setValue(aznumeric_cast<int>(m_handledAssetCount));
|
||||
++m_handledAssetCount;
|
||||
AddLogEntries();
|
||||
}
|
||||
|
||||
void Controller::OnScanLoadFailure(const AZ::Data::AssetInfo& info)
|
||||
void Controller::OnScanLoadFailure(const SourceHandle& info)
|
||||
{
|
||||
const int rowIndex = m_view->tableWidget->rowCount();
|
||||
m_view->tableWidget->insertRow(rowIndex);
|
||||
QTableWidgetItem* rowName = new QTableWidgetItem
|
||||
( tr(AZStd::string::format("Load Error: %s", info.m_relativePath.c_str()).c_str()));
|
||||
( tr(AZStd::string::format("Load Error: %s", info.Path().c_str()).c_str()));
|
||||
m_view->tableWidget->setItem(rowIndex, static_cast<int>(ColumnAsset), rowName);
|
||||
SetRowFailed(rowIndex, "Load failed");
|
||||
OnScannedGraphResult(info);
|
||||
}
|
||||
|
||||
void Controller::OnScanUnFilteredGraph(const AZ::Data::AssetInfo& info)
|
||||
void Controller::OnScanUnFilteredGraph(const SourceHandle& info)
|
||||
{
|
||||
OnScannedGraph(info, Filtered::No);
|
||||
}
|
||||
|
||||
void Controller::OnUpgradeBegin
|
||||
( const ModifyConfiguration& config
|
||||
, [[maybe_unused]] const WorkingAssets& assets)
|
||||
, [[maybe_unused]] const AZStd::vector<SourceHandle>& assets)
|
||||
{
|
||||
QString spinnerText = QStringLiteral("Upgrade in progress - ");
|
||||
if (config.modifySingleAsset.m_assetId.IsValid())
|
||||
if (!config.modifySingleAsset.Path().empty())
|
||||
{
|
||||
spinnerText.append(" single graph");
|
||||
|
||||
if (assets.size() == 1)
|
||||
{
|
||||
for (auto* item : FindTableItems(assets.front().info))
|
||||
for (auto* item : FindTableItems(assets.front()))
|
||||
{
|
||||
int row = item->row();
|
||||
SetRowBusy(row);
|
||||
@@ -498,7 +446,7 @@ namespace ScriptCanvasEditor
|
||||
m_view->scanButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void Controller::OnUpgradeDependenciesGathered(const AZ::Data::AssetInfo& info, Result result)
|
||||
void Controller::OnUpgradeDependenciesGathered(const SourceHandle& info, Result result)
|
||||
{
|
||||
for (auto* item : FindTableItems(info))
|
||||
{
|
||||
@@ -527,7 +475,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void Controller::OnUpgradeDependencySortBegin
|
||||
( [[maybe_unused]] const ModifyConfiguration& config
|
||||
, const WorkingAssets& assets)
|
||||
, const AZStd::vector<SourceHandle>& assets)
|
||||
{
|
||||
m_handledAssetCount = 0;
|
||||
m_view->progressBar->setVisible(true);
|
||||
@@ -553,7 +501,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void Controller::OnUpgradeDependencySortEnd
|
||||
( [[maybe_unused]] const ModifyConfiguration& config
|
||||
, const WorkingAssets& assets
|
||||
, const AZStd::vector<SourceHandle>& assets
|
||||
, [[maybe_unused]] const AZStd::vector<size_t>& sortedOrder)
|
||||
{
|
||||
m_handledAssetCount = 0;
|
||||
|
||||
@@ -65,37 +65,38 @@ namespace ScriptCanvasEditor
|
||||
|
||||
void AddLogEntries();
|
||||
void EnableAllUpgradeButtons();
|
||||
QList<QTableWidgetItem*> FindTableItems(const AZ::Data::AssetInfo& assetInfo);
|
||||
QList<QTableWidgetItem*> FindTableItems(const SourceHandle& assetInfo);
|
||||
|
||||
void OnButtonPressClose();
|
||||
void OnButtonPressScan();
|
||||
void OnButtonPressUpgrade();
|
||||
void OnButtonPressUpgradeImplementation(const AZ::Data::AssetInfo& assetInfo);
|
||||
void OnButtonPressUpgradeSingle(const AZ::Data::AssetInfo& assetInfo);
|
||||
void OnButtonPressUpgradeImplementation(const SourceHandle& assetInfo);
|
||||
void OnButtonPressUpgradeSingle(const SourceHandle& assetInfo);
|
||||
|
||||
void OnGraphUpgradeComplete(AZ::Data::Asset<AZ::Data::AssetData>&, bool skipped) override;
|
||||
void OnGraphUpgradeComplete(SourceHandle&, bool skipped) override;
|
||||
|
||||
void OnScanBegin(size_t assetCount) override;
|
||||
void OnScanComplete(const ScanResult& result) override;
|
||||
void OnScanFilteredGraph(const AZ::Data::AssetInfo& info) override;
|
||||
void OnScanLoadFailure(const AZ::Data::AssetInfo& info) override;
|
||||
void OnScanUnFilteredGraph(const AZ::Data::AssetInfo& info) override;
|
||||
void OnScanFilteredGraph(const SourceHandle& info) override;
|
||||
void OnScanLoadFailure(const SourceHandle& info) override;
|
||||
void OnScanUnFilteredGraph(const SourceHandle& info) override;
|
||||
enum class Filtered { No, Yes };
|
||||
void OnScannedGraph(const AZ::Data::AssetInfo& info, Filtered filtered);
|
||||
void OnScannedGraphResult(const AZ::Data::AssetInfo& info);
|
||||
void OnScannedGraph(const SourceHandle& info, Filtered filtered);
|
||||
void OnScannedGraphResult(const SourceHandle& info);
|
||||
|
||||
// for single operation UI updates, just check the assets size, or note it on the request
|
||||
void OnUpgradeBegin(const ModifyConfiguration& config, const WorkingAssets& assets) override;
|
||||
void OnUpgradeBegin(const ModifyConfiguration& config, const AZStd::vector<SourceHandle>& assets) override;
|
||||
void OnUpgradeComplete(const ModificationResults& results) override;
|
||||
void OnUpgradeDependenciesGathered(const AZ::Data::AssetInfo& info, Result result) override;
|
||||
void OnUpgradeDependencySortBegin(const ModifyConfiguration& config, const WorkingAssets& assets) override;
|
||||
void OnUpgradeDependenciesGathered(const SourceHandle& info, Result result) override;
|
||||
void OnUpgradeDependencySortBegin(const ModifyConfiguration& config, const AZStd::vector<SourceHandle>& assets) override;
|
||||
void OnUpgradeDependencySortEnd
|
||||
( const ModifyConfiguration& config
|
||||
, const WorkingAssets& assets
|
||||
, const AZStd::vector<SourceHandle>& assets
|
||||
, const AZStd::vector<size_t>& sortedOrder) override;
|
||||
void OnUpgradeModificationBegin(const ModifyConfiguration& config, const AZ::Data::AssetInfo& info) override;
|
||||
void OnUpgradeModificationEnd(const ModifyConfiguration& config, const AZ::Data::AssetInfo& info, ModificationResult result) override;
|
||||
|
||||
void OnUpgradeDependencyWaitInterval(const SourceHandle& info) override;
|
||||
void OnUpgradeModificationBegin(const ModifyConfiguration& config, const SourceHandle& info) override;
|
||||
void OnUpgradeModificationEnd(const ModifyConfiguration& config, const SourceHandle& info, ModificationResult result) override;
|
||||
|
||||
void SetLoggingPreferences();
|
||||
void SetSpinnerIsBusy(bool isBusy);
|
||||
void SetRowBusy(int index);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzToolsFramework/SourceControl/SourceControlAPI.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/FileSaver.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAssetHandler.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
|
||||
namespace FileSaverCpp
|
||||
{
|
||||
@@ -58,6 +59,11 @@ namespace ScriptCanvasEditor
|
||||
, m_onComplete(onComplete)
|
||||
{}
|
||||
|
||||
const SourceHandle& FileSaver::GetSource() const
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
void FileSaver::PerformMove
|
||||
( AZStd::string tmpFileName
|
||||
, AZStd::string target
|
||||
@@ -70,7 +76,7 @@ namespace ScriptCanvasEditor
|
||||
AZ::SystemTickBus::QueueFunction([this, tmpFileName]()
|
||||
{
|
||||
FileSaveResult result;
|
||||
result.fileSaveError = "Failed to move updated file from temporary location to tmpFileName destination";
|
||||
result.fileSaveError = "Failed to move updated file from temporary location to original destination.";
|
||||
result.tempFileRemovalError = RemoveTempFile(tmpFileName);
|
||||
m_onComplete(result);
|
||||
});
|
||||
@@ -98,7 +104,9 @@ namespace ScriptCanvasEditor
|
||||
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
|
||||
AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str());
|
||||
// Bump the slice asset up in the asset processor's queue.
|
||||
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str());
|
||||
AzFramework::AssetSystemRequestBus::Broadcast
|
||||
(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str());
|
||||
|
||||
AZ::SystemTickBus::QueueFunction([this, tmpFileName]()
|
||||
{
|
||||
FileSaveResult result;
|
||||
@@ -108,28 +116,29 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to tmpFileName destination failed: %s, trying again", target.c_str());
|
||||
AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false
|
||||
, "moving converted file to tmpFileName destination failed: %s, trying again", target.c_str());
|
||||
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
|
||||
AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str());
|
||||
streamer->SetRequestCompleteCallback(flushRequest, [this, tmpFileName, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request)
|
||||
streamer->SetRequestCompleteCallback(flushRequest
|
||||
, [this, tmpFileName, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request)
|
||||
{
|
||||
// Continue saving.
|
||||
AZ::SystemTickBus::QueueFunction([this, tmpFileName, target, remainingAttempts]() { PerformMove(tmpFileName, target, remainingAttempts - 1); });
|
||||
AZ::SystemTickBus::QueueFunction(
|
||||
[this, tmpFileName, target, remainingAttempts]() { PerformMove(tmpFileName, target, remainingAttempts - 1); });
|
||||
});
|
||||
streamer->QueueRequest(flushRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSaver::OnSourceFileReleased(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
void FileSaver::OnSourceFileReleased(const SourceHandle& source)
|
||||
{
|
||||
AZStd::string relativePath, fullPath;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId());
|
||||
bool fullPathFound = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath);
|
||||
AZStd::string fullPath = source.Path().c_str();
|
||||
AZStd::string tmpFileName;
|
||||
// here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file.
|
||||
// This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP.
|
||||
// This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing.
|
||||
// Temp files are ignored by AP.
|
||||
if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName))
|
||||
{
|
||||
FileSaveResult result;
|
||||
@@ -138,23 +147,24 @@ namespace ScriptCanvasEditor
|
||||
return;
|
||||
}
|
||||
|
||||
bool tempSavedSucceeded = false;
|
||||
AZStd::string saveError;
|
||||
|
||||
AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText);
|
||||
if (fileStream.IsOpen())
|
||||
{
|
||||
if (asset.GetType() == azrtti_typeid<ScriptCanvasEditor::ScriptCanvasAsset>())
|
||||
auto saveOutcome = ScriptCanvasEditor::SaveToStream(source, fileStream);
|
||||
if (!saveOutcome.IsSuccess())
|
||||
{
|
||||
ScriptCanvasEditor::ScriptCanvasAssetHandler handler;
|
||||
tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream);
|
||||
saveError = saveOutcome.TakeError();
|
||||
}
|
||||
|
||||
fileStream.Close();
|
||||
}
|
||||
|
||||
if (!tempSavedSucceeded)
|
||||
if (!saveError.empty())
|
||||
{
|
||||
FileSaveResult result;
|
||||
result.fileSaveError = "Save asset data to temporary file failed";
|
||||
result.fileSaveError = AZStd::string::format("Save asset data to temporary file failed: %s", saveError.c_str());
|
||||
m_onComplete(result);
|
||||
return;
|
||||
}
|
||||
@@ -164,26 +174,26 @@ namespace ScriptCanvasEditor
|
||||
, fullPath.c_str()
|
||||
, true
|
||||
, [this, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info)
|
||||
{
|
||||
constexpr const size_t k_maxAttemps = 10;
|
||||
{
|
||||
constexpr const size_t k_maxAttemps = 10;
|
||||
|
||||
if (!info.IsReadOnly())
|
||||
{
|
||||
PerformMove(tmpFileName, fullPath, k_maxAttemps);
|
||||
}
|
||||
else if (m_onReadOnlyFile && m_onReadOnlyFile())
|
||||
{
|
||||
AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true);
|
||||
PerformMove(tmpFileName, fullPath, k_maxAttemps);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSaveResult result;
|
||||
result.fileSaveError = "Source file was and remained read-only";
|
||||
result.tempFileRemovalError = RemoveTempFile(tmpFileName);
|
||||
m_onComplete(result);
|
||||
}
|
||||
});
|
||||
if (!info.IsReadOnly())
|
||||
{
|
||||
PerformMove(tmpFileName, fullPath, k_maxAttemps);
|
||||
}
|
||||
else if (m_onReadOnlyFile && m_onReadOnlyFile())
|
||||
{
|
||||
AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true);
|
||||
PerformMove(tmpFileName, fullPath, k_maxAttemps);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSaveResult result;
|
||||
result.fileSaveError = "Source file was and remained read-only";
|
||||
result.tempFileRemovalError = RemoveTempFile(tmpFileName);
|
||||
m_onComplete(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AZStd::string FileSaver::RemoveTempFile(AZStd::string_view tempFile)
|
||||
@@ -191,7 +201,7 @@ namespace ScriptCanvasEditor
|
||||
AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance();
|
||||
if (!fileIO)
|
||||
{
|
||||
return "GraphUpgradeComplete: No FileIO instance";
|
||||
return "No FileIO instance";
|
||||
}
|
||||
|
||||
if (fileIO->Exists(tempFile.data()) && !fileIO->Remove(tempFile.data()))
|
||||
@@ -202,30 +212,30 @@ namespace ScriptCanvasEditor
|
||||
return "";
|
||||
}
|
||||
|
||||
void FileSaver::Save(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
void FileSaver::Save(const SourceHandle& source)
|
||||
{
|
||||
AZStd::string relativePath, fullPath;
|
||||
AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId());
|
||||
bool fullPathFound = false;
|
||||
AzToolsFramework::AssetSystemRequestBus::BroadcastResult
|
||||
(fullPathFound
|
||||
, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath
|
||||
, relativePath, fullPath);
|
||||
m_source = source;
|
||||
|
||||
if (!fullPathFound)
|
||||
if (source.Path().empty())
|
||||
{
|
||||
FileSaveResult result;
|
||||
result.fileSaveError = "Full source path not found";
|
||||
result.fileSaveError = "No save location specified";
|
||||
m_onComplete(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
|
||||
AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath);
|
||||
streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request)
|
||||
AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(source.Path().c_str());
|
||||
streamer->SetRequestCompleteCallback(flushRequest, [this]([[maybe_unused]] AZ::IO::FileRequestHandle request)
|
||||
{
|
||||
this->OnSourceFileReleased(asset);
|
||||
AZStd::lock_guard<AZStd::mutex> lock(m_mutex);
|
||||
if (!m_sourceFileReleased)
|
||||
{
|
||||
m_sourceFileReleased = true;
|
||||
AZ::SystemTickBus::QueueFunction([this]() { this->OnSourceFileReleased(m_source); });
|
||||
}
|
||||
});
|
||||
|
||||
streamer->QueueRequest(flushRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,19 @@ namespace ScriptCanvasEditor
|
||||
( AZStd::function<bool()> onReadOnlyFile
|
||||
, AZStd::function<void(const FileSaveResult& result)> onComplete);
|
||||
|
||||
void Save(AZ::Data::Asset<AZ::Data::AssetData> asset);
|
||||
const SourceHandle& GetSource() const;
|
||||
void Save(const SourceHandle& source);
|
||||
|
||||
private:
|
||||
AZStd::mutex m_mutex;
|
||||
|
||||
bool m_sourceFileReleased = false;
|
||||
SourceHandle m_source;
|
||||
AZStd::function<void(const FileSaveResult& result)> m_onComplete;
|
||||
AZStd::function<bool()> m_onReadOnlyFile;
|
||||
|
||||
void OnSourceFileReleased(AZ::Data::Asset<AZ::Data::AssetData> asset);
|
||||
|
||||
void OnSourceFileReleased(const SourceHandle& source);
|
||||
|
||||
void PerformMove
|
||||
( AZStd::string source
|
||||
, AZStd::string target
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace ScriptCanvasEditor
|
||||
return;
|
||||
}
|
||||
|
||||
if (modification.modifySingleAsset.m_assetId.IsValid())
|
||||
if (!modification.modifySingleAsset.Path().empty())
|
||||
{
|
||||
const auto& results = m_scanner->GetResult();
|
||||
auto iter = AZStd::find_if
|
||||
@@ -109,7 +109,7 @@ namespace ScriptCanvasEditor
|
||||
, results.m_unfiltered.end()
|
||||
, [&modification](const auto& candidate)
|
||||
{
|
||||
return candidate.info.m_assetId == modification.modifySingleAsset.m_assetId;
|
||||
return candidate.AnyEquals(modification.modifySingleAsset);
|
||||
});
|
||||
|
||||
if (iter == results.m_unfiltered.end())
|
||||
@@ -120,7 +120,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
|
||||
m_state = State::ModifySingle;
|
||||
m_modifier = AZStd::make_unique<Modifier>(modification, WorkingAssets{ *iter }, [this]() { OnModificationComplete(); });
|
||||
m_modifier = AZStd::make_unique<Modifier>(modification, AZStd::vector<SourceHandle>{ *iter }, [this]() { OnModificationComplete(); });
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -145,6 +145,7 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
|
||||
Idle();
|
||||
RestoreSettings();
|
||||
}
|
||||
|
||||
void Model::OnScanComplete()
|
||||
@@ -161,6 +162,7 @@ namespace ScriptCanvasEditor
|
||||
return;
|
||||
}
|
||||
|
||||
CacheSettings();
|
||||
m_state = State::Scanning;
|
||||
m_log.Activate();
|
||||
m_keepEditorAlive = AZStd::make_unique<EditorKeepAlive>();
|
||||
|
||||
@@ -9,53 +9,52 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
namespace VersionExplorer
|
||||
{
|
||||
struct WorkingAsset
|
||||
{
|
||||
AZ::Data::Asset<AZ::Data::AssetData> asset;
|
||||
AZ::Data::AssetInfo info;
|
||||
};
|
||||
|
||||
using WorkingAssets = AZStd::vector<WorkingAsset>;
|
||||
|
||||
struct ModifyConfiguration
|
||||
{
|
||||
AZStd::function<void(AZ::Data::Asset<AZ::Data::AssetData>)> modification;
|
||||
AZStd::function<void(SourceHandle&)> modification;
|
||||
AZStd::function<bool()> onReadOnlyFile;
|
||||
AZ::Data::AssetInfo modifySingleAsset;
|
||||
SourceHandle modifySingleAsset;
|
||||
bool backupGraphBeforeModification = false;
|
||||
bool successfulDependencyUpgradeRequired = true;
|
||||
AZ::s32 perDependencyWaitSecondsMax = 20;
|
||||
};
|
||||
|
||||
struct ModificationResult
|
||||
{
|
||||
AZ::Data::Asset<AZ::Data::AssetData> asset;
|
||||
AZ::Data::AssetInfo assetInfo;
|
||||
SourceHandle asset;
|
||||
AZStd::string errorMessage;
|
||||
};
|
||||
|
||||
struct ModificationResults
|
||||
{
|
||||
AZStd::vector<AZ::Data::AssetInfo> m_successes;
|
||||
AZStd::vector<SourceHandle> m_successes;
|
||||
AZStd::vector<ModificationResult> m_failures;
|
||||
};
|
||||
|
||||
struct ScanConfiguration
|
||||
{
|
||||
AZStd::function<bool(AZ::Data::Asset<AZ::Data::AssetData>)> filter;
|
||||
enum class Filter
|
||||
{
|
||||
Include,
|
||||
Exclude
|
||||
};
|
||||
|
||||
AZStd::function<Filter(const SourceHandle&)> filter;
|
||||
bool reportFilteredGraphs = false;
|
||||
};
|
||||
|
||||
struct ScanResult
|
||||
{
|
||||
AZStd::vector<AZ::Data::AssetInfo> m_catalogAssets;
|
||||
WorkingAssets m_unfiltered;
|
||||
AZStd::vector<AZ::Data::AssetInfo> m_filteredAssets;
|
||||
AZStd::vector<AZ::Data::AssetInfo> m_loadErrors;
|
||||
AZStd::vector<SourceHandle> m_catalogAssets;
|
||||
AZStd::vector<SourceHandle> m_unfiltered;
|
||||
AZStd::vector<SourceHandle> m_filteredAssets;
|
||||
AZStd::vector<SourceHandle> m_loadErrors;
|
||||
};
|
||||
|
||||
enum Result
|
||||
@@ -88,20 +87,21 @@ namespace ScriptCanvasEditor
|
||||
public:
|
||||
virtual void OnScanBegin(size_t assetCount) = 0;
|
||||
virtual void OnScanComplete(const ScanResult& result) = 0;
|
||||
virtual void OnScanFilteredGraph(const AZ::Data::AssetInfo& info) = 0;
|
||||
virtual void OnScanLoadFailure(const AZ::Data::AssetInfo& info) = 0;
|
||||
virtual void OnScanUnFilteredGraph(const AZ::Data::AssetInfo& info) = 0;
|
||||
virtual void OnScanFilteredGraph(const SourceHandle& info) = 0;
|
||||
virtual void OnScanLoadFailure(const SourceHandle& info) = 0;
|
||||
virtual void OnScanUnFilteredGraph(const SourceHandle& info) = 0;
|
||||
|
||||
virtual void OnUpgradeBegin(const ModifyConfiguration& config, const WorkingAssets& assets) = 0;
|
||||
virtual void OnUpgradeBegin(const ModifyConfiguration& config, const AZStd::vector<SourceHandle>& assets) = 0;
|
||||
virtual void OnUpgradeComplete(const ModificationResults& results) = 0;
|
||||
virtual void OnUpgradeDependenciesGathered(const AZ::Data::AssetInfo& info, Result result) = 0;
|
||||
virtual void OnUpgradeDependencySortBegin(const ModifyConfiguration& config, const WorkingAssets& assets) = 0;
|
||||
virtual void OnUpgradeDependenciesGathered(const SourceHandle& info, Result result) = 0;
|
||||
virtual void OnUpgradeDependencySortBegin(const ModifyConfiguration& config, const AZStd::vector<SourceHandle>& assets) = 0;
|
||||
virtual void OnUpgradeDependencySortEnd
|
||||
( const ModifyConfiguration& config
|
||||
, const WorkingAssets& assets
|
||||
, const AZStd::vector<SourceHandle>& assets
|
||||
, const AZStd::vector<size_t>& sortedOrder) = 0;
|
||||
virtual void OnUpgradeModificationBegin(const ModifyConfiguration& config, const AZ::Data::AssetInfo& info) = 0;
|
||||
virtual void OnUpgradeModificationEnd(const ModifyConfiguration& config, const AZ::Data::AssetInfo& info, ModificationResult result) = 0;
|
||||
virtual void OnUpgradeDependencyWaitInterval(const SourceHandle& info) = 0;
|
||||
virtual void OnUpgradeModificationBegin(const ModifyConfiguration& config, const SourceHandle& info) = 0;
|
||||
virtual void OnUpgradeModificationEnd(const ModifyConfiguration& config, const SourceHandle& info, ModificationResult result) = 0;
|
||||
};
|
||||
using ModelNotificationsBus = AZ::EBus<ModelNotificationsTraits>;
|
||||
}
|
||||
|
||||
@@ -6,24 +6,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Editor/Include/ScriptCanvas/Components/EditorGraph.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/LogTraits.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/Modifier.h>
|
||||
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
#include <ScriptCanvas/Core/Graph.h>
|
||||
|
||||
namespace ModifierCpp
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
namespace VersionExplorer
|
||||
{
|
||||
Modifier::Modifier
|
||||
( const ModifyConfiguration& modification
|
||||
, WorkingAssets&& assets
|
||||
, AZStd::vector<SourceHandle>&& assets
|
||||
, AZStd::function<void()> onComplete)
|
||||
: m_state(State::GatheringDependencies)
|
||||
, m_config(modification)
|
||||
@@ -33,46 +30,98 @@ namespace ScriptCanvasEditor
|
||||
AZ_Assert(m_config.modification, "No modification function provided");
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeBegin, modification, m_assets);
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
AzFramework::AssetSystemInfoBus::Handler::BusConnect();
|
||||
m_result.asset = m_assets[GetCurrentIndex()];
|
||||
}
|
||||
|
||||
const AZ::Data::AssetInfo& Modifier::GetCurrentAsset() const
|
||||
Modifier::~Modifier()
|
||||
{
|
||||
return m_state == State::GatheringDependencies
|
||||
? m_assets[m_assetIndex].info
|
||||
: m_assets[m_dependencyOrderedAssetIndicies[m_assetIndex]].info;
|
||||
AzFramework::AssetSystemInfoBus::Handler::BusDisconnect();
|
||||
}
|
||||
|
||||
AZStd::unordered_set<size_t>& Modifier::GetOrCreateDependencyIndexSet()
|
||||
bool Modifier::AllDependenciesCleared(const AZStd::unordered_set<size_t>& dependencies) const
|
||||
{
|
||||
auto iter = m_dependencies.find(m_assetIndex);
|
||||
if (iter == m_dependencies.end())
|
||||
for (auto index : dependencies)
|
||||
{
|
||||
iter = m_dependencies.insert_or_assign(m_assetIndex, AZStd::unordered_set<size_t>()).first;
|
||||
SourceHandle dependency = m_assets[index];
|
||||
CompleteDescriptionInPlace(dependency);
|
||||
|
||||
if (dependency.Id().IsNull() || !m_assetsCompletedByAP.contains(dependency.Id()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
const ModificationResults& Modifier::GetResult() const
|
||||
bool Modifier::AnyDependenciesFailed(const AZStd::unordered_set<size_t>& dependencies) const
|
||||
{
|
||||
return m_results;
|
||||
for (auto index : dependencies)
|
||||
{
|
||||
SourceHandle dependency = m_assets[index];
|
||||
CompleteDescriptionInPlace(dependency);
|
||||
|
||||
if (dependency.Id().IsNull() || m_assetsFailedByAP.contains(dependency.Id()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Modifier::AssetCompilationSuccess([[maybe_unused]] const AZStd::string& assetPath)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
m_successNotifications.insert(assetPath);
|
||||
}
|
||||
|
||||
void Modifier::AssetCompilationFailed(const AZStd::string& assetPath)
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
m_failureNotifications.insert(assetPath);
|
||||
}
|
||||
|
||||
AZStd::sys_time_t Modifier::CalculateRemainingWaitTime(const AZStd::unordered_set<size_t>& dependencies) const
|
||||
{
|
||||
auto maxSeconds = AZStd::chrono::seconds(dependencies.size() * m_config.perDependencyWaitSecondsMax);
|
||||
auto waitedSeconds = AZStd::chrono::seconds(AZStd::chrono::system_clock::now() - m_waitTimeStamp);
|
||||
return (maxSeconds - waitedSeconds).count();
|
||||
}
|
||||
|
||||
void Modifier::CheckDependencies()
|
||||
{
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeModificationBegin, m_config, m_result.asset);
|
||||
|
||||
if (auto dependencies = GetDependencies(GetCurrentIndex()); dependencies != nullptr && !dependencies->empty())
|
||||
{
|
||||
VE_LOG
|
||||
( "dependencies found for %s, update will wait for the AP to finish processing them"
|
||||
, m_result.asset.Path().c_str());
|
||||
|
||||
m_waitTimeStamp = AZStd::chrono::system_clock::now();
|
||||
m_waitLogTimeStamp = AZStd::chrono::system_clock::time_point{};
|
||||
m_modifyState = ModifyState::WaitingForDependencyProcessing;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_modifyState = ModifyState::StartModification;
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::GatherDependencies()
|
||||
{
|
||||
AZ::SerializeContext* serializeContext{};
|
||||
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
|
||||
AZ_Assert(serializeContext, "SerializeContext is required to enumerate dependent assets in the ScriptCanvas file");
|
||||
|
||||
LoadAsset();
|
||||
bool anyFailures = false;
|
||||
auto asset = LoadAsset();
|
||||
|
||||
if (asset
|
||||
&& asset.GetAs<ScriptCanvasAsset>()
|
||||
&& asset.GetAs<ScriptCanvasAsset>()->GetScriptCanvasGraph()
|
||||
&& asset.GetAs<ScriptCanvasAsset>()->GetScriptCanvasGraph()->GetGraphData())
|
||||
if (m_result.asset.Get() && m_result.asset.Mod()->GetGraphData())
|
||||
{
|
||||
auto graphData = asset.GetAs<ScriptCanvasAsset>()->GetScriptCanvasGraph()->GetGraphData();
|
||||
auto graphData = m_result.asset.Mod()->GetGraphData();
|
||||
|
||||
auto dependencyGrabber = [this]
|
||||
( void* instancePointer
|
||||
@@ -108,70 +157,101 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
anyFailures = true;
|
||||
VE_LOG("Modifier: ERROR - Failed to gather dependencies from graph data: %s"
|
||||
, GetCurrentAsset().m_relativePath.c_str())
|
||||
, m_result.asset.Path().c_str())
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
anyFailures = true;
|
||||
VE_LOG("Modifier: ERROR - Failed to load asset %s for modification, even though it scanned properly"
|
||||
, GetCurrentAsset().m_relativePath.c_str());
|
||||
, m_result.asset.Path().c_str());
|
||||
}
|
||||
|
||||
|
||||
ModelNotificationsBus::Broadcast
|
||||
( &ModelNotificationsTraits::OnUpgradeDependenciesGathered
|
||||
, GetCurrentAsset()
|
||||
, m_result.asset
|
||||
, anyFailures ? Result::Failure : Result::Success);
|
||||
|
||||
// Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
}
|
||||
|
||||
AZ::Data::Asset<AZ::Data::AssetData> Modifier::LoadAsset()
|
||||
size_t Modifier::GetCurrentIndex() const
|
||||
{
|
||||
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetManager::Instance().GetAsset
|
||||
( GetCurrentAsset().m_assetId
|
||||
, azrtti_typeid<ScriptCanvasAsset>()
|
||||
, AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
return m_state == State::GatheringDependencies
|
||||
? m_assetIndex
|
||||
: m_dependencyOrderedAssetIndicies[m_assetIndex];
|
||||
}
|
||||
|
||||
asset.BlockUntilLoadComplete();
|
||||
const AZStd::unordered_set<size_t>* Modifier::GetDependencies(size_t index) const
|
||||
{
|
||||
auto iter = m_dependencies.find(index);
|
||||
return iter != m_dependencies.end() ? &iter->second : nullptr;
|
||||
}
|
||||
|
||||
if (asset.IsReady())
|
||||
AZStd::unordered_set<size_t>& Modifier::GetOrCreateDependencyIndexSet()
|
||||
{
|
||||
auto iter = m_dependencies.find(m_assetIndex);
|
||||
if (iter == m_dependencies.end())
|
||||
{
|
||||
return asset;
|
||||
iter = m_dependencies.insert_or_assign(m_assetIndex, AZStd::unordered_set<size_t>()).first;
|
||||
}
|
||||
else
|
||||
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
const ModificationResults& Modifier::GetResult() const
|
||||
{
|
||||
return m_results;
|
||||
}
|
||||
|
||||
void Modifier::InitializeResult()
|
||||
{
|
||||
m_result = {};
|
||||
|
||||
if (m_assetIndex != m_assets.size())
|
||||
{
|
||||
return {};
|
||||
m_result.asset = m_assets[GetCurrentIndex()];
|
||||
CompleteDescriptionInPlace(m_result.asset);
|
||||
m_attemptedAssets.insert(m_result.asset.Id());
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::LoadAsset()
|
||||
{
|
||||
auto& handle = m_result.asset;
|
||||
if (!handle.IsGraphValid())
|
||||
{
|
||||
auto outcome = LoadFromFile(handle.Path().c_str());
|
||||
if (outcome.IsSuccess())
|
||||
{
|
||||
handle = outcome.TakeValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::ModificationComplete(const ModificationResult& result)
|
||||
{
|
||||
m_result = result;
|
||||
|
||||
if (result.errorMessage.empty())
|
||||
if (!result.errorMessage.empty())
|
||||
{
|
||||
SaveModifiedGraph(result);
|
||||
ReportModificationError(result.errorMessage);
|
||||
}
|
||||
else if (m_result.asset.Describe() != result.asset.Describe())
|
||||
{
|
||||
ReportModificationError("Received modification complete notification for different result");
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportModificationError(result.errorMessage);
|
||||
SaveModifiedGraph(result);
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::ModifyCurrentAsset()
|
||||
{
|
||||
m_result = {};
|
||||
m_result.assetInfo = GetCurrentAsset();
|
||||
LoadAsset();
|
||||
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeModificationBegin, m_config, GetCurrentAsset());
|
||||
|
||||
if (auto asset = LoadAsset())
|
||||
if (m_result.asset.IsGraphValid())
|
||||
{
|
||||
ModificationNotificationsBus::Handler::BusConnect();
|
||||
m_modifyState = ModifyState::InProgress;
|
||||
m_config.modification(asset);
|
||||
m_config.modification(m_result.asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -179,44 +259,17 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::ModifyNextAsset()
|
||||
void Modifier::NextAsset()
|
||||
{
|
||||
ModelNotificationsBus::Broadcast
|
||||
( &ModelNotificationsTraits::OnUpgradeModificationEnd, m_config, GetCurrentAsset(), m_result);
|
||||
ModificationNotificationsBus::Handler::BusDisconnect();
|
||||
m_modifyState = ModifyState::Idle;
|
||||
++m_assetIndex;
|
||||
m_result = {};
|
||||
InitializeResult();
|
||||
}
|
||||
|
||||
void Modifier::ReportModificationError(AZStd::string_view report)
|
||||
void Modifier::NextModification()
|
||||
{
|
||||
m_result.asset = {};
|
||||
m_result.errorMessage = report;
|
||||
m_results.m_failures.push_back(m_result);
|
||||
ModifyNextAsset();
|
||||
}
|
||||
|
||||
void Modifier::ReportModificationSuccess()
|
||||
{
|
||||
m_results.m_successes.push_back(m_result.assetInfo);
|
||||
ModifyNextAsset();
|
||||
}
|
||||
|
||||
void Modifier::ReportSaveResult()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
m_fileSaver.reset();
|
||||
|
||||
if (m_fileSaveResult.fileSaveError.empty())
|
||||
{
|
||||
ReportModificationSuccess();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportModificationError(m_fileSaveResult.fileSaveError);
|
||||
}
|
||||
|
||||
ModelNotificationsBus::Broadcast( &ModelNotificationsTraits::OnUpgradeModificationEnd, m_config, m_result.asset, m_result);
|
||||
ModificationNotificationsBus::Handler::BusDisconnect();
|
||||
NextAsset();
|
||||
m_fileSaveResult = {};
|
||||
m_modifyState = ModifyState::Idle;
|
||||
}
|
||||
@@ -226,8 +279,8 @@ namespace ScriptCanvasEditor
|
||||
if (!result.tempFileRemovalError.empty())
|
||||
{
|
||||
VE_LOG
|
||||
( "Temporary file not removed for %s: %s"
|
||||
, m_result.assetInfo.m_relativePath.c_str()
|
||||
("Temporary file not removed for %s: %s"
|
||||
, m_result.asset.Path().c_str()
|
||||
, result.tempFileRemovalError.c_str());
|
||||
}
|
||||
|
||||
@@ -254,12 +307,84 @@ namespace ScriptCanvasEditor
|
||||
AZ::SystemTickBus::ExecuteQueuedEvents();
|
||||
}
|
||||
|
||||
void Modifier::ProcessNotifications()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
|
||||
for (const auto& assetPath : m_successNotifications)
|
||||
{
|
||||
VE_LOG("received AssetCompilationSuccess: %s", assetPath.c_str());
|
||||
SourceHandle sourceHandle(nullptr, {}, assetPath.c_str());
|
||||
CompleteDescriptionInPlace(sourceHandle);
|
||||
|
||||
if (m_attemptedAssets.contains(sourceHandle.Id()))
|
||||
{
|
||||
m_assetsCompletedByAP.insert(sourceHandle.Id());
|
||||
}
|
||||
}
|
||||
|
||||
m_successNotifications.clear();
|
||||
|
||||
for (const auto& assetPath : m_failureNotifications)
|
||||
{
|
||||
VE_LOG("received AssetCompilationFailed: %s", assetPath.c_str());
|
||||
SourceHandle sourceHandle(nullptr, {}, assetPath.c_str());
|
||||
CompleteDescriptionInPlace(sourceHandle);
|
||||
|
||||
if (m_attemptedAssets.contains(sourceHandle.Id()))
|
||||
{
|
||||
m_assetsFailedByAP.insert(sourceHandle.Id());
|
||||
}
|
||||
}
|
||||
|
||||
m_failureNotifications.clear();
|
||||
}
|
||||
|
||||
void Modifier::ReleaseCurrentAsset()
|
||||
{
|
||||
m_result.asset = m_result.asset.Describe();
|
||||
// Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
|
||||
AZ::Data::AssetManager::Instance().DispatchEvents();
|
||||
}
|
||||
|
||||
void Modifier::ReportModificationError(AZStd::string_view report)
|
||||
{
|
||||
m_result.errorMessage = report;
|
||||
m_results.m_failures.push_back({ m_result.asset.Describe(), report });
|
||||
m_assetsFailedByAP.insert(m_result.asset.Id());
|
||||
NextModification();
|
||||
}
|
||||
|
||||
void Modifier::ReportModificationSuccess()
|
||||
{
|
||||
// \note DO NOT put asset into the m_assetsCompletedByAP here. That can only be done when the message is received by the AP
|
||||
m_results.m_successes.push_back({ m_result.asset.Describe(), {} });
|
||||
AzFramework::AssetSystemRequestBus::Broadcast(
|
||||
&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetByUuid, m_result.asset.Id());
|
||||
NextModification();
|
||||
}
|
||||
|
||||
void Modifier::ReportSaveResult()
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
m_fileSaver.reset();
|
||||
|
||||
if (m_fileSaveResult.fileSaveError.empty())
|
||||
{
|
||||
ReportModificationSuccess();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportModificationError(m_fileSaveResult.fileSaveError);
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::SaveModifiedGraph(const ModificationResult& result)
|
||||
{
|
||||
m_modifyState = ModifyState::Saving;
|
||||
m_fileSaver = AZStd::make_unique<FileSaver>
|
||||
( m_config.onReadOnlyFile
|
||||
, [this](const FileSaveResult& result) { OnFileSaveComplete(result); });
|
||||
, [this](const FileSaveResult& fileSaveResult) { OnFileSaveComplete(fileSaveResult); });
|
||||
m_fileSaver->Save(result.asset);
|
||||
}
|
||||
|
||||
@@ -287,7 +412,7 @@ namespace ScriptCanvasEditor
|
||||
|
||||
for (size_t index = 0; index != m_assets.size(); ++index)
|
||||
{
|
||||
m_assetInfoIndexById.insert({ m_assets[index].info.m_assetId.m_guid, index });
|
||||
m_assetInfoIndexById.insert({ m_assets[index].Id(), index });
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -299,7 +424,7 @@ namespace ScriptCanvasEditor
|
||||
m_dependencyOrderedAssetIndicies.push_back(index);
|
||||
}
|
||||
|
||||
// go straight into ModifyinGraphs
|
||||
// go straight into ModifyingGraphs
|
||||
m_assetIndex = m_assets.size();
|
||||
}
|
||||
}
|
||||
@@ -318,48 +443,87 @@ namespace ScriptCanvasEditor
|
||||
|
||||
m_assetIndex = 0;
|
||||
m_state = State::ModifyingGraphs;
|
||||
InitializeResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
GatherDependencies();
|
||||
++m_assetIndex;
|
||||
NextAsset();
|
||||
}
|
||||
}
|
||||
|
||||
void Modifier::TickUpdateGraph()
|
||||
{
|
||||
if (m_assetIndex == m_assets.size())
|
||||
{
|
||||
VE_LOG("Modifier: Complete.");
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
|
||||
if (m_onComplete)
|
||||
switch (m_modifyState)
|
||||
{
|
||||
case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::Idle:
|
||||
if (m_assetIndex == m_assets.size())
|
||||
{
|
||||
m_onComplete();
|
||||
VE_LOG("Modifier: Complete.");
|
||||
AZ::SystemTickBus::Handler::BusDisconnect();
|
||||
|
||||
if (m_onComplete)
|
||||
{
|
||||
m_onComplete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckDependencies();
|
||||
}
|
||||
break;
|
||||
case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::WaitingForDependencyProcessing:
|
||||
WaitForDependencies();
|
||||
break;
|
||||
case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::StartModification:
|
||||
ModifyCurrentAsset();
|
||||
break;
|
||||
case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::ReportResult:
|
||||
ReportSaveResult();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
|
||||
}
|
||||
|
||||
switch (m_modifyState)
|
||||
{
|
||||
case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::Idle:
|
||||
ModifyCurrentAsset();
|
||||
break;
|
||||
case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::ReportResult:
|
||||
ReportSaveResult();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
void Modifier::WaitForDependencies()
|
||||
{
|
||||
const AZ::s32 LogPeriodSeconds = 5;
|
||||
|
||||
ProcessNotifications();
|
||||
|
||||
auto dependencies = GetDependencies(GetCurrentIndex());
|
||||
if (dependencies == nullptr || dependencies->empty() || AllDependenciesCleared(*dependencies))
|
||||
{
|
||||
m_modifyState = ModifyState::StartModification;
|
||||
}
|
||||
else if (AnyDependenciesFailed(*dependencies))
|
||||
{
|
||||
ReportModificationError("A required dependency failed to update, graph cannot update.");
|
||||
}
|
||||
else if (AZStd::chrono::seconds(CalculateRemainingWaitTime(*dependencies)).count() < 0)
|
||||
{
|
||||
ReportModificationError("Dependency update time has taken too long, aborting modification.");
|
||||
}
|
||||
else if (AZStd::chrono::seconds(AZStd::chrono::system_clock::now() - m_waitLogTimeStamp).count() > LogPeriodSeconds)
|
||||
{
|
||||
m_waitLogTimeStamp = AZStd::chrono::system_clock::now();
|
||||
|
||||
AZ_TracePrintf
|
||||
( ScriptCanvas::k_VersionExplorerWindow.data()
|
||||
, "Waiting for dependencies for %d more seconds: %s"
|
||||
, AZStd::chrono::seconds(CalculateRemainingWaitTime(*dependencies)).count()
|
||||
, m_result.asset.Path().c_str());
|
||||
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeDependencyWaitInterval, m_result.asset);
|
||||
}
|
||||
}
|
||||
|
||||
const AZStd::unordered_set<size_t>* Modifier::Sorter::GetDependencies(size_t index) const
|
||||
{
|
||||
auto iter = modifier->m_dependencies.find(index);
|
||||
return iter != modifier->m_dependencies.end() ? &iter->second : nullptr;
|
||||
return modifier->GetDependencies(index);
|
||||
}
|
||||
|
||||
void Modifier::Sorter::Sort()
|
||||
@@ -380,10 +544,10 @@ namespace ScriptCanvasEditor
|
||||
if (markedTemporary.contains(index))
|
||||
{
|
||||
AZ_Error
|
||||
(ScriptCanvas::k_VersionExplorerWindow.data()
|
||||
( ScriptCanvas::k_VersionExplorerWindow.data()
|
||||
, false
|
||||
, "Modifier: Dependency sort has failed during, circular dependency detected for Asset: %s"
|
||||
, modifier->GetCurrentAsset().m_relativePath.c_str());
|
||||
, modifier->m_result.asset.Path().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/TickBus.h>
|
||||
#include <AzFramework/Asset/AssetSystemBus.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/FileSaver.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h>
|
||||
#include <ScriptCanvas/Core/Core.h>
|
||||
@@ -17,18 +18,21 @@ namespace ScriptCanvasEditor
|
||||
{
|
||||
namespace VersionExplorer
|
||||
{
|
||||
class Modifier
|
||||
: private AZ::SystemTickBus::Handler
|
||||
, private ModificationNotificationsBus::Handler
|
||||
class Modifier final
|
||||
: public AZ::SystemTickBus::Handler
|
||||
, public ModificationNotificationsBus::Handler
|
||||
, public AzFramework::AssetSystemInfoBus::Handler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(Modifier, AZ::SystemAllocator, 0);
|
||||
|
||||
Modifier
|
||||
( const ModifyConfiguration& modification
|
||||
, WorkingAssets&& assets
|
||||
, AZStd::vector<SourceHandle>&& assets
|
||||
, AZStd::function<void()> onComplete);
|
||||
|
||||
~Modifier();
|
||||
|
||||
const ModificationResults& GetResult() const;
|
||||
ModificationResults&& TakeResult();
|
||||
|
||||
@@ -56,6 +60,8 @@ namespace ScriptCanvasEditor
|
||||
enum class ModifyState
|
||||
{
|
||||
Idle,
|
||||
WaitingForDependencyProcessing,
|
||||
StartModification,
|
||||
InProgress,
|
||||
Saving,
|
||||
ReportResult
|
||||
@@ -67,37 +73,58 @@ namespace ScriptCanvasEditor
|
||||
State m_state = State::GatheringDependencies;
|
||||
ModifyState m_modifyState = ModifyState::Idle;
|
||||
size_t m_assetIndex = 0;
|
||||
|
||||
AZStd::function<void()> m_onComplete;
|
||||
// asset infos in scanned order
|
||||
WorkingAssets m_assets;
|
||||
AZStd::vector<SourceHandle> m_assets;
|
||||
// dependency sorted order indices into the asset vector
|
||||
AZStd::vector<size_t> m_dependencyOrderedAssetIndicies;
|
||||
// dependency indices by asset info index (only exist if graphs have them)
|
||||
AZStd::unordered_map<size_t, AZStd::unordered_set<size_t>> m_dependencies;
|
||||
AZStd::unordered_map<AZ::Uuid, size_t> m_assetInfoIndexById;
|
||||
AZStd::vector<size_t> m_failures;
|
||||
ModifyConfiguration m_config;
|
||||
ModificationResult m_result;
|
||||
ModificationResults m_results;
|
||||
AZStd::unique_ptr<FileSaver> m_fileSaver;
|
||||
FileSaveResult m_fileSaveResult;
|
||||
// m_attemptedAssets is assets attempted to be processed by modification, as opposed to
|
||||
// those processed by the AP as a result of one of their dependencies being processed.
|
||||
AZStd::unordered_set<AZ::Uuid> m_attemptedAssets;
|
||||
AZStd::unordered_set<AZ::Uuid> m_assetsCompletedByAP;
|
||||
AZStd::unordered_set<AZ::Uuid> m_assetsFailedByAP;
|
||||
AZStd::chrono::system_clock::time_point m_waitLogTimeStamp;
|
||||
AZStd::chrono::system_clock::time_point m_waitTimeStamp;
|
||||
AZStd::unordered_set<AZStd::string> m_successNotifications;
|
||||
AZStd::unordered_set<AZStd::string> m_failureNotifications;
|
||||
|
||||
bool AllDependenciesCleared(const AZStd::unordered_set<size_t>& dependencies) const;
|
||||
bool AnyDependenciesFailed(const AZStd::unordered_set<size_t>& dependencies) const;
|
||||
void AssetCompilationSuccess(const AZStd::string& assetPath) override;
|
||||
void AssetCompilationFailed(const AZStd::string& assetPath) override;
|
||||
AZStd::sys_time_t CalculateRemainingWaitTime(const AZStd::unordered_set<size_t>& dependencies) const;
|
||||
void CheckDependencies();
|
||||
void GatherDependencies();
|
||||
const AZ::Data::AssetInfo& GetCurrentAsset() const;
|
||||
size_t GetCurrentIndex() const;
|
||||
const AZStd::unordered_set<size_t>* GetDependencies(size_t index) const;
|
||||
AZStd::unordered_set<size_t>& GetOrCreateDependencyIndexSet();
|
||||
AZ::Data::Asset<AZ::Data::AssetData> LoadAsset();
|
||||
void ModifyCurrentAsset();
|
||||
void ModifyNextAsset();
|
||||
void InitializeResult();
|
||||
void LoadAsset();
|
||||
void ModificationComplete(const ModificationResult& result) override;
|
||||
void ModifyCurrentAsset();
|
||||
void NextAsset();
|
||||
void NextModification();
|
||||
void OnFileSaveComplete(const FileSaveResult& result);
|
||||
void OnSystemTick() override;
|
||||
void ProcessNotifications();
|
||||
void ReleaseCurrentAsset();
|
||||
void ReportModificationError(AZStd::string_view report);
|
||||
void ReportModificationSuccess();
|
||||
void ReportSaveResult();
|
||||
void SaveModifiedGraph(const ModificationResult& result);
|
||||
void SortGraphsByDependencies();
|
||||
void OnFileSaveComplete(const FileSaveResult& result);
|
||||
void OnSystemTick() override;
|
||||
void TickGatherDependencies();
|
||||
void TickUpdateGraph();
|
||||
void WaitForDependencies();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,49 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserEntry.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
|
||||
#include <AzToolsFramework/AssetBrowser/AssetBrowserModel.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/LogTraits.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/Scanner.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasAsset.h>
|
||||
#include <Editor/View/Windows/Tools/UpgradeTool/LogTraits.h>
|
||||
#include <ScriptCanvas/Assets/ScriptCanvasFileHandling.h>
|
||||
|
||||
namespace ScannerCpp
|
||||
{
|
||||
void TraverseTree
|
||||
( QModelIndex index
|
||||
, AzToolsFramework::AssetBrowser::AssetBrowserFilterModel& model
|
||||
, ScriptCanvasEditor::VersionExplorer::ScanResult& result)
|
||||
{
|
||||
QModelIndex sourceIndex = model.mapToSource(index);
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserEntry* entry =
|
||||
reinterpret_cast<AzToolsFramework::AssetBrowser::AssetBrowserEntry*>(sourceIndex.internalPointer());
|
||||
|
||||
if (entry
|
||||
&& entry->GetEntryType() == AzToolsFramework::AssetBrowser::AssetBrowserEntry::AssetEntryType::Source
|
||||
&& azrtti_istypeof<const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry*>(entry)
|
||||
&& entry->GetFullPath().ends_with(".scriptcanvas"))
|
||||
{
|
||||
auto sourceEntry = azrtti_cast<const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry*>(entry);
|
||||
|
||||
AZStd::string fullPath = sourceEntry->GetFullPath();
|
||||
AzFramework::StringFunc::Path::Normalize(fullPath);
|
||||
|
||||
result.m_catalogAssets.push_back(
|
||||
ScriptCanvasEditor::SourceHandle(nullptr, sourceEntry->GetSourceUuid(), fullPath));
|
||||
}
|
||||
|
||||
const int rowCount = model.rowCount(index);
|
||||
|
||||
for (int i = 0; i < rowCount; ++i)
|
||||
{
|
||||
TraverseTree(model.index(i, 0, index), model, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace ScriptCanvasEditor
|
||||
{
|
||||
@@ -18,60 +58,54 @@ namespace ScriptCanvasEditor
|
||||
: m_config(config)
|
||||
, m_onComplete(onComplete)
|
||||
{
|
||||
AZ::Data::AssetCatalogRequestBus::Broadcast
|
||||
( &AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets
|
||||
, nullptr
|
||||
, [this](const AZ::Data::AssetId, const AZ::Data::AssetInfo& assetInfo)
|
||||
{
|
||||
if (assetInfo.m_assetType == azrtti_typeid<ScriptCanvasAsset>())
|
||||
{
|
||||
m_result.m_catalogAssets.push_back(assetInfo);
|
||||
}
|
||||
}
|
||||
, nullptr);
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserModel* assetBrowserModel = nullptr;
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserComponentRequestBus::BroadcastResult
|
||||
( assetBrowserModel, &AzToolsFramework::AssetBrowser::AssetBrowserComponentRequests::GetAssetBrowserModel);
|
||||
|
||||
if (assetBrowserModel)
|
||||
{
|
||||
auto stringFilter = new AzToolsFramework::AssetBrowser::StringFilter();
|
||||
stringFilter->SetName("ScriptCanvas");
|
||||
stringFilter->SetFilterString(".scriptcanvas");
|
||||
stringFilter->SetFilterPropagation(AzToolsFramework::AssetBrowser::AssetBrowserEntryFilter::PropagateDirection::Down);
|
||||
|
||||
AzToolsFramework::AssetBrowser::AssetBrowserFilterModel assetFilterModel;
|
||||
assetFilterModel.SetFilter(AzToolsFramework::AssetBrowser::FilterConstType(stringFilter));
|
||||
assetFilterModel.setSourceModel(assetBrowserModel);
|
||||
|
||||
ScannerCpp::TraverseTree(QModelIndex(), assetFilterModel, m_result);
|
||||
}
|
||||
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanBegin, m_result.m_catalogAssets.size());
|
||||
AZ::SystemTickBus::Handler::BusConnect();
|
||||
}
|
||||
|
||||
void Scanner::FilterAsset(AZ::Data::Asset<AZ::Data::AssetData> asset)
|
||||
void Scanner::FilterAsset(SourceHandle asset)
|
||||
{
|
||||
if (m_config.filter && m_config.filter(asset))
|
||||
if (m_config.filter && m_config.filter(asset) == ScanConfiguration::Filter::Exclude)
|
||||
{
|
||||
VE_LOG("Scanner: Excluded: %s ", GetCurrentAsset().m_relativePath.c_str());
|
||||
m_result.m_filteredAssets.push_back(GetCurrentAsset());
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanFilteredGraph, GetCurrentAsset());
|
||||
VE_LOG("Scanner: Excluded: %s ", ModCurrentAsset().Path().c_str());
|
||||
m_result.m_filteredAssets.push_back(ModCurrentAsset().Describe());
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanFilteredGraph, ModCurrentAsset());
|
||||
}
|
||||
else
|
||||
{
|
||||
VE_LOG("Scanner: Included: %s ", GetCurrentAsset().m_relativePath.c_str());
|
||||
m_result.m_unfiltered.push_back({ asset, GetCurrentAsset() });
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanUnFilteredGraph, GetCurrentAsset());
|
||||
VE_LOG("Scanner: Included: %s ", ModCurrentAsset().Path().c_str());
|
||||
m_result.m_unfiltered.push_back(ModCurrentAsset().Describe());
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanUnFilteredGraph, ModCurrentAsset());
|
||||
}
|
||||
}
|
||||
|
||||
const AZ::Data::AssetInfo& Scanner::GetCurrentAsset() const
|
||||
{
|
||||
return m_result.m_catalogAssets[m_catalogAssetIndex];
|
||||
}
|
||||
|
||||
const ScanResult& Scanner::GetResult() const
|
||||
{
|
||||
return m_result;
|
||||
}
|
||||
|
||||
AZ::Data::Asset<AZ::Data::AssetData> Scanner::LoadAsset()
|
||||
SourceHandle Scanner::LoadAsset()
|
||||
{
|
||||
AZ::Data::Asset<AZ::Data::AssetData> asset = AZ::Data::AssetManager::Instance().GetAsset
|
||||
( GetCurrentAsset().m_assetId
|
||||
, azrtti_typeid<ScriptCanvasAsset>()
|
||||
, AZ::Data::AssetLoadBehavior::PreLoad);
|
||||
|
||||
asset.BlockUntilLoadComplete();
|
||||
|
||||
if (asset.IsReady())
|
||||
auto fileOutcome = LoadFromFile(ModCurrentAsset().Path().c_str());
|
||||
if (fileOutcome.IsSuccess())
|
||||
{
|
||||
return asset;
|
||||
return fileOutcome.GetValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -79,6 +113,11 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
SourceHandle& Scanner::ModCurrentAsset()
|
||||
{
|
||||
return m_result.m_catalogAssets[m_catalogAssetIndex];
|
||||
}
|
||||
|
||||
void Scanner::OnSystemTick()
|
||||
{
|
||||
if (m_catalogAssetIndex == m_result.m_catalogAssets.size())
|
||||
@@ -93,19 +132,19 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
else
|
||||
{
|
||||
if (auto asset = LoadAsset())
|
||||
if (auto asset = LoadAsset(); asset.IsGraphValid())
|
||||
{
|
||||
VE_LOG("Scanner: Loaded: %s ", GetCurrentAsset().m_relativePath.c_str());
|
||||
VE_LOG("Scanner: Loaded: %s ", ModCurrentAsset().Path().c_str());
|
||||
FilterAsset(asset);
|
||||
}
|
||||
else
|
||||
{
|
||||
VE_LOG("Scanner: Failed to load: %s ", GetCurrentAsset().m_relativePath.c_str());
|
||||
m_result.m_loadErrors.push_back(GetCurrentAsset());
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanLoadFailure, GetCurrentAsset());
|
||||
VE_LOG("Scanner: Failed to load: %s ", ModCurrentAsset().Path().c_str());
|
||||
m_result.m_loadErrors.push_back(ModCurrentAsset().Describe());
|
||||
ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnScanLoadFailure, ModCurrentAsset());
|
||||
}
|
||||
|
||||
VE_LOG("Scanner: scan of %s complete", GetCurrentAsset().m_relativePath.c_str());
|
||||
VE_LOG("Scanner: scan of %s complete", ModCurrentAsset().Path().c_str());
|
||||
++m_catalogAssetIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ namespace ScriptCanvasEditor
|
||||
ScanConfiguration m_config;
|
||||
ScanResult m_result;
|
||||
|
||||
void FilterAsset(AZ::Data::Asset<AZ::Data::AssetData>);
|
||||
const AZ::Data::AssetInfo& GetCurrentAsset() const;
|
||||
AZ::Data::Asset<AZ::Data::AssetData> LoadAsset();
|
||||
void FilterAsset(SourceHandle);
|
||||
SourceHandle LoadAsset();
|
||||
SourceHandle& ModCurrentAsset();
|
||||
void OnSystemTick() override;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,26 +55,25 @@ namespace ScriptCanvasEditor
|
||||
|
||||
for (auto& failedUpdate : result->m_failures)
|
||||
{
|
||||
auto& assetInfo = failedUpdate.assetInfo;
|
||||
auto assetId = assetInfo.m_assetId;
|
||||
|
||||
auto asset = failedUpdate.asset;
|
||||
|
||||
m_ui->tableWidget->insertRow(rows);
|
||||
|
||||
connect(m_ui->closeButton, &QPushButton::pressed, this, &QDialog::accept);
|
||||
connect(m_ui->tableWidget, &QTableWidget::itemDoubleClicked, this, [this, rows, assetId](QTableWidgetItem* item)
|
||||
connect(m_ui->tableWidget, &QTableWidget::itemDoubleClicked, this, [this, rows, asset](QTableWidgetItem* item)
|
||||
{
|
||||
if (item && item->data(Qt::UserRole).toInt() == rows)
|
||||
{
|
||||
OpenGraph(assetId);
|
||||
OpenGraph(asset);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
auto openGraph = [this, assetId] {
|
||||
OpenGraph(assetId);
|
||||
auto openGraph = [this, asset] {
|
||||
OpenGraph(asset);
|
||||
};
|
||||
|
||||
QTableWidgetItem* rowName = new QTableWidgetItem(tr(assetInfo.m_relativePath.c_str()));
|
||||
QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.Path().c_str()));
|
||||
rowName->setData(Qt::UserRole, rows);
|
||||
m_ui->tableWidget->setItem(rows, 0, rowName);
|
||||
|
||||
@@ -91,15 +90,15 @@ namespace ScriptCanvasEditor
|
||||
}
|
||||
}
|
||||
|
||||
void UpgradeHelper::OpenGraph(AZ::Data::AssetId assetId)
|
||||
void UpgradeHelper::OpenGraph(const SourceHandle& asset)
|
||||
{
|
||||
// Open the graph in SC editor
|
||||
AzToolsFramework::OpenViewPane(/*LyViewPane::ScriptCanvas*/"Script Canvas");
|
||||
AZ::Outcome<int, AZStd::string> openOutcome = AZ::Failure(AZStd::string());
|
||||
|
||||
if (assetId.IsValid())
|
||||
if (!asset.Path().empty())
|
||||
{
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, assetId, -1);
|
||||
GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, asset, Tracker::ScriptCanvasFileState::UNMODIFIED, -1);
|
||||
}
|
||||
|
||||
if (!openOutcome)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user