Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
# Python Asset Builder
This gem is meant to run Python scripts that want to run as asset builders in the Lumberyard asset processing system.
@@ -0,0 +1,3 @@
{
"test": true
}
+13
View File
@@ -0,0 +1,13 @@
#
# 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.
#
ly_add_external_target_path(${CMAKE_CURRENT_LIST_DIR}/3rdParty)
add_subdirectory(Code)
@@ -0,0 +1,94 @@
#
# 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.
#
if(NOT PAL_TRAIT_BUILD_HOST_TOOLS)
return()
endif()
set(static_files pythonassetbuilder_common_files.cmake)
set(editor_files pythonassetbuilder_editor_files.cmake)
set(shared_files pythonassetbuilder_shared_files.cmake)
set(static_dependencies
3rdParty::Python
Gem::EditorPythonBindings.Static
AZ::AssetBuilderSDK
)
set(editor_dependencies
Gem::EditorPythonBindings.Static
AZ::AssetBuilderSDK
)
ly_add_target(
NAME PythonAssetBuilder.Static STATIC
NAMESPACE Gem
FILES_CMAKE
${static_files}
PLATFORM_INCLUDE_FILES
Source/Platform/Common/${PAL_TRAIT_COMPILER_ID}/pythonassetbuilder_static_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
Source
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
PUBLIC
${static_dependencies}
AZ::AzToolsFramework
)
ly_add_target(
NAME PythonAssetBuilder.Editor MODULE
NAMESPACE Gem
OUTPUT_NAME Gem.PythonAssetBuilder.Editor.0a5fda05323649009444bb7c3ee2b9c4.v0.1.0
FILES_CMAKE
${editor_files}
${shared_files}
PLATFORM_INCLUDE_FILES
Source/Platform/Common/${PAL_TRAIT_COMPILER_ID}/pythonassetbuilder_static_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
Source
PUBLIC
Include
BUILD_DEPENDENCIES
PRIVATE
${editor_dependencies}
)
################################################################################
# Tests
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_target(
NAME PythonAssetBuilder.Tests MODULE
NAMESPACE Gem
FILES_CMAKE
pythonassetbuilder_tests_files.cmake
PLATFORM_INCLUDE_FILES
Source/Platform/Common/${PAL_TRAIT_COMPILER_ID}/pythonassetbuilder_tests_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
Source
Tests
BUILD_DEPENDENCIES
PRIVATE
AZ::AzTest
Gem::PythonAssetBuilder.Static
)
ly_add_googletest(
NAME Gem::PythonAssetBuilder.Tests
)
endif()
@@ -0,0 +1,43 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace AssetBuilderSDK
{
struct AssetBuilderDesc;
}
namespace PythonAssetBuilder
{
class PythonAssetBuilderRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! registers an asset builder using a builder descriptor
virtual AZ::Outcome<bool, AZStd::string> RegisterAssetBuilder(const AssetBuilderSDK::AssetBuilderDesc& desc) = 0;
//! fetches the current executable folder
virtual AZ::Outcome<AZStd::string, AZStd::string> GetExecutableFolder() const = 0;
};
using PythonAssetBuilderRequestBus = AZ::EBus<PythonAssetBuilderRequests>;
}
@@ -0,0 +1,48 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
namespace PythonAssetBuilder
{
class PythonBuilderWorker;
//! A notification bus for Python asset builder to hook into to operate asset building events
class PythonBuilderNotifications
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
using BusIdType = AZ::Uuid; //< JobId
//////////////////////////////////////////////////////////////////////////
//! creates jobs response using a request input
virtual AssetBuilderSDK::CreateJobsResponse OnCreateJobsRequest(const AssetBuilderSDK::CreateJobsRequest& request) = 0;
//! processes a source asset using a job request input
virtual AssetBuilderSDK::ProcessJobResponse OnProcessJobRequest(const AssetBuilderSDK::ProcessJobRequest& request) = 0;
//! signals when the entire asset building system is shutting down
virtual void OnShutdown() = 0;
//! signals the current job being processed should be canceled
virtual void OnCancel() = 0;
};
using PythonBuilderNotificationBus = AZ::EBus<PythonBuilderNotifications>;
}
@@ -0,0 +1,42 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/Asset/AssetCommon.h>
namespace PythonAssetBuilder
{
//! A request bus to help produce Lumberyard asset data
class PythonBuilderRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! Creates an AZ::Entity populated with Editor components and a name
virtual AZ::Outcome<AZ::EntityId, AZStd::string> CreateEditorEntity(const AZStd::string& name) = 0;
//! Writes out a .SLICE file with a given list of entities; optionally can be set to dynamic
virtual AZ::Outcome<AZ::Data::AssetType, AZStd::string> WriteSliceFile(
AZStd::string_view filename,
AZStd::vector<AZ::EntityId> entityList,
bool makeDynamic) = 0;
};
using PythonBuilderRequestBus = AZ::EBus<PythonBuilderRequests>;
}
@@ -0,0 +1,15 @@
#
# 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.
#
set(LY_COMPILE_OPTIONS
PRIVATE
-fexceptions
)
@@ -0,0 +1,15 @@
#
# 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.
#
set(LY_COMPILE_OPTIONS
PRIVATE
-fexceptions
)
@@ -0,0 +1,15 @@
#
# 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.
#
set(LY_COMPILE_OPTIONS
PRIVATE
/EHsc
)
@@ -0,0 +1,20 @@
#
# 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.
#
ly_add_source_properties(
SOURCES
Tests/PythonAssetBuilderTest.cpp
Tests/PythonBuilderRegisterTest.cpp
Tests/PythonBuilderCreateJobsTest.cpp
Tests/PythonBuilderProcessJobTest.cpp
PROPERTY COMPILE_OPTIONS
VALUES -bigobj
)
@@ -0,0 +1,12 @@
#
# 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.
#
set(PAL_TRAIT_BUILD_PYTHONASSETBUILDER_SUPPORTED TRUE)
@@ -0,0 +1,12 @@
#
# 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.
#
set(PAL_TRAIT_BUILD_PYTHONASSETBUILDER_SUPPORTED FALSE)
@@ -0,0 +1,12 @@
#
# 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.
#
set(PAL_TRAIT_BUILD_PYTHONASSETBUILDER_SUPPORTED TRUE)
@@ -0,0 +1,48 @@
/*
* 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 <AzCore/Memory/SystemAllocator.h>
#include <AzCore/Module/Module.h>
#include <PythonAssetBuilderSystemComponent.h>
namespace PythonAssetBuilder
{
class PythonAssetBuilderModule
: public AZ::Module
{
public:
AZ_RTTI(PythonAssetBuilderModule, "{35C9457E-54C2-474C-AEBE-5A70CC1D435D}", AZ::Module);
AZ_CLASS_ALLOCATOR(PythonAssetBuilderModule, AZ::SystemAllocator, 0);
PythonAssetBuilderModule()
: AZ::Module()
{
m_descriptors.insert(m_descriptors.end(), {
PythonAssetBuilderSystemComponent::CreateDescriptor(),
});
}
// Add required SystemComponents to the SystemEntity.
AZ::ComponentTypeList GetRequiredSystemComponents() const override
{
return AZ::ComponentTypeList {
azrtti_typeid<PythonAssetBuilderSystemComponent>(),
};
}
};
}
// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM
// The first parameter should be GemName_GemIdLower
// The second should be the fully qualified name of the class above
AZ_DECLARE_MODULE_CLASS(PythonAssetBuilder_0a5fda05323649009444bb7c3ee2b9c4, PythonAssetBuilder::PythonAssetBuilderModule)
@@ -0,0 +1,259 @@
/*
* 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 <PythonAssetBuilderSystemComponent.h>
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include <PythonAssetBuilder/PythonBuilderRequestBus.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/IO/LocalFileIO.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <AzToolsFramework/API/EditorPythonConsoleBus.h>
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Slice/SliceTransaction.h>
#include <AzToolsFramework/Slice/SliceUtilities.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include <Source/PythonBuilderWorker.h>
#include <Source/PythonBuilderMessageSink.h>
#include <Source/PythonBuilderNotificationHandler.h>
namespace PythonAssetBuilder
{
void PythonAssetBuilderSystemComponent::Reflect(AZ::ReflectContext* context)
{
PythonBuilderNotificationHandler::Reflect(context);
PythonBuilderWorker::Reflect(context);
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
const AZStd::vector<AZ::Crc32> systemTags({ AssetBuilderSDK::ComponentTags::AssetBuilder });
serialize->Class<PythonAssetBuilderSystemComponent, AZ::Component>()
->Version(0)
->Attribute(AZ::Edit::Attributes::SystemComponentTags, systemTags)
;
}
if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<PythonAssetBuilderRequestBus>("PythonAssetBuilderRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
->Event("RegisterAssetBuilder", &PythonAssetBuilderRequestBus::Events::RegisterAssetBuilder)
->Event("GetExecutableFolder", &PythonAssetBuilderRequestBus::Events::GetExecutableFolder)
;
behaviorContext->EBus<PythonBuilderRequestBus>("PythonBuilderRequestBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "asset.entity")
->Event("WriteSliceFile", &PythonBuilderRequestBus::Events::WriteSliceFile)
->Event("CreateEditorEntity", &PythonBuilderRequestBus::Events::CreateEditorEntity)
;
}
}
void PythonAssetBuilderSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC_CE("PythonAssetBuilderService"));
}
void PythonAssetBuilderSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC_CE("PythonAssetBuilderService"));
}
void PythonAssetBuilderSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
{
dependent.push_back(EditorPythonBindings::PythonMarshalingService);
dependent.push_back(EditorPythonBindings::PythonReflectionService);
dependent.push_back(EditorPythonBindings::PythonEmbeddedService);
}
void PythonAssetBuilderSystemComponent::Init()
{
m_messageSink = AZStd::make_shared<PythonBuilderMessageSink>();
}
void PythonAssetBuilderSystemComponent::Activate()
{
PythonAssetBuilderRequestBus::Handler::BusConnect();
if (auto&& pythonInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get())
{
pythonInterface->StartPython(true);
}
PythonBuilderRequestBus::Handler::BusConnect();
}
void PythonAssetBuilderSystemComponent::Deactivate()
{
PythonBuilderRequestBus::Handler::BusDisconnect();
m_messageSink.reset();
if (PythonAssetBuilderRequestBus::HasHandlers())
{
PythonAssetBuilderRequestBus::Handler::BusDisconnect();
if (auto&& pythonInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get())
{
pythonInterface->StopPython(true);
}
}
}
AZ::Outcome<bool, AZStd::string> PythonAssetBuilderSystemComponent::RegisterAssetBuilder(const AssetBuilderSDK::AssetBuilderDesc& desc)
{
const AZ::Uuid busId = desc.m_busId;
if (m_pythonBuilderWorkerMap.find(busId) != m_pythonBuilderWorkerMap.end())
{
AZStd::string busIdString(busId.ToString<AZStd::string>());
AZStd::string failMessage = AZStd::string::format("Asset Builder of JobId:%s has already been created.", busIdString.c_str());
AZ_Warning(PythonBuilder, false, failMessage.c_str());
return AZ::Failure(failMessage);
}
// create a PythonBuilderWorker instance
auto worker = AZStd::make_shared<PythonBuilderWorker>();
if (worker->ConfigureBuilderInformation(desc) == false)
{
return AZ::Failure(AZStd::string::format("Failed to configure builderId:%s", busId.ToString<AZStd::string>().c_str()));
}
m_pythonBuilderWorkerMap[busId] = worker;
return AZ::Success(true);
}
AZ::Outcome<AZStd::string, AZStd::string> PythonAssetBuilderSystemComponent::GetExecutableFolder() const
{
const char* exeFolderName = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(exeFolderName, &AZ::ComponentApplicationRequests::GetExecutableFolder);
if (exeFolderName)
{
return AZ::Success(AZStd::string(exeFolderName));
}
return AZ::Failure(AZStd::string("GetExecutableFolder access is missing."));
}
AZ::Outcome<AZ::EntityId, AZStd::string> PythonAssetBuilderSystemComponent::CreateEditorEntity(const AZStd::string& name)
{
AZ::EntityId entityId;
AzToolsFramework::EditorEntityContextRequestBus::BroadcastResult(
entityId,
&AzToolsFramework::EditorEntityContextRequestBus::Events::CreateNewEditorEntity,
name.c_str());
if (entityId.IsValid() == false)
{
return AZ::Failure<AZStd::string>("Failed to CreateNewEditorEntity.");
}
AZ::Entity* entity = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, entityId);
if (entity == nullptr)
{
return AZ::Failure<AZStd::string>(AZStd::string::format("Failed to find created entityId %s", entityId.ToString().c_str()));
}
entity->Deactivate();
AzToolsFramework::EditorEntityContextRequestBus::Broadcast(
&AzToolsFramework::EditorEntityContextRequestBus::Events::AddRequiredComponents,
*entity);
entity->Activate();
return AZ::Success(entityId);
}
AZ::Outcome<AZ::Data::AssetType, AZStd::string> PythonAssetBuilderSystemComponent::WriteSliceFile(
AZStd::string_view filename,
AZStd::vector<AZ::EntityId> entityList,
bool makeDynamic)
{
using namespace AzToolsFramework::SliceUtilities;
AZ::SerializeContext* serializeContext = nullptr;
AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
if (serializeContext == nullptr)
{
return AZ::Failure<AZStd::string>("GetSerializeContext failed");
}
// transaction->Commit() requires the "@user@" alias
if (AZ::IO::FileIOBase::GetInstance()->GetAlias("@user@") == nullptr)
{
AZStd::string assetRoot;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
assetRoot,
&AzFramework::ApplicationRequests::Bus::Events::GetAssetRoot);
AZStd::string userPath;
AZ::StringFunc::Path::Join(assetRoot.c_str(), "AssetProcessorTemp", userPath);
AZ::IO::FileIOBase::GetInstance()->SetAlias("@user@", userPath.c_str());
}
// transaction->Commit() expects the file to exist and write-able
AZ::IO::HandleType fileHandle;
AZ::IO::LocalFileIO::GetInstance()->Open(filename.data(), AZ::IO::OpenMode::ModeWrite, fileHandle);
if (fileHandle == AZ::IO::InvalidHandle)
{
return AZ::Failure<AZStd::string>(
AZStd::string::format("Failed to create slice file %.*s", aznumeric_cast<int>(filename.size()), filename.data()));
}
AZ::IO::LocalFileIO::GetInstance()->Close(fileHandle);
AZ::u32 creationFlags = 0;
if (makeDynamic)
{
creationFlags |= SliceTransaction::CreateAsDynamic;
}
SliceTransaction::TransactionPtr transaction = SliceTransaction::BeginNewSlice(nullptr, serializeContext, creationFlags);
// add entities
for (const AZ::EntityId& entityId : entityList)
{
auto addResult = transaction->AddEntity(entityId, SliceTransaction::SliceAddEntityFlags::DiscardSliceAncestry);
if (!addResult)
{
return AZ::Failure<AZStd::string>(AZStd::string::format("Failed slice add entity: %s", addResult.GetError().c_str()));
}
}
// commit to a file
AZ::Data::AssetType sliceAssetType;
auto resultCommit = transaction->Commit(filename.data(), nullptr, [&sliceAssetType](
SliceTransaction::TransactionPtr transactionPtr,
[[maybe_unused]] const char* fullPath,
const SliceTransaction::SliceAssetPtr& sliceAssetPtr)
{
sliceAssetType = sliceAssetPtr->GetType();
return AZ::Success();
});
if (!resultCommit)
{
return AZ::Failure<AZStd::string>(AZStd::string::format("Failed commit slice: %s", resultCommit.GetError().c_str()));
}
return AZ::Success(sliceAssetType);
}
}
@@ -0,0 +1,64 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include <PythonAssetBuilder/PythonBuilderRequestBus.h>
namespace PythonAssetBuilder
{
class PythonBuilderWorker;
class PythonBuilderMessageSink;
class PythonAssetBuilderSystemComponent
: public AZ::Component
, protected PythonAssetBuilderRequestBus::Handler
, protected PythonBuilderRequestBus::Handler
{
public:
AZ_COMPONENT(PythonAssetBuilderSystemComponent, "{E2872C13-D103-4534-9A95-76A66C8DDB5D}");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
protected:
// AZ::Component
void Init() override;
void Activate() override;
void Deactivate() override;
// PythonAssetBuilderRequestBus
AZ::Outcome<bool, AZStd::string> RegisterAssetBuilder(const AssetBuilderSDK::AssetBuilderDesc& desc) override;
AZ::Outcome<AZStd::string, AZStd::string> GetExecutableFolder() const override;
// PythonBuilderRequestBus
AZ::Outcome<AZ::EntityId, AZStd::string> CreateEditorEntity(const AZStd::string& name) override;
AZ::Outcome<AZ::Data::AssetType, AZStd::string> WriteSliceFile(
AZStd::string_view filename,
AZStd::vector<AZ::EntityId> entityList,
bool makeDynamic) override;
private:
using PythonBuilderWorkerPointer = AZStd::shared_ptr<PythonBuilderWorker>;
using PythonBuilderWorkerMap = AZStd::unordered_map<AZ::Uuid, PythonBuilderWorkerPointer>;
PythonBuilderWorkerMap m_pythonBuilderWorkerMap;
AZStd::shared_ptr <PythonBuilderMessageSink> m_messageSink;
};
constexpr const char PythonBuilder[] = "PythonBuilder";
}
@@ -0,0 +1,52 @@
/*
* 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 <PythonBuilderMessageSink.h>
#include <AssetBuilderSDK/AssetBuilderBusses.h>
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
namespace PythonAssetBuilder
{
PythonBuilderMessageSink::PythonBuilderMessageSink()
{
AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect();
}
PythonBuilderMessageSink::~PythonBuilderMessageSink()
{
AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect();
}
void PythonBuilderMessageSink::OnTraceMessage(AZStd::string_view message)
{
if (message.empty() == false)
{
AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "%.*s", static_cast<int>(message.size()), message.data());
}
}
void PythonBuilderMessageSink::OnErrorMessage(AZStd::string_view message)
{
if (message.empty() == false)
{
AZ_Error(AssetBuilderSDK::ErrorWindow, false, "ERROR: %.*s", static_cast<int>(message.size()), message.data());
}
}
void PythonBuilderMessageSink::OnExceptionMessage(AZStd::string_view message)
{
if (message.empty() == false)
{
AZ_Error(AssetBuilderSDK::ErrorWindow, false, "EXCEPTION: %.*s", static_cast<int>(message.size()), message.data());
}
}
}
@@ -0,0 +1,33 @@
/*
* 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.
*
*/
#pragma once
#include <AzToolsFramework/API/EditorPythonConsoleBus.h>
namespace PythonAssetBuilder
{
class PythonBuilderMessageSink final
: public AzToolsFramework::EditorPythonConsoleNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(PythonBuilderMessageSink, AZ::SystemAllocator, 0);
PythonBuilderMessageSink();
~PythonBuilderMessageSink();
protected:
// AzToolsFramework::EditorPythonConsoleNotificationBus
void OnTraceMessage(AZStd::string_view message) override;
void OnErrorMessage(AZStd::string_view message) override;
void OnExceptionMessage(AZStd::string_view message) override;
};
}
@@ -0,0 +1,131 @@
/*
* 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 <PythonBuilderNotificationHandler.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/EditContextConstants.inl>
#include <AzToolsFramework/API/EditorPythonConsoleBus.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include <Source/PythonAssetBuilderSystemComponent.h>
namespace PythonAssetBuilder
{
void PythonBuilderNotificationHandler::Reflect(AZ::ReflectContext * context)
{
if (auto&& behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->EBus<PythonBuilderNotificationBus>("PythonBuilderNotificationBus")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
->Handler<PythonBuilderNotificationHandler>()
->Event("OnCreateJobsRequest", &PythonBuilderNotificationBus::Events::OnCreateJobsRequest)
->Event("OnProcessJobRequest", &PythonBuilderNotificationBus::Events::OnProcessJobRequest)
->Event("OnShutdown", &PythonBuilderNotificationBus::Events::OnShutdown)
->Event("OnCancel", &PythonBuilderNotificationBus::Events::OnCancel)
;
}
}
AssetBuilderSDK::CreateJobsResponse PythonBuilderNotificationHandler::OnCreateJobsRequest(const AssetBuilderSDK::CreateJobsRequest& request)
{
AssetBuilderSDK::CreateJobsResponse response;
try
{
auto editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
if (editorPythonEventsInterface)
{
editorPythonEventsInterface->ExecuteWithLock([&response, &request, this]()
{
this->CallResult(response, FN_OnCreateJobsRequest, request);
});
}
else
{
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
}
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Error(PythonBuilder, false, "OnCreateJobsRequest exception %s", e.what());
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
}
return response;
}
AssetBuilderSDK::ProcessJobResponse PythonBuilderNotificationHandler::OnProcessJobRequest(const AssetBuilderSDK::ProcessJobRequest& request)
{
AssetBuilderSDK::ProcessJobResponse response;
try
{
auto editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
if (editorPythonEventsInterface)
{
editorPythonEventsInterface->ExecuteWithLock([&response, &request, this]()
{
this->CallResult(response, FN_OnProcessJobRequest, request);
});
}
else
{
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
}
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Error(PythonBuilder, false, "OnProcessJobRequest exception %s", e.what());
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
}
return response;
}
void PythonBuilderNotificationHandler::OnShutdown()
{
try
{
auto editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
if (editorPythonEventsInterface)
{
editorPythonEventsInterface->ExecuteWithLock([this]()
{
this->Call(FN_OnShutdown);
});
}
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Warning(PythonBuilder, false, "OnShutdown exception %s", e.what());
}
}
void PythonBuilderNotificationHandler::OnCancel()
{
try
{
auto editorPythonEventsInterface = AZ::Interface<AzToolsFramework::EditorPythonEventsInterface>::Get();
if (editorPythonEventsInterface)
{
editorPythonEventsInterface->ExecuteWithLock([this]()
{
this->Call(FN_OnCancel);
});
}
}
catch ([[maybe_unused]] const std::exception& e)
{
AZ_Error(PythonBuilder, false, "OnCancel exception %s", e.what());
}
}
}
@@ -0,0 +1,35 @@
/*
* 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.
*
*/
#pragma once
#include <PythonAssetBuilder/PythonBuilderNotificationBus.h>
#include <AzToolsFramework/API/EditorPythonConsoleBus.h>
namespace PythonAssetBuilder
{
class PythonBuilderNotificationHandler final
: public AZ::BehaviorEBusHandler
, public PythonBuilderNotificationBus::Handler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(PythonBuilderNotificationHandler, "{9CF1761E-3365-42F7-83D0-5039B1B73223}", AZ::SystemAllocator,
OnCreateJobsRequest, OnProcessJobRequest, OnShutdown, OnCancel);
static void Reflect(AZ::ReflectContext* context);
protected:
AssetBuilderSDK::CreateJobsResponse OnCreateJobsRequest(const AssetBuilderSDK::CreateJobsRequest& request) override;
AssetBuilderSDK::ProcessJobResponse OnProcessJobRequest(const AssetBuilderSDK::ProcessJobRequest& request) override;
void OnShutdown() override;
void OnCancel() override;
};
}
@@ -0,0 +1,121 @@
/*
* 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 <PythonBuilderWorker.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzToolsFramework/API/EditorPythonConsoleBus.h>
#include <Source/PythonAssetBuilderSystemComponent.h>
#include <PythonAssetBuilder/PythonBuilderNotificationBus.h>
namespace PythonAssetBuilder
{
void PythonBuilderWorker::Reflect(AZ::ReflectContext* context)
{
if (auto&& serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<PythonBuilderWorker>()->Version(0);
}
if (auto&& behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
behaviorContext->Class<PythonBuilderWorker>("PythonBuilderWorker")
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation)
->Attribute(AZ::Script::Attributes::Module, "asset.builder")
->Constructor()
;
}
}
bool PythonBuilderWorker::ConfigureBuilderInformation(const AssetBuilderSDK::AssetBuilderDesc& assetBuilderDesc)
{
using namespace AssetBuilderSDK;
if (m_assetBuilderDesc)
{
AZ_Error(PythonBuilder, false, "Asset Builder (%s) already configured!", assetBuilderDesc.m_name.c_str());
return false;
}
// register the new PythonBuilderWorker instance with the Asset Builder
m_assetBuilderDesc = AZStd::make_shared<AssetBuilderSDK::AssetBuilderDesc>(assetBuilderDesc);
// prepare delegate handler for CreateJobs function to be resolved in a Python script
m_assetBuilderDesc->m_createJobFunction = [this](auto&& request, auto&& response)
{
this->CreateJobs(request, response);
};
// prepare delegate handler for ProcessJob function to be resolved in a Python script
m_assetBuilderDesc->m_processJobFunction = [this](auto&& request, auto&& response)
{
this->ProcessJob(request, response);
};
// connect to the shutdown signal handler
AssetBuilderCommandBus::Handler::BusConnect(m_assetBuilderDesc->m_busId);
// register with the Asset Builder
AssetBuilderBus::Broadcast(&AssetBuilderBus::Events::RegisterBuilderInformation, *m_assetBuilderDesc);
return true;
}
void PythonBuilderWorker::ShutDown()
{
// Note - Shutdown will be called on a different thread than your process job thread
if (!m_isShuttingDown)
{
m_isShuttingDown = true;
PythonBuilderNotificationBus::Event(m_busId, &PythonBuilderNotificationBus::Events::OnShutdown);
AssetBuilderSDK::AssetBuilderCommandBus::Handler::BusDisconnect();
}
}
void PythonBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response)
{
if (m_isShuttingDown)
{
response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown;
return;
}
// assume failure
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
PythonBuilderNotificationBus::EventResult(
response,
request.m_builderid,
&PythonBuilderNotificationBus::Events::OnCreateJobsRequest,
request);
}
void PythonBuilderWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response)
{
AssetBuilderSDK::JobCommandBus::Handler::BusConnect(request.m_jobId);
// assume failure
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
PythonBuilderNotificationBus::EventResult(
response,
request.m_builderGuid,
&PythonBuilderNotificationBus::Events::OnProcessJobRequest,
request);
AssetBuilderSDK::JobCommandBus::Handler::BusDisconnect(request.m_jobId);
}
void PythonBuilderWorker::Cancel()
{
PythonBuilderNotificationBus::Event(m_busId, &PythonBuilderNotificationBus::Events::OnCancel);
}
}
@@ -0,0 +1,58 @@
/*
* 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.
*
*/
#pragma once
#include <AzCore/Component/Component.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <AssetBuilderSDK/AssetBuilderBusses.h>
#include <EditorPythonBindings/EditorPythonBindingsBus.h>
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
namespace PythonAssetBuilder
{
//! A delegate asset build worker for Python scripts
class PythonBuilderWorker
: public AssetBuilderSDK::AssetBuilderCommandBus::Handler
, public AssetBuilderSDK::JobCommandBus::Handler
{
public:
AZ_TYPE_INFO(PythonBuilderWorker, "{F27E64FB-A7FF-47F2-80DB-7E1371B014DD}");
AZ_CLASS_ALLOCATOR(PythonBuilderWorker, AZ::SystemAllocator, 0);
PythonBuilderWorker() = default;
virtual ~PythonBuilderWorker() = default;
static void Reflect(AZ::ReflectContext* context);
//! Configure the Python builder using an asset builder description; should only be done once
bool ConfigureBuilderInformation(const AssetBuilderSDK::AssetBuilderDesc& assetBuilderDesc);
protected:
//! AssetBuilder callback functions
void CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response);
void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response);
//! AssetBuilderSDK::AssetBuilderCommandBus interface
void ShutDown() override;
//! AssetBuilderSDK::JobCommandBus interface
void Cancel() override;
private:
AZ::Uuid m_busId = AZ::Uuid::CreateNull();
bool m_isShuttingDown = false;
AZStd::shared_ptr<AssetBuilderSDK::AssetBuilderDesc> m_assetBuilderDesc;
};
}
@@ -0,0 +1,155 @@
/*
* 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 <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Component/ComponentApplication.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include "Source/PythonAssetBuilderSystemComponent.h"
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include <PythonAssetBuilder/PythonBuilderRequestBus.h>
#include <AzCore/Asset/AssetCommon.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
namespace UnitTest
{
class PythonAssetBuilderTest
: public ScopedAllocatorSetupFixture
{
protected:
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
AZ::Entity* m_systemEntity = nullptr;
void SetUp() override
{
AZ::ComponentApplication::Descriptor appDesc;
m_app = AZStd::make_unique<AZ::ComponentApplication>();
m_systemEntity = m_app->Create(appDesc);
}
void TearDown() override
{
m_app.reset();
}
};
TEST_F(PythonAssetBuilderTest, SystemComponent_InitActivate)
{
m_app->RegisterComponentDescriptor(PythonAssetBuilder::PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilder::PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
EXPECT_EQ(AZ::Entity::State::Init, m_systemEntity->GetState());
m_systemEntity->Activate();
EXPECT_EQ(AZ::Entity::State::Active, m_systemEntity->GetState());
}
TEST_F(PythonAssetBuilderTest, SystemComponent_RegisterAssetBuilder)
{
using namespace PythonAssetBuilder;
m_app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
AssetBuilderSDK::AssetBuilderDesc mockAssetBuilderDesc;
mockAssetBuilderDesc.m_busId = AZ::Uuid::CreateString("{C68C8E96-223A-46BD-8D4A-E159A85AC02A}");
AZ::Outcome<bool, AZStd::string> result;
PythonAssetBuilderRequestBus::BroadcastResult(result, &PythonAssetBuilderRequestBus::Events::RegisterAssetBuilder, mockAssetBuilderDesc);
EXPECT_TRUE(result.IsSuccess());
}
TEST_F(PythonAssetBuilderTest, PythonAssetBuilderRequestBus_GetExecutableFolder_Works)
{
using namespace PythonAssetBuilder;
EXPECT_FALSE(PythonAssetBuilderRequestBus::HasHandlers());
m_app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
EXPECT_TRUE(PythonAssetBuilderRequestBus::HasHandlers());
AZ::Outcome<AZStd::string, AZStd::string> result;
PythonAssetBuilderRequestBus::BroadcastResult(
result,
&PythonAssetBuilderRequestBus::Events::GetExecutableFolder);
EXPECT_TRUE(result.IsSuccess());
}
// test bus API exists
TEST_F(PythonAssetBuilderTest, PythonBuilderRequestBus_CreateEditorEntity_Exists)
{
using namespace PythonAssetBuilder;
EXPECT_FALSE(PythonBuilderRequestBus::HasHandlers());
// Some static tests to make sure the public API has not changed since that
// would break Python asset builders using this EBus
{
AZ::Outcome<AZ::EntityId, AZStd::string> result;
AZStd::string name;
PythonBuilderRequestBus::BroadcastResult(
result,
&PythonBuilderRequestBus::Events::CreateEditorEntity,
name);
EXPECT_FALSE(result.IsSuccess());
}
m_app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
EXPECT_TRUE(PythonBuilderRequestBus::HasHandlers());
}
TEST_F(PythonAssetBuilderTest, PythonBuilderRequestBus_WriteSliceFile_Exists)
{
using namespace PythonAssetBuilder;
EXPECT_FALSE(PythonBuilderRequestBus::HasHandlers());
// Some static tests to make sure the public API has not changed since that
// would break Python asset builders using this EBus
{
AZ::Outcome<AZ::Data::AssetType, AZStd::string> result;
AZStd::string_view filename;
AZStd::vector<AZ::EntityId> entities;
bool makeDynamic = {};
PythonBuilderRequestBus::BroadcastResult(
result,
&PythonBuilderRequestBus::Events::WriteSliceFile,
filename,
entities,
makeDynamic);
EXPECT_FALSE(result.IsSuccess());
}
m_app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
EXPECT_TRUE(PythonBuilderRequestBus::HasHandlers());
}
}
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
@@ -0,0 +1,119 @@
/*
* 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 <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Component/ComponentApplication.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include "Source/PythonAssetBuilderSystemComponent.h"
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include <PythonAssetBuilder/PythonBuilderNotificationBus.h>
#include "PythonBuilderTestShared.h"
namespace UnitTest
{
// fixtures
class PythonBuilderCreateJobsTest
: public ScopedAllocatorSetupFixture
{
protected:
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
AZ::Entity* m_systemEntity = nullptr;
void SetUp() override
{
AZ::ComponentApplication::Descriptor appDesc;
m_app = AZStd::make_unique<AZ::ComponentApplication>();
m_systemEntity = m_app->Create(appDesc);
}
void TearDown() override
{
m_app.reset();
}
};
// tests
TEST_F(PythonBuilderCreateJobsTest, PythonBuilder_CreateJobs_Success)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
const AZ::Uuid builderId = RegisterAssetBuilder(m_app.get(), m_systemEntity);
MockJobHandler mockJobHandler;
mockJobHandler.BusConnect(builderId);
AssetBuilderSDK::CreateJobsRequest request;
request.m_builderid = builderId;
request.m_sourceFileUUID = AZ::Uuid::CreateRandom();
AssetBuilderSDK::CreateJobsResponse response;
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Failed;
PythonBuilderNotificationBus::EventResult(
response,
builderId,
&PythonBuilderNotificationBus::Events::OnCreateJobsRequest,
request);
EXPECT_EQ(AssetBuilderSDK::CreateJobsResultCode::Success, response.m_result);
EXPECT_EQ(0, mockJobHandler.m_onShutdownCount);
}
TEST_F(PythonBuilderCreateJobsTest, PythonBuilder_CreateJobs_Failed)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
const AZ::Uuid builderId = RegisterAssetBuilder(m_app.get(), m_systemEntity);
EXPECT_NE(AZ::Uuid::CreateNull(), builderId);
MockJobHandler mockJobHandler;
mockJobHandler.BusConnect(builderId);
AssetBuilderSDK::CreateJobsRequest request;
request.m_builderid = builderId;
request.m_sourceFileUUID = AZ::Uuid::CreateNull();
AssetBuilderSDK::CreateJobsResponse response;
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
PythonBuilderNotificationBus::EventResult(
response,
request.m_builderid,
&PythonBuilderNotificationBus::Events::OnCreateJobsRequest,
request);
EXPECT_EQ(AssetBuilderSDK::CreateJobsResultCode::Failed, response.m_result);
EXPECT_EQ(0, mockJobHandler.m_onShutdownCount);
}
TEST_F(PythonBuilderCreateJobsTest, PythonBuilder_CreateJobs_OnShutdown)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
const AZ::Uuid builderId = RegisterAssetBuilder(m_app.get(), m_systemEntity);
EXPECT_NE(AZ::Uuid::CreateNull(), builderId);
MockJobHandler mockJobHandler;
mockJobHandler.BusConnect(builderId);
PythonBuilderNotificationBus::Event(builderId, &PythonBuilderNotificationBus::Events::OnShutdown);
EXPECT_EQ(1, mockJobHandler.m_onShutdownCount);
}
}
@@ -0,0 +1,126 @@
/*
* 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 <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/RTTI/BehaviorContext.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include "Source/PythonAssetBuilderSystemComponent.h"
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include "PythonBuilderTestShared.h"
namespace UnitTest
{
class PythonBuilderProcessJobTest
: public ScopedAllocatorSetupFixture
{
protected:
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
AZ::Entity* m_systemEntity = nullptr;
void SetUp() override
{
AZ::ComponentApplication::Descriptor appDesc;
m_app = AZStd::make_unique<AZ::ComponentApplication>();
m_systemEntity = m_app->Create(appDesc);
}
void TearDown() override
{
m_app.reset();
}
};
TEST_F(PythonBuilderProcessJobTest, PythonBuilder_ProcessJob_ResultSuccess)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
const AZ::Uuid builderId = RegisterAssetBuilder(m_app.get(), m_systemEntity);
MockJobHandler mockJobHandler;
mockJobHandler.BusConnect(builderId);
AssetBuilderSDK::ProcessJobRequest request;
request.m_builderGuid = builderId;
request.m_sourceFileUUID = AZ::Uuid::CreateRandom();
AssetBuilderSDK::ProcessJobResponse response;
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_NetworkIssue;
PythonBuilderNotificationBus::EventResult(
response,
builderId,
&PythonBuilderNotificationBus::Events::OnProcessJobRequest,
request);
EXPECT_EQ(AssetBuilderSDK::ProcessJobResult_Success, response.m_resultCode);
EXPECT_EQ(0, mockJobHandler.m_onCancelCount);
}
TEST_F(PythonBuilderProcessJobTest, PythonBuilder_ProcessJob_ResultFailed)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
const AZ::Uuid builderId = RegisterAssetBuilder(m_app.get(), m_systemEntity);
MockJobHandler mockJobHandler;
mockJobHandler.BusConnect(builderId);
AssetBuilderSDK::ProcessJobRequest request;
request.m_builderGuid = builderId;
request.m_sourceFileUUID = AZ::Uuid::CreateNull();
AssetBuilderSDK::ProcessJobResponse response;
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
PythonBuilderNotificationBus::EventResult(
response,
builderId,
&PythonBuilderNotificationBus::Events::OnProcessJobRequest,
request);
EXPECT_EQ(AssetBuilderSDK::ProcessJobResult_Failed, response.m_resultCode);
EXPECT_EQ(0, mockJobHandler.m_onCancelCount);
}
TEST_F(PythonBuilderProcessJobTest, PythonBuilder_ProcessJob_OnCancel)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
const AZ::Uuid builderId = RegisterAssetBuilder(m_app.get(), m_systemEntity);
MockJobHandler mockJobHandler;
mockJobHandler.BusConnect(builderId);
PythonBuilderNotificationBus::Event(builderId, &PythonBuilderNotificationBus::Events::OnCancel);
EXPECT_EQ(1, mockJobHandler.m_onCancelCount);
}
TEST_F(PythonBuilderProcessJobTest, PythonBuilderRequestBus_Behavior_Exists)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
RegisterAssetBuilder(m_app.get(), m_systemEntity);
auto entry = m_app->GetBehaviorContext()->m_ebuses.find("PythonBuilderRequestBus");
ASSERT_NE(m_app->GetBehaviorContext()->m_ebuses.end(), entry);
EXPECT_NE(entry->second->m_events.end(), entry->second->m_events.find("WriteSliceFile"));
EXPECT_NE(entry->second->m_events.end(), entry->second->m_events.find("CreateEditorEntity"));
}
}
@@ -0,0 +1,93 @@
/*
* 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 <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Component/ComponentApplication.h>
#include <AssetBuilderSDK/AssetBuilderSDK.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include "Source/PythonAssetBuilderSystemComponent.h"
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
namespace UnitTest
{
class PythonBuilderRegisterJobsTest
: public ScopedAllocatorSetupFixture
{
protected:
AZStd::unique_ptr<AZ::ComponentApplication> m_app;
AZ::Entity* m_systemEntity = nullptr;
void SetUp() override
{
AZ::ComponentApplication::Descriptor appDesc;
m_app = AZStd::make_unique<AZ::ComponentApplication>();
m_systemEntity = m_app->Create(appDesc);
}
void TearDown() override
{
m_app.reset();
}
};
TEST_F(PythonBuilderRegisterJobsTest, PythonBuilder_RegisterBuilder_Regex)
{
using namespace PythonAssetBuilder;
m_app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
AssetBuilderSDK::AssetBuilderPattern buildPattern;
buildPattern.m_pattern = R"_(^.*\.foo$)_";
buildPattern.m_type = AssetBuilderSDK::AssetBuilderPattern::Regex;
AssetBuilderSDK::AssetBuilderDesc builderDesc;
builderDesc.m_busId = AZ::Uuid::CreateRandom();
builderDesc.m_name = "Mock Builder Regex";
builderDesc.m_patterns.push_back(buildPattern);
builderDesc.m_version = 0;
AZ::Outcome<bool, AZStd::string> result;
PythonAssetBuilderRequestBus::BroadcastResult(result, &PythonAssetBuilderRequestBus::Events::RegisterAssetBuilder, builderDesc);
EXPECT_TRUE(result.IsSuccess());
}
TEST_F(PythonBuilderRegisterJobsTest, PythonBuilder_RegisterBuilder_Wildcard)
{
using namespace PythonAssetBuilder;
m_app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
m_systemEntity->CreateComponent<PythonAssetBuilderSystemComponent>();
m_systemEntity->Init();
m_systemEntity->Activate();
AssetBuilderSDK::AssetBuilderPattern buildPattern;
buildPattern.m_pattern = "a/path/to/*.foo";
buildPattern.m_type = AssetBuilderSDK::AssetBuilderPattern::Wildcard;
AssetBuilderSDK::AssetBuilderDesc builderDesc;
builderDesc.m_busId = AZ::Uuid::CreateRandom();
builderDesc.m_name = "Mock Builder Wildcard";
builderDesc.m_patterns.push_back(buildPattern);
builderDesc.m_version = 0;
AZ::Outcome<bool, AZStd::string> result;
PythonAssetBuilderRequestBus::BroadcastResult(result, &PythonAssetBuilderRequestBus::Events::RegisterAssetBuilder, builderDesc);
EXPECT_TRUE(result.IsSuccess());
}
}
@@ -0,0 +1,94 @@
/*
* 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.
*
*/
#pragma once
#include <AzTest/AzTest.h>
#include <AzCore/UnitTest/TestTypes.h>
#include <AzCore/Component/ComponentApplication.h>
#include <EditorPythonBindings/EditorPythonBindingsSymbols.h>
#include "Source/PythonAssetBuilderSystemComponent.h"
#include <PythonAssetBuilder/PythonAssetBuilderBus.h>
#include <PythonAssetBuilder/PythonBuilderNotificationBus.h>
namespace UnitTest
{
struct MockJobHandler final
: public PythonAssetBuilder::PythonBuilderNotificationBus::Handler
{
int m_onShutdownCount = 0;
int m_onCancelCount = 0;
AssetBuilderSDK::CreateJobsResponse OnCreateJobsRequest(const AssetBuilderSDK::CreateJobsRequest& request) override
{
if (request.m_sourceFileUUID.IsNull())
{
return AssetBuilderSDK::CreateJobsResponse{};
}
AssetBuilderSDK::CreateJobsResponse response;
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
return response;
}
AssetBuilderSDK::ProcessJobResponse OnProcessJobRequest(const AssetBuilderSDK::ProcessJobRequest& request)
{
if (request.m_sourceFileUUID.IsNull())
{
return AssetBuilderSDK::ProcessJobResponse{};
}
AssetBuilderSDK::ProcessJobResponse response;
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
return response;
}
void OnShutdown()
{
++m_onShutdownCount;
}
void OnCancel()
{
++m_onCancelCount;
}
};
template <typename App, typename EntityType>
AZ::Uuid RegisterAssetBuilder(App* app, EntityType* systemEntity)
{
using namespace PythonAssetBuilder;
using namespace AssetBuilderSDK;
app->RegisterComponentDescriptor(PythonAssetBuilderSystemComponent::CreateDescriptor());
systemEntity->template CreateComponent<PythonAssetBuilderSystemComponent>();
systemEntity->Init();
systemEntity->Activate();
AssetBuilderPattern buildPattern;
buildPattern.m_pattern = "*.mock";
buildPattern.m_type = AssetBuilderPattern::Wildcard;
AssetBuilderDesc builderDesc;
builderDesc.m_busId = AZ::Uuid::CreateRandom();
builderDesc.m_name = "Mock Builder";
builderDesc.m_patterns.push_back(buildPattern);
builderDesc.m_version = 0;
AZ::Outcome<bool, AZStd::string> result;
PythonAssetBuilderRequestBus::BroadcastResult(result, &PythonAssetBuilderRequestBus::Events::RegisterAssetBuilder, builderDesc);
EXPECT_TRUE(result.IsSuccess());
return builderDesc.m_busId;
}
}
@@ -0,0 +1,131 @@
"""
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.
"""
#
# Simple example asset builder that processes *.foo files
#
import azlmbr.math
import azlmbr.asset.builder
import os, shutil
# the UUID must be unique amongst all the asset builders in Python or otherwise
busIdString = '{E4DB381B-61A0-4729-ACD9-4C8BDD2D2282}'
busId = azlmbr.math.Uuid_CreateString(busIdString, 0)
assetTypeScript = azlmbr.math.Uuid_CreateString('{82557326-4AE3-416C-95D6-C70635AB7588}', 0)
handler = None
jobKeyPrefix = 'Foo Job Key'
targetAssetFolder = 'foo_scripts'
# creates a single job to compile for a 'pc' platform
def on_create_jobs(args):
request = args[0] # azlmbr.asset.builder.CreateJobsRequest
response = azlmbr.asset.builder.CreateJobsResponse()
# note: if the asset builder is going to handle more than one file pattern it might need to check out
# the request.sourceFile to figure out what jobs need to be created
jobDescriptorList = []
for platformInfo in request.enabledPlatforms:
# for each enabled platform like 'pc' or 'ios'
platformId = platformInfo.identifier
# set up unique job key
jobKey = '{} {}'.format(jobKeyPrefix, platformId)
# create job descriptor
jobDesc = azlmbr.asset.builder.JobDescriptor()
jobDesc.jobKey = jobKey
jobDesc.set_platform_identifier(platformId)
jobDescriptorList.append(jobDesc)
print ('created a job for {} with key {}'.format(platformId, jobKey))
response.createJobOutputs = jobDescriptorList
response.result = azlmbr.asset.builder.CreateJobsResponse_ResultSuccess
return response
def get_target_name(sourceFullpath):
lua_file = os.path.basename(sourceFullpath)
lua_file = os.path.splitext(lua_file)[0]
lua_file = lua_file + '.lua'
return lua_file
def copy_foo_file(srcFile, dstFile):
try:
dir_name = os.path.dirname(dstFile)
if (os.path.exists(dir_name) is False):
os.makedirs(dir_name)
shutil.copyfile(srcFile, dstFile)
return True
except:
return False
# using the incoming 'request' find the type of job via 'jobKey' to determine what to do
def on_process_job(args):
request = args[0] # azlmbr.asset.builder.ProcessJobRequest
response = azlmbr.asset.builder.ProcessJobResponse()
# note: if possible to loop through incoming data a 'yeild' can be used to cooperatively
# thread the processing of the assets so that shutdown and cancel can be handled
if (request.jobDescription.jobKey.startswith(jobKeyPrefix)):
targetFile = os.path.join(targetAssetFolder, get_target_name(request.fullPath))
dstFile = os.path.join(request.tempDirPath, targetFile)
if (copy_foo_file(request.fullPath, dstFile)):
response.outputProducts = [azlmbr.asset.builder.JobProduct(dstFile, assetTypeScript, 0)]
response.resultCode = azlmbr.asset.builder.ProcessJobResponse_Success
response.dependenciesHandled = True
return response
def on_shutdown(args):
# note: user should attempt to close down any processing job if any running
global handler
if (handler is not None):
handler.disconnect()
handler = None
def on_cancel_job(args):
# note: user should attempt to close down any processing job if any running
print('>>> FOO asset builder - on_cancel_job <<<')
# register asset builder for source assets
def register_asset_builder():
assetPattern = azlmbr.asset.builder.AssetBuilderPattern()
assetPattern.pattern = '*.foo'
assetPattern.type = azlmbr.asset.builder.AssetBuilderPattern_Wildcard
builderDescriptor = azlmbr.asset.builder.AssetBuilderDesc()
builderDescriptor.name = "Foo Asset Builder"
builderDescriptor.patterns = [assetPattern]
builderDescriptor.busId = busId
builderDescriptor.version = 0
outcome = azlmbr.asset.builder.PythonAssetBuilderRequestBus(azlmbr.bus.Broadcast, 'RegisterAssetBuilder', builderDescriptor)
if outcome.IsSuccess():
# created the asset builder handler to hook into the notification bus
jobHandler = azlmbr.asset.builder.PythonBuilderNotificationBusHandler()
jobHandler.connect(busId)
jobHandler.add_callback('OnCreateJobsRequest', on_create_jobs)
jobHandler.add_callback('OnProcessJobRequest', on_process_job)
jobHandler.add_callback('OnShutdown', on_shutdown)
jobHandler.add_callback('OnCancel', on_cancel_job)
return jobHandler
# note: the handler has to be retained since Python retains the object ref count
# on_shutdown will clear the 'handler' to disconnect from the notification bus
handler = register_asset_builder()
@@ -0,0 +1,24 @@
#
# 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.
#
set(FILES
Include/PythonAssetBuilder/PythonAssetBuilderBus.h
Include/PythonAssetBuilder/PythonBuilderNotificationBus.h
Include/PythonAssetBuilder/PythonBuilderRequestBus.h
Source/PythonAssetBuilderSystemComponent.cpp
Source/PythonAssetBuilderSystemComponent.h
Source/PythonBuilderMessageSink.cpp
Source/PythonBuilderMessageSink.h
Source/PythonBuilderNotificationHandler.cpp
Source/PythonBuilderNotificationHandler.h
Source/PythonBuilderWorker.cpp
Source/PythonBuilderWorker.h
)
@@ -0,0 +1,24 @@
#
# 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.
#
set(FILES
Include/PythonAssetBuilder/PythonAssetBuilderBus.h
Include/PythonAssetBuilder/PythonBuilderNotificationBus.h
Include/PythonAssetBuilder/PythonBuilderRequestBus.h
Source/PythonAssetBuilderSystemComponent.cpp
Source/PythonAssetBuilderSystemComponent.h
Source/PythonBuilderMessageSink.cpp
Source/PythonBuilderMessageSink.h
Source/PythonBuilderNotificationHandler.cpp
Source/PythonBuilderNotificationHandler.h
Source/PythonBuilderWorker.cpp
Source/PythonBuilderWorker.h
)
@@ -0,0 +1,18 @@
#
# 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.
#
set(FILES
Tests/PythonAssetBuilderTest.cpp
Tests/PythonBuilderRegisterTest.cpp
Tests/PythonBuilderCreateJobsTest.cpp
Tests/PythonBuilderProcessJobTest.cpp
Tests/PythonBuilderTestShared.h
)
@@ -0,0 +1,14 @@
#
# 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.
#
set(FILES
Source/PythonAssetBuilderModule.cpp
)
@@ -0,0 +1,18 @@
#
# 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.
#
set(FILES
Tests/PythonAssetBuilderTest.cpp
Tests/PythonBuilderRegisterTest.cpp
Tests/PythonBuilderCreateJobsTest.cpp
Tests/PythonBuilderProcessJobTest.cpp
Tests/PythonBuilderTestShared.h
)
@@ -0,0 +1,12 @@
"""
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.
"""
+16
View File
@@ -0,0 +1,16 @@
{
"GemFormatVersion": 4,
"Uuid": "0a5fda05323649009444bb7c3ee2b9c4",
"Name": "PythonAssetBuilder",
"DisplayName": "PythonAssetBuilder",
"Version": "0.1.0",
"Summary": "Runs asset builders written in Python scripts.",
"Tags": ["asset"],
"IconPath": "preview.png",
"Modules": [
{
"Name": "Editor",
"Type": "EditorModule"
}
]
}
+3
View File
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa
size 41127