/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include "precompiled.h" #include "ScriptEventsSystemEditorComponent.h" #include #include #include #include #include #include #include #if defined(SCRIPTEVENTS_EDITOR) namespace ScriptEventsEditor { //////////////////////////// // ScriptEventAssetHandler //////////////////////////// ScriptEventAssetHandler::ScriptEventAssetHandler(const char* displayName, const char* group, const char* extension, const AZ::Uuid& componentTypeId, AZ::SerializeContext* serializeContext) : AzFramework::GenericAssetHandler(displayName, group, extension, componentTypeId, serializeContext) { } AZ::Data::AssetPtr ScriptEventAssetHandler::CreateAsset(const AZ::Data::AssetId& id, const AZ::Data::AssetType& type) { if (type != azrtti_typeid()) { return nullptr; } AZ::Data::AssetPtr assetPtr = AzFramework::GenericAssetHandler::CreateAsset(id, type); if (!AzToolsFramework::AssetEditor::AssetEditorValidationRequestBus::MultiHandler::BusIsConnectedId(id)) { AzToolsFramework::AssetEditor::AssetEditorValidationRequestBus::MultiHandler::BusConnect(id); } return assetPtr; } bool ScriptEventAssetHandler::LoadAssetData(const AZ::Data::Asset& asset, const char* assetPath, const AZ::Data::AssetFilterCB& assetLoadFilterCB) { bool loadedData = AzFramework::GenericAssetHandler::LoadAssetData(asset, assetPath, assetLoadFilterCB); if (loadedData) { ScriptEvents::ScriptEventsAsset* assetData = asset.GetAs(); if (assetData) { auto busIter = m_previousEbusNames.find(asset.GetId()); bool registerBus = true; if (busIter != m_previousEbusNames.end()) { if (busIter->second.m_version < assetData->m_definition.GetVersion()) { ScriptEvents::Internal::Utils::DestroyScriptEventBehaviorEBus(busIter->second.m_previousName); m_previousEbusNames.erase(busIter); } else { registerBus = false; } } if (registerBus) { // LoadAssetData is being called from an Asset system thread, // we need to complete registering with the BehaviorContext in the main thread auto registerBusFn = [this, assetData, asset]() { if (ScriptEvents::Internal::Utils::ConstructAndRegisterScriptEventBehaviorEBus(assetData->m_definition)) { PreviousNameSettings previousSettings; previousSettings.m_previousName = assetData->m_definition.GetName().c_str(); previousSettings.m_version = assetData->m_definition.GetVersion(); m_previousEbusNames[asset.GetId()] = previousSettings; } }; AZ::TickBus::QueueFunction(registerBusFn); } } } return loadedData; } bool ScriptEventAssetHandler::SaveAssetData(const AZ::Data::Asset& asset, AZ::IO::GenericStream* stream) { AZ_TracePrintf("ScriptEvent", "Trying to save Asset with ID: %s - SCRIPTEVENT", asset.Get()->GetId().ToString().c_str()); // Attempt to Save the data to a temporary stream in order to see if any AZ::Outcome outcome = AZ::Failure(AZStd::string::format("AssetEditorValidationRequests is not connected ID: %s", asset.Get()->GetId().ToString().c_str())); // Verify that the asset is in a valid state that can be saved. AzToolsFramework::AssetEditor::AssetEditorValidationRequestBus::EventResult(outcome, asset.Get()->GetId(), &AzToolsFramework::AssetEditor::AssetEditorValidationRequests::IsAssetDataValid, asset); if (!outcome.IsSuccess()) { AZ_Error("Asset Editor", false, "%s", outcome.GetError().c_str()); return false; } ScriptEvents::ScriptEventsAsset* assetData = asset.GetAs(); AZ_Assert(assetData, "Asset is of the wrong type."); if (assetData && m_serializeContext) { return AZ::Utils::SaveObjectToStream(*stream, m_saveAsBinary ? AZ::ObjectStream::ST_BINARY : AZ::ObjectStream::ST_XML, assetData, m_serializeContext); } return false; } AZ::Outcome ScriptEventAssetHandler::IsAssetDataValid(const AZ::Data::Asset& asset) { ScriptEvents::ScriptEventsAsset* assetData = asset.GetAs(); if (!assetData) { return AZ::Failure(AZStd::string::format("Unable to validate asset with id: %s it has not been registered with the Script Event system component.", asset.GetId().ToString().c_str())); } const ScriptEvents::ScriptEvent* definition = &assetData->m_definition; AZ_Assert(definition, "The AssetData should have a valid definition"); return definition->Validate(); } void ScriptEventAssetHandler::PreAssetSave(AZ::Data::Asset asset) { ScriptEvents::ScriptEventsAsset* scriptEventAsset = asset.GetAs(); scriptEventAsset->m_definition.IncreaseVersion(); } void ScriptEventAssetHandler::BeforePropertyEdit(AzToolsFramework::InstanceDataNode* node, AZ::Data::Asset asset) { ScriptEventData::VersionedProperty* property = nullptr; AzToolsFramework::InstanceDataNode* parent = node; while (parent) { if (parent->GetClassMetadata()->m_typeId == azrtti_typeid()) { property = static_cast(parent->GetInstance(0)); break; } parent = parent->GetParent(); } if (property) { property->OnPropertyChange(); } } void ScriptEventEditorSystemComponent::Reflect(AZ::ReflectContext* context) { if (AZ::SerializeContext* serialize = azrtti_cast(context)) { serialize->Class() ->Version(3) ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AZ_CRC("AssetBuilder", 0xc739c7d7) })); ; } using namespace ScriptEvents; ScriptEventData::VersionedProperty::Reflect(context); Parameter::Reflect(context); Method::Reflect(context); ScriptEvent::Reflect(context); ScriptEventsAsset::Reflect(context); ScriptEventsAssetRef::Reflect(context); ScriptEventsAssetPtr::Reflect(context); } void ScriptEventEditorSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC("ScriptEventsService", 0x6897c23b)); } void ScriptEventEditorSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) { incompatible.push_back(AZ_CRC("ScriptEventsService", 0x6897c23b)); } //////////////////// // SystemComponent //////////////////// void ScriptEventEditorSystemComponent::Activate() { using namespace ScriptEvents; ScriptEventsSystemComponentImpl* moduleConfiguration = nullptr; ScriptEventModuleConfigurationRequestBus::BroadcastResult(moduleConfiguration, &ScriptEventModuleConfigurationRequests::GetSystemComponentImpl); if (moduleConfiguration) { moduleConfiguration->RegisterAssetHandler(); } m_propertyHandlers.emplace_back(AzToolsFramework::RegisterGenericComboBoxHandler()); } void ScriptEventEditorSystemComponent::Deactivate() { for (auto&& propertyHandler : m_propertyHandlers) { AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::UnregisterPropertyType, propertyHandler.get()); } m_propertyHandlers.clear(); using namespace ScriptEvents; ScriptEventsSystemComponentImpl* moduleConfiguration = nullptr; ScriptEventModuleConfigurationRequestBus::BroadcastResult(moduleConfiguration, &ScriptEventModuleConfigurationRequests::GetSystemComponentImpl); if (moduleConfiguration) { moduleConfiguration->UnregisterAssetHandler(); } } } #endif