Merge from main

This commit is contained in:
jonbeer
2021-05-04 09:09:27 -07:00
9337 changed files with 135927 additions and 693498 deletions
@@ -175,7 +175,7 @@ namespace AzFramework
}
// Initializes the IArchive for reading archive(.pak) files
if (auto archive = AZ::Interface<AZ::IO::IArchive>::Get(); !archive)
if (auto archive = AZ::Interface<AZ::IO::IArchive>::Get(); archive == nullptr)
{
m_archive = AZStd::make_unique<AZ::IO::Archive>();
AZ::Interface<AZ::IO::IArchive>::Register(m_archive.get());
@@ -189,6 +189,12 @@ namespace AzFramework
SetFileIOAliases();
}
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI == nullptr)
{
m_nativeUI = AZStd::make_unique<AZ::NativeUI::NativeUISystem>();
AZ::Interface<AZ::NativeUI::NativeUIRequests>::Register(m_nativeUI.get());
}
ApplicationRequests::Bus::Handler::BusConnect();
AZ::UserSettingsFileLocatorBus::Handler::BusConnect();
NetSystemRequestBus::Handler::BusConnect();
@@ -205,12 +211,17 @@ namespace AzFramework
AZ::UserSettingsFileLocatorBus::Handler::BusDisconnect();
ApplicationRequests::Bus::Handler::BusDisconnect();
if (AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get() == m_nativeUI.get())
{
AZ::Interface<AZ::NativeUI::NativeUIRequests>::Unregister(m_nativeUI.get());
}
m_nativeUI.reset();
// Unset the Archive file IO if it is set as the direct instance
if (AZ::IO::FileIOBase::GetInstance() == m_archiveFileIO.get())
{
AZ::IO::FileIOBase::SetInstance(nullptr);
}
m_archiveFileIO.reset();
// Destroy the IArchive instance
@@ -303,7 +314,6 @@ namespace AzFramework
azrtti_typeid<AZ::AssetManagerComponent>(),
azrtti_typeid<AZ::UserSettingsComponent>(),
azrtti_typeid<AZ::Debug::FrameProfilerComponent>(),
azrtti_typeid<AZ::NativeUI::NativeUISystemComponent>(),
azrtti_typeid<AZ::SliceComponent>(),
azrtti_typeid<AZ::SliceSystemComponent>(),
@@ -372,7 +382,6 @@ namespace AzFramework
azrtti_typeid<AZ::UserSettingsComponent>(),
azrtti_typeid<AZ::ScriptSystemComponent>(),
azrtti_typeid<AZ::JobManagerComponent>(),
azrtti_typeid<AZ::NativeUI::NativeUISystemComponent>(),
azrtti_typeid<AZ::SliceSystemComponent>(),
azrtti_typeid<AzFramework::AssetCatalogComponent>(),
@@ -16,6 +16,7 @@
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/UserSettings/UserSettings.h>
#include <AzCore/Math/Uuid.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/string/fixed_string.h>
@@ -187,6 +188,7 @@ namespace AzFramework
AZStd::unique_ptr<AZ::IO::FileIOBase> m_archiveFileIO; ///> The Default file IO instance is a ArchiveFileIO.
AZStd::unique_ptr<AZ::IO::Archive> m_archive; ///> The AZ::IO::Instance
AZStd::unique_ptr<Implementation> m_pimpl;
AZStd::unique_ptr<AZ::NativeUI::NativeUIRequests> m_nativeUI;
bool m_ownsConsole = false;
bool m_exitMainLoopRequested = false;
@@ -809,7 +809,7 @@ namespace AzFramework
#if defined(AZ_ENABLE_TRACING)
if (message.m_assetType == AZ::Data::s_invalidAssetType)
{
AZ_TracePrintf("AssetCatalog", "Registering asset \"%s\" via AssetSystem message, but type is not set.", relativePath.c_str());
AZ_TracePrintf("AssetCatalog", "Registering asset \"%s\" via AssetSystem message, but type is not set.\n", relativePath.c_str());
}
#endif
@@ -220,7 +220,7 @@ namespace AzFramework
{
// Read the wait for connection boolean from the Settings Registry
AZ::s64 waitForConnect64{};
if (!AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect64, AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, AzFramework::AssetSystem::WaitForConnect))
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect64, AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, AzFramework::AssetSystem::WaitForConnect))
{
outputConnectionSettings.m_waitForConnect = waitForConnect64 != 0;
}
@@ -65,4 +65,4 @@ namespace AzFramework
using CommandRegistrationBus = AZ::EBus<CommandRegistration>;
} // namespace AzFramework
} // namespace AzFramework
@@ -17,7 +17,7 @@
#include <AzCore/RTTI/BehaviorContext.h>
#include <AzCore/Debug/Trace.h>
#include <AzFramework/Scene/Scene.h>
#include <AzFramework/Scene/SceneSystemBus.h>
#include <AzFramework/Scene/SceneSystemInterface.h>
#include <AzFramework/Entity/GameEntityContextComponent.h>
namespace AzFramework
@@ -50,36 +50,34 @@ namespace AzFramework
void AzFrameworkConfigurationSystemComponent::Activate()
{
// Create the defaults scene and associate the GameEntityContext with it.
AZ::Outcome<Scene*, AZStd::string> createSceneOutcome = AZ::Failure<AZStd::string>("SceneSystemRequests bus not responding.");
SceneSystemRequestBus::BroadcastResult(createSceneOutcome, &AzFramework::SceneSystemRequests::CreateScene, "default");
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> createSceneOutcome =
SceneSystemInterface::Get()->CreateScene(Scene::MainSceneName);
if (createSceneOutcome)
{
Scene* scene = createSceneOutcome.GetValue();
bool success = false;
EntityContextId gameEntityContextId = EntityContextId::CreateNull();
GameEntityContextRequestBus::BroadcastResult(gameEntityContextId, &GameEntityContextRequests::GetGameEntityContextId);
if (!gameEntityContextId.IsNull())
AZStd::shared_ptr<Scene> scene = createSceneOutcome.TakeValue();
EntityContext* gameEntityContext = nullptr;
GameEntityContextRequestBus::BroadcastResult(gameEntityContext, &GameEntityContextRequests::GetGameEntityContextInstance);
if (gameEntityContext != nullptr)
{
SceneSystemRequestBus::BroadcastResult(success, &AzFramework::SceneSystemRequests::SetSceneForEntityContextId, gameEntityContextId, scene);
[[maybe_unused]] bool result = scene->SetSubsystem<EntityContext::SceneStorageType&>(gameEntityContext);
AZ_Assert(result, "Unable to register main entity context with the main scene.");
}
else
{
AZ_Assert(false, "Unable to retrieve the game entity context instance.");
}
AZ_Assert(success, "The application was unable to setup a scene for the game entity context, this should always work");
}
else
{
AZ_Assert(false, "%s", createSceneOutcome.GetError().data());
AZ_Assert(false, "Unable to create main scene due to: %s", createSceneOutcome.GetError().c_str());
}
}
void AzFrameworkConfigurationSystemComponent::Deactivate()
{
bool success = false;
SceneSystemRequestBus::BroadcastResult(
success, &AzFramework::SceneSystemRequestBus::Events::RemoveScene, "default");
AZ_Assert(success, "\"default\" scene was not removed");
[[maybe_unused]] bool success = SceneSystemInterface::Get()->RemoveScene(Scene::MainSceneName);
AZ_Assert(success, "Unable to remove the main scene.");
}
void AzFrameworkConfigurationSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@@ -37,4 +37,4 @@ namespace AzFramework
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
};
} // AzFramework
} // AzFramework
@@ -69,4 +69,4 @@ namespace AzFramework
} // namespace AzFramework
#endif // AZFRAMEWORK_CONSOLE_BUS_H
#endif // AZFRAMEWORK_CONSOLE_BUS_H
@@ -69,4 +69,4 @@ namespace AzFramework
virtual void DebugCameraMoved(const AZ::Transform& world) {}
};
using DebugCameraEventsBus = AZ::EBus<DebugCameraEventsInterface>;
} // namespace AzFramework
} // namespace AzFramework
@@ -240,4 +240,4 @@ namespace AzFramework
AZ::EntityId m_entityId;
};
} // namespace AzFramework
} // namespace AzFramework
@@ -18,6 +18,8 @@
#include <AzCore/Component/TickBus.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/std/containers/stack.h>
#include <AzFramework/Scene/Scene.h>
#include <AzFramework/Scene/SceneSystemInterface.h>
#include "EntityContext.h"
@@ -37,6 +39,30 @@ namespace AzFramework
}
}
AZStd::shared_ptr<Scene> EntityContext::FindContainingScene(const EntityContextId& contextId)
{
auto sceneSystem = SceneSystemInterface::Get();
AZ_Assert(sceneSystem, "Attempting to retrieve the scene containing a entity context before the scene system is available.");
AZStd::shared_ptr<Scene> result;
sceneSystem->IterateActiveScenes([&result, &contextId](const AZStd::shared_ptr<Scene>& scene)
{
EntityContext** entityContext = scene->FindSubsystemInScene<EntityContext::SceneStorageType>();
if (entityContext && (*entityContext)->GetContextId() == contextId)
{
result = scene;
// Result found, returning.
return false;
}
else
{
// No match, continuing to search for containing scene.
return true;
}
});
return result;
}
//=========================================================================
// EntityContext ctor
//=========================================================================
@@ -17,6 +17,7 @@
#include <AzCore/Component/EntityBus.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <AzCore/Serialization/IdUtils.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Entity/EntityContextBus.h>
#include <AzFramework/Entity/SliceEntityOwnershipService.h>
@@ -27,7 +28,7 @@ namespace AZ
namespace AzFramework
{
class EntityContext;
class Scene;
/**
* Provides services for a group of entities under the umbrella of a given context.
@@ -47,9 +48,11 @@ namespace AzFramework
, public EntityOwnershipServiceNotificationBus::Handler
{
public:
AZ_TYPE_INFO(EntityContext, "{4F98A6B9-C7B5-450E-8A8A-30EEFC411EF5}");
/// The type used to store entity in AzFramework::Scene.
using SceneStorageType = EntityContext*;
EntityContext(AZ::SerializeContext* serializeContext = nullptr);
EntityContext(const EntityContextId& contextId, AZ::SerializeContext* serializeContext = nullptr);
EntityContext(const EntityContextId& contextId, AZStd::unique_ptr<EntityOwnershipService> entityOwnershipService,
@@ -75,6 +78,7 @@ namespace AzFramework
//////////////////////////////////////////////////////////////////////////
static void Reflect(AZ::ReflectContext* context);
static AZStd::shared_ptr<Scene> FindContainingScene(const EntityContextId& contextId);
protected:
@@ -66,6 +66,8 @@ namespace AzFramework
*/
virtual EntityContextId GetGameEntityContextId() = 0;
virtual EntityContext* GetGameEntityContextInstance() = 0;
/**
* Creates an entity in the game context.
* @param name A name for the new entity.
@@ -51,6 +51,7 @@ namespace AzFramework
//////////////////////////////////////////////////////////////////////////
// GameEntityContextRequestBus
AZ::Uuid GetGameEntityContextId() override { return GetContextId(); }
EntityContext* GetGameEntityContextInstance() override { return this; }
void ResetGameContext() override;
AZ::Entity* CreateGameEntity(const char* name) override;
BehaviorEntity CreateGameEntityForBehaviorContext(const char* name) override;
@@ -12,11 +12,13 @@
#include <AzCore/Serialization/Utils.h>
#include <AzCore/IO/FileIO.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/algorithm.h>
#include <AzCore/std/string/wildcard.h>
#include <AzCore/std/string/regex.h>
#include <AzCore/std/string/conversions.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/XML/rapidxml.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/Asset/FileTagAsset.h>
@@ -31,7 +33,7 @@ namespace AzFramework
const char* ExcludeFileName = "exclude";
const char* IncludeFileName = "include";
const char* FileTags[] = { "ignore", "error", "productdependency", "editoronly", "shader" };
const char EngineName[] = "Engine";
constexpr AZ::IO::PathView EngineAssetSourceRelPath = "Assets/Engine";
void LowerCaseFileTags(AZStd::vector<AZStd::string>& fileTags)
{
@@ -107,7 +109,7 @@ namespace AzFramework
}
AZ::Outcome<AZStd::string, AZStd::string> FileTagManager::AddTagsInternal(AZStd::string filePath, FileTagType fileTagType, AZStd::vector<AZStd::string> fileTags, AzFramework::FileTag::FilePatternType filePatternType)
{
{
if (!NormalizeFileAndLowerCaseTags(filePath, filePatternType, fileTags))
{
return AZ::Failure(AZStd::string::format("Unable to normalize file (%s). Unable to remove the file.\n", filePath.c_str()));
@@ -243,11 +245,10 @@ namespace AzFramework
AZStd::string FileTagQueryManager::GetDefaultFileTagFilePath(FileTagType fileTagType)
{
AZStd::string destinationFilePath;
const char* engineRoot = nullptr;
AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot);
AzFramework::StringFunc::Path::ConstructFull(engineRoot, EngineName, fileTagType == FileTagType::Exclude ? ExcludeFileName : IncludeFileName, AzFramework::FileTag::FileTagAsset::Extension(), destinationFilePath, true);
return destinationFilePath;
auto destinationFilePath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / EngineAssetSourceRelPath;
destinationFilePath /= fileTagType == FileTagType::Exclude ? ExcludeFileName : IncludeFileName;
destinationFilePath.ReplaceExtension(AzFramework::FileTag::FileTagAsset::Extension());
return destinationFilePath.String();
}
bool FileTagQueryManager::Load(const AZStd::string& filePath)
@@ -296,4 +296,4 @@ namespace AZ
return static_cast<int>(bytesWritten);
}
} // namespace IO
} // namespace AZ
} // namespace AZ
@@ -41,4 +41,4 @@ namespace AZ
}
}
#endif // #ifndef CRYCOMMON_FILEOPERATIONS_H
#endif // #ifndef CRYCOMMON_FILEOPERATIONS_H
@@ -253,4 +253,4 @@ namespace AzFramework
{
return m_rolloverLength;
}
};
};
@@ -143,4 +143,4 @@ namespace GridMate
};
}
#endif
#endif
@@ -73,4 +73,4 @@ namespace GridMate
};
}
#endif
#endif
@@ -44,8 +44,8 @@ namespace AzFramework
"Network Binding", "The Network Binding component marks an entity as able to be replicated across the network")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Category, "Networking")
->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/NetBinding.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/NetBinding.png")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NetBinding.svg")
->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/NetBinding.png")
->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-network-binding.html")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c));
}
@@ -35,4 +35,4 @@ namespace AzFramework
};
using NetSystemRequestBus = AZ::EBus<NetSystemRequests>;
}
}
@@ -32,4 +32,4 @@ namespace Physics
;
}
}
} // Physics
} // Physics
@@ -34,4 +34,4 @@ namespace Physics
CharacterColliderConfiguration m_clothConfig;
CharacterColliderConfiguration m_simulatedObjectColliderConfig;
};
} // namespace Physics
} // namespace Physics
@@ -28,7 +28,7 @@ namespace Physics
class CharacterColliderNodeConfiguration
{
public:
AZ_RTTI(CharacterColliderNodeConfiguration, "{C16F3301-0979-400C-B734-692D83755C39}");
AZ_RTTI(Physics::CharacterColliderNodeConfiguration, "{C16F3301-0979-400C-B734-692D83755C39}");
AZ_CLASS_ALLOCATOR_DECL
virtual ~CharacterColliderNodeConfiguration() = default;
@@ -42,7 +42,7 @@ namespace Physics
class CharacterColliderConfiguration
{
public:
AZ_RTTI(CharacterColliderConfiguration, "{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}");
AZ_RTTI(Physics::CharacterColliderConfiguration, "{4DFF1434-DF5B-4ED5-BE0F-D3E66F9B331A}");
AZ_CLASS_ALLOCATOR_DECL
virtual ~CharacterColliderConfiguration() = default;
@@ -63,21 +63,23 @@ namespace Physics
{
public:
AZ_CLASS_ALLOCATOR(CharacterConfiguration, AZ::SystemAllocator, 0);
AZ_RTTI(CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
AZ_RTTI(Physics::CharacterConfiguration, "{58D5A6CA-113B-4AC3-8D53-239DB0C4E240}", AzPhysics::SimulatedBodyConfiguration);
virtual ~CharacterConfiguration() = default;
static void Reflect(AZ::ReflectContext* context);
AzPhysics::CollisionGroups::Id m_collisionGroupId; ///< Which layers does this character collide with.
AzPhysics::CollisionLayer m_collisionLayer; ///< Which collision layer is this character on.
MaterialSelection m_materialSelection; ///< Material selected from library for the body associated with the character.
AZ::Vector3 m_upDirection = AZ::Vector3::CreateAxisZ(); ///< Up direction for character orientation and step behavior.
float m_maximumSlopeAngle = 30.0f; ///< The maximum slope on which the character can move, in degrees.
float m_stepHeight = 0.5f; ///< Affects what size steps the character can climb.
float m_minimumMovementDistance = 0.001f; ///< To avoid jittering, the controller will not attempt to move distances below this.
float m_maximumSpeed = 100.0f; ///< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
AZStd::string m_colliderTag; ///< Used to identify the collider associated with the character controller.
AzPhysics::CollisionGroups::Id m_collisionGroupId; //!< Which layers does this character collide with.
AzPhysics::CollisionLayer m_collisionLayer; //!< Which collision layer is this character on.
MaterialSelection m_materialSelection; //!< Material selected from library for the body associated with the character.
AZ::Vector3 m_upDirection = AZ::Vector3::CreateAxisZ(); //!< Up direction for character orientation and step behavior.
float m_maximumSlopeAngle = 30.0f; //!< The maximum slope on which the character can move, in degrees.
float m_stepHeight = 0.5f; //!< Affects what size steps the character can climb.
float m_minimumMovementDistance = 0.001f; //!< To avoid jittering, the controller will not attempt to move distances below this.
float m_maximumSpeed = 100.0f; //!< If the accumulated requested velocity for a tick exceeds this magnitude, it will be clamped.
AZStd::string m_colliderTag; //!< Used to identify the collider associated with the character controller.
AZStd::shared_ptr<Physics::ShapeConfiguration> m_shapeConfig; //!< The shape to use when creating the character controller.
AZStd::vector<AZStd::shared_ptr<Physics::Shape>> m_colliders; //!< The list of colliders to attach to the character controller.
};
/// Basic implementation of common character-style needs as a WorldBody. Is not a full-functional ship-ready
@@ -88,7 +90,7 @@ namespace Physics
{
public:
AZ_CLASS_ALLOCATOR(Character, AZ::SystemAllocator, 0);
AZ_RTTI(Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
AZ_RTTI(Physics::Character, "{962E37A1-3401-4672-B896-0A6157CFAC97}", AzPhysics::SimulatedBody);
~Character() override = default;
@@ -55,7 +55,7 @@ namespace AzPhysics
//! Flag to determine if the body is part of the simulation.
//! When true the body will be affected by any forces, collisions, and found with scene queries.
bool m_simulating = true;
bool m_simulating = false;
//! Helper functions for setting user data.
//! @param userData Can be a pointer to any type as internally will be cast to a void*. Object lifetime not managed by the SimulatedBody.
@@ -46,6 +46,7 @@ namespace AzPhysics
->Field("orientation", &SimulatedBodyConfiguration::m_orientation)
->Field("scale", &SimulatedBodyConfiguration::m_scale)
->Field("entityId", &SimulatedBodyConfiguration::m_entityId)
->Field("startSimulationEnabled", &SimulatedBodyConfiguration::m_startSimulationEnabled)
;
}
}
@@ -29,7 +29,7 @@ namespace AzPhysics
struct SimulatedBodyConfiguration
{
AZ_CLASS_ALLOCATOR_DECL;
AZ_RTTI(SimulatedBodyConfiguration, "{52844E3D-79C8-4F34-AF63-5C45ADE77F85}");
AZ_RTTI(AzPhysics::SimulatedBodyConfiguration, "{52844E3D-79C8-4F34-AF63-5C45ADE77F85}");
static void Reflect(AZ::ReflectContext* context);
SimulatedBodyConfiguration() = default;
@@ -39,6 +39,7 @@ namespace AzPhysics
AZ::Vector3 m_position = AZ::Vector3::CreateZero();
AZ::Quaternion m_orientation = AZ::Quaternion::CreateIdentity();
AZ::Vector3 m_scale = AZ::Vector3::CreateOne();
bool m_startSimulationEnabled = true;
// Entity/object association.
AZ::EntityId m_entityId = AZ::EntityId(AZ::EntityId::InvalidEntityId);
@@ -22,4 +22,4 @@ namespace Physics
const static AZ::Crc32 CollisionGroupSelector = AZ_CRC("CollisionGroupSelector", 0x7d498664);
const static AZ::Crc32 MaterialIdSelector = AZ_CRC("MaterialIdSelector", 0x494511ad);
}
}
}
@@ -52,6 +52,11 @@ namespace Physics
}
}
RagdollConfiguration::RagdollConfiguration()
{
m_startSimulationEnabled = false; //ragdolls do not start enabled.
}
void RagdollConfiguration::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
@@ -24,6 +24,8 @@
namespace Physics
{
using ParentIndices = AZStd::vector<size_t>;
class RagdollNodeConfiguration
: public AzPhysics::RigidBodyConfiguration
{
@@ -46,7 +48,7 @@ namespace Physics
AZ_RTTI(RagdollConfiguration, "{7C96D332-61D8-4C58-A2BF-707716D38D14}", AzPhysics::SimulatedBodyConfiguration);
static void Reflect(AZ::ReflectContext* context);
RagdollConfiguration() = default;
RagdollConfiguration();
explicit RagdollConfiguration(const RagdollConfiguration& settings) = default;
RagdollNodeConfiguration* FindNodeConfigByName(const AZStd::string& nodeName) const;
@@ -56,6 +58,8 @@ namespace Physics
AZStd::vector<RagdollNodeConfiguration> m_nodes;
CharacterColliderConfiguration m_colliders;
RagdollState m_initialState;
ParentIndices m_parentIndices;
};
/// Represents a single rigid part of a ragdoll.
@@ -79,7 +83,7 @@ namespace Physics
{
public:
AZ_CLASS_ALLOCATOR(Ragdoll, AZ::SystemAllocator, 0);
AZ_RTTI(Ragdoll, "{01F09602-80EC-4693-A0E7-C2719239044B}", AzPhysics::SimulatedBody);
AZ_RTTI(Physics::Ragdoll, "{01F09602-80EC-4693-A0E7-C2719239044B}", AzPhysics::SimulatedBody);
virtual ~Ragdoll() = default;
/// Inserts the ragdoll into the physics simulation.
@@ -26,6 +26,22 @@ namespace Physics
->Field("Scale", &ShapeConfiguration::m_scale)
;
}
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
{
#define REFLECT_SHAPETYPE_ENUM_VALUE(EnumValue) \
behaviorContext->EnumProperty<(int)Physics::ShapeType::EnumValue>("ShapeType_"#EnumValue) \
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) \
->Attribute(AZ::Script::Attributes::Module, "physics");
// Note: Here we only expose the types that are available to the user in the editor
REFLECT_SHAPETYPE_ENUM_VALUE(Box);
REFLECT_SHAPETYPE_ENUM_VALUE(Sphere);
REFLECT_SHAPETYPE_ENUM_VALUE(Cylinder);
REFLECT_SHAPETYPE_ENUM_VALUE(PhysicsAsset);
#undef REFLECT_SHAPETYPE_ENUM_VALUE
}
}
void SphereShapeConfiguration::Reflect(AZ::ReflectContext* context)
@@ -246,26 +246,6 @@ namespace Physics
using SystemRequests = System;
using SystemRequestBus = AZ::EBus<SystemRequests, SystemRequestsTraits>;
/// Physics character system global requests.
class CharacterSystemRequests
: public AZ::EBusTraits
{
public:
// EBusTraits
// singleton pattern
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual ~CharacterSystemRequests() = default;
/// Creates the physics representation used to handle basic character interactions (also known as a character
/// controller).
virtual AZStd::unique_ptr<Character> CreateCharacter(const CharacterConfiguration& characterConfig,
const ShapeConfiguration& shapeConfig, AzPhysics::SceneHandle& sceneHandle) = 0;
};
typedef AZ::EBus<CharacterSystemRequests> CharacterSystemRequestBus;
/// Physics system global debug requests.
class SystemDebugRequests
: public AZ::EBusTraits
@@ -41,9 +41,10 @@ namespace AzFramework::ProjectManager
// at the end of the function
AZ::CommandLine commandLine;
commandLine.Parse(argc, argv);
AZ::SettingsRegistryImpl settingsRegistry;
// Store the Command line to the Setting Registry
AZ::SettingsRegistryMergeUtils::ParseCommandLine(commandLine);
// Store the Command line to the Setting Registry
AZ::SettingsRegistryImpl settingsRegistry;
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
@@ -68,7 +69,14 @@ namespace AzFramework::ProjectManager
// If we were able to locate a path to a project, we're done
if (!projectRootPath.empty())
{
return ProjectPathCheckResult::ProjectPathFound;
AZ::IO::FixedMaxPath projectJsonPath = engineRootPath / projectRootPath / "project.json";
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
return ProjectPathCheckResult::ProjectPathFound;
}
AZ_TracePrintf(
"ProjectManager", "Did not find a project file at location '%s', launching the Project Manager...",
projectJsonPath.c_str());
}
if (LaunchProjectManager(engineRootPath))
@@ -14,9 +14,9 @@
#include <AzCore/std/algorithm.h>
#include <AzCore/std/sort.h>
#include <AzFramework/Entity/EntityContext.h>
#include <AzFramework/Render/Intersector.h>
#include <AzFramework/Scene/Scene.h>
#include <AzFramework/Scene/SceneSystemBus.h>
#include <AzFramework/Visibility/BoundsBus.h>
#include <algorithm>
@@ -30,11 +30,11 @@ namespace AzFramework
{
IntersectorBus::Handler::BusConnect(m_contextId);
IntersectionNotificationBus::Handler::BusConnect(m_contextId);
Scene* scene = nullptr;
SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, m_contextId);
AZStd::shared_ptr<Scene> scene = EntityContext::FindContainingScene(m_contextId);
if (scene)
{
scene->SetSubsystem<IntersectorInterface>(this);
scene->SetSubsystem(this);
}
}
@@ -42,11 +42,12 @@ namespace AzFramework
{
IntersectorBus::Handler::BusDisconnect();
IntersectionNotificationBus::Handler::BusDisconnect();
Scene* scene = nullptr;
SceneSystemRequestBus::BroadcastResult(scene, &AzFramework::SceneSystemRequestBus::Events::GetSceneFromEntityContextId, m_contextId);
AZStd::shared_ptr<Scene> scene = EntityContext::FindContainingScene(m_contextId);
if (scene)
{
scene->UnsetSubsystem<IntersectorInterface>();
[[maybe_unused]] bool result = scene->UnsetSubsystem(this);
AZ_Assert(result, "Failed to unregister Intersector with scene");
}
}
@@ -33,6 +33,8 @@ namespace AzFramework
, protected IntersectionNotificationBus::Handler
{
public:
AZ_TYPE_INFO(AzFramework::RenderGeometry::Intersector, "{4CCA7971-CD83-4856-ADEA-89CEB41FB197}");
Intersector(AzFramework::EntityContextId contextId);
~Intersector();
@@ -14,13 +14,102 @@
namespace AzFramework
{
Scene::Scene(AZStd::string_view name)
: m_name(name)
Scene::Scene(AZStd::string name)
: m_name(AZStd::move(name))
{
}
const AZStd::string& Scene::GetName()
Scene::Scene(AZStd::string name, AZStd::shared_ptr<Scene> parent)
: m_name(AZStd::move(name))
, m_parent(AZStd::move(parent))
{
}
Scene::~Scene()
{
m_removalEvent.Signal(*this, RemovalEventType::Destroyed);
}
const AZStd::string& Scene::GetName() const
{
return m_name;
}
}
const AZStd::shared_ptr<Scene>& Scene::GetParent()
{
return m_parent;
}
AZStd::shared_ptr<const Scene> Scene::GetParent() const
{
return m_parent;
}
bool Scene::IsAlive() const
{
return m_isAlive;
}
void Scene::ConnectToEvents(RemovalEvent::Handler& handler)
{
handler.Connect(m_removalEvent);
}
void Scene::ConnectToEvents(SubsystemEvent::Handler& handler)
{
handler.Connect(m_subsystemEvent);
}
AZStd::any* Scene::FindSubsystem(const AZ::TypeId& typeId)
{
AZStd::any* result = FindSubsystemInScene(typeId);
return (!result && m_parent) ? m_parent->FindSubsystem(typeId) : result;
}
const AZStd::any* Scene::FindSubsystem(const AZ::TypeId& typeId) const
{
return const_cast<Scene*>(this)->FindSubsystem(typeId);
}
AZStd::any* Scene::FindSubsystemInScene(const AZ::TypeId& typeId)
{
// Spot check that the internal arrays remain consistent.
AZ_Assert(
m_systemKeys.size() == m_systemObjects.size(), "Key and object list in AzFramework::Scene '%s' have gone out of sync.",
m_name.c_str());
const size_t m_systemKeysCount = m_systemKeys.size();
for (size_t i = 0; i < m_systemKeysCount; ++i)
{
if (m_systemKeys[i] != typeId)
{
continue;
}
else
{
return &m_systemObjects[i];
}
}
return nullptr;
}
const AZStd::any* Scene::FindSubsystemInScene(const AZ::TypeId& typeId) const
{
return const_cast<Scene*>(this)->FindSubsystemInScene(typeId);
}
void Scene::MarkForDestruction()
{
m_isAlive = false;
m_removalEvent.Signal(*this, RemovalEventType::Zombified);
}
void Scene::RemoveSubsystem(size_t index, const AZ::TypeId& subsystemType)
{
m_systemKeys[index] = m_systemKeys.back();
m_systemObjects[index] = AZStd::move(m_systemObjects.back());
m_systemKeys.pop_back();
m_systemObjects.pop_back();
m_subsystemEvent.Signal(*this, SubsystemEventType::Removed, subsystemType);
}
}
@@ -11,10 +11,14 @@
*/
#pragma once
#include <AzCore/EBus/Event.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/string/string.h>
#include <AzCore/Memory/SystemAllocator.h>
#include <AzCore/std/any.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/string/string_view.h>
namespace AzFramework
{
@@ -24,71 +28,100 @@ namespace AzFramework
AZ_TYPE_INFO(Scene, "{DB449BB3-7A95-434D-BC61-47ACBB1F3436}");
AZ_CLASS_ALLOCATOR(Scene, AZ::SystemAllocator, 0);
explicit Scene(AZStd::string_view name);
friend class ISceneSystem;
const AZStd::string& GetName();
constexpr static AZStd::string_view MainSceneName = "Main";
constexpr static AZStd::string_view EditorMainSceneName = "Editor";
enum class RemovalEventType
{
Zombified, // The scene has be marked for destruction and is no longer visible in the scene system.
Destroyed, // The scene has been destroyed.
};
using RemovalEvent = AZ::Event<Scene&, RemovalEventType>;
enum class SubsystemEventType
{
Added,
Removed
};
using SubsystemEvent = AZ::Event<Scene&, SubsystemEventType, const AZ::TypeId&>;
explicit Scene(AZStd::string name);
Scene(AZStd::string name, AZStd::shared_ptr<Scene> parent);
~Scene();
[[nodiscard]] const AZStd::string& GetName() const;
[[nodiscard]] const AZStd::shared_ptr<Scene>& GetParent();
[[nodiscard]] AZStd::shared_ptr<const Scene> GetParent() const;
[[nodiscard]] bool IsAlive() const;
void ConnectToEvents(RemovalEvent::Handler& handler);
void ConnectToEvents(SubsystemEvent::Handler& handler);
// Set the instance of a subsystem associated with this scene.
template <typename T>
bool SetSubsystem(T* system);
bool SetSubsystem(T&& system);
// Unset the instance of a subsystem associated with this scene.
template <typename T>
bool UnsetSubsystem();
// Get the instance of a subsystem associated with this scene.
// Unset the instance of the exact system associated with this scene.
// Use this to make sure the expected instance is removed or to make sure type deduction is done in the same way as during setting.
template<typename T>
bool UnsetSubsystem(const T& system);
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
[[nodiscard]] AZStd::any* FindSubsystem(const AZ::TypeId& typeId);
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
[[nodiscard]] const AZStd::any* FindSubsystem(const AZ::TypeId& typeId) const;
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
template <typename T>
T* GetSubsystem();
[[nodiscard]] T* FindSubsystem();
// Get the instance of a subsystem associated with this scene. This call will also look in parent scenes if not found on the target
// scene. Returns a pointer to the subsystem if found, otherwise returns a nullptr.
template<typename T>
[[nodiscard]] const T* FindSubsystem() const;
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
// the subsystem if found, otherwise returns a nullptr.
[[nodiscard]] AZStd::any* FindSubsystemInScene(const AZ::TypeId& typeId);
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
// the subsystem if found, otherwise returns a nullptr.
[[nodiscard]] const AZStd::any* FindSubsystemInScene(const AZ::TypeId& typeId) const;
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
// the subsystem if found, otherwise returns a nullptr.
template<typename T>
[[nodiscard]] T* FindSubsystemInScene();
// Get the instance of a subsystem associated with this scene. This call will only look in the selected scene. Returns a pointer to
// the subsystem if found, otherwise returns a nullptr.
template<typename T>
[[nodiscard]] const T* FindSubsystemInScene() const;
private:
void MarkForDestruction();
void RemoveSubsystem(size_t index, const AZ::TypeId& subsystemType);
AZStd::string m_name;
RemovalEvent m_removalEvent;
SubsystemEvent m_subsystemEvent;
// Storing keys separate from data to optimize for fast key search.
AZStd::vector<AZ::TypeId> m_systemKeys;
AZStd::vector<void*> m_systemPointers;
AZStd::vector<AZStd::any> m_systemObjects;
// Name that identifies the scene.
AZStd::string m_name;
// Parent to this scene. Any subsystems are inherited from the parent but can be overwritten locally.
AZStd::shared_ptr<Scene> m_parent;
// If false, the scene has been removed from scene system and can no longer be found. As soon as all handles to the scene are
// released it will be destroyed.
bool m_isAlive{ true };
};
template <typename T>
bool Scene::SetSubsystem(T* system)
{
if (GetSubsystem<T>() != nullptr)
{
return false;
}
m_systemKeys.push_back(T::RTTI_Type());
m_systemPointers.push_back(system);
return true;
}
} // AzFramework
template <typename T>
bool Scene::UnsetSubsystem()
{
for (size_t i = 0; i < m_systemKeys.size(); ++i)
{
if (m_systemKeys.at(i) == T::RTTI_Type())
{
m_systemKeys.at(i) = m_systemKeys.back();
m_systemKeys.pop_back();
m_systemPointers.at(i) = m_systemPointers.back();
m_systemPointers.pop_back();
return true;
}
}
return false;
}
template <typename T>
T* Scene::GetSubsystem()
{
for (size_t i = 0; i < m_systemKeys.size(); ++i)
{
if (m_systemKeys.at(i) == T::RTTI_Type())
{
return reinterpret_cast<T*>(m_systemPointers.at(i));
}
}
return nullptr;
}
} // AzFramework
#include <AzFramework/Scene/Scene.inl>
@@ -0,0 +1,108 @@
/*
* 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.
*
*/
namespace AzFramework
{
template<typename T>
bool Scene::SetSubsystem(T&& system)
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
for (const AZ::TypeId& key : m_systemKeys)
{
if (key == targetType)
{
return false;
}
}
m_systemKeys.push_back(targetType);
m_systemObjects.emplace_back(AZStd::forward<T>(system));
m_subsystemEvent.Signal(*this, SubsystemEventType::Added, targetType);
return true;
}
template<typename T>
bool Scene::UnsetSubsystem()
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
const size_t m_systemKeysCount = m_systemKeys.size();
for (size_t i = 0; i < m_systemKeysCount; ++i)
{
if (m_systemKeys[i] != targetType)
{
continue;
}
else
{
RemoveSubsystem(i, targetType);
return true;
}
}
return false;
}
template<typename T>
bool Scene::UnsetSubsystem([[maybe_unused]] const T& system)
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
const size_t systemKeysCount = m_systemKeys.size();
for (size_t i = 0; i < systemKeysCount; ++i)
{
if (m_systemKeys[i] != targetType)
{
continue;
}
else
{
[[maybe_unused]] T* instance = AZStd::any_cast<T>(&m_systemObjects[i]);
AZ_Assert(
instance && *instance == system,
"Subsystem being released matched type, but wasn't pointing to the same system that was stored.");
RemoveSubsystem(i, targetType);
return true;
}
}
return false;
}
template<typename T>
T* Scene::FindSubsystem()
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
AZStd::any* subSystem = FindSubsystem(targetType);
return subSystem ? AZStd::any_cast<T>(subSystem) : nullptr;
}
template<typename T>
const T* Scene::FindSubsystem() const
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
const AZStd::any* subSystem = FindSubsystem(targetType);
return subSystem ? AZStd::any_cast<const T>(subSystem) : nullptr;
}
template<typename T>
T* Scene::FindSubsystemInScene()
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
AZStd::any* subSystem = FindSubsystemInScene(targetType);
return subSystem ? AZStd::any_cast<T>(subSystem) : nullptr;
}
template<typename T>
const T* Scene::FindSubsystemInScene() const
{
const AZ::TypeId& targetType = azrtti_typeid<T>();
const AZStd::any* subSystem = FindSubsystemInScene(targetType);
return subSystem ? AZStd::any_cast<const T>(subSystem) : nullptr;
}
} // namespace AzFramework
@@ -1,114 +0,0 @@
/*
* 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 <AzFramework/Entity/EntityContext.h>
namespace AzFramework
{
// Forward declarations
class Scene;
//! Interface used to create, get, or destroy scenes.
class SceneSystemRequests
: public AZ::EBusTraits
{
public:
virtual ~SceneSystemRequests() = default;
//! Single handler policy since there should only be one instance of this system component.
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
//! Creates a scene with a given name.
//! - If there is already a scene with the provided name this will return AZ::Failure().
//! - If isDefault is set to true and there is already a default scene, the default scene will be switched to this one.
virtual AZ::Outcome<Scene*, AZStd::string> CreateScene(AZStd::string_view name) = 0;
//! Gets a scene with a given name
//! - If a scene does not exist with the given name, nullptr is returned.
virtual Scene* GetScene(AZStd::string_view name) = 0;
//! Gets all the scenes that currently exist.
virtual AZStd::vector<Scene*> GetAllScenes() = 0;
//! Remove a scene with a given name and return if the operation was successful.
//! - If the removed scene is the default scene, there will no longer be a default scene.
virtual bool RemoveScene(AZStd::string_view name) = 0;
//! Add a mapping from the provided EntityContextId to a Scene
//! - If a scene is already associated with this EntityContextId, nothing is changed and false is returned.
virtual bool SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) = 0;
//! Remove a mapping from the provided EntityContextId to a Scene
//! - If no scene is found from the provided EntityContextId, false is returned.
virtual bool RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) = 0;
//! Get the scene associated with an EntityContextId
//! - If no scene is found for the provided EntityContextId, nullptr is returned.
virtual Scene* GetSceneFromEntityContextId(EntityContextId entityContextId) = 0;
};
using SceneSystemRequestBus = AZ::EBus<SceneSystemRequests>;
//! Interface used for notifications from the scene system
class SceneSystemNotifications
: public AZ::EBusTraits
{
public:
virtual ~SceneSystemNotifications() = default;
//! There can be multiple listeners to changes in the scene system.
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
//! Called when a scene has been created.
virtual void SceneCreated(Scene& /*scene*/) {};
//! Called just before a scene is removed.
virtual void SceneAboutToBeRemoved(Scene& /*scene*/) {};
};
using SceneSystemNotificationBus = AZ::EBus<SceneSystemNotifications>;
//! Interface used for notifications about individual scenes
class SceneNotifications
: public AZ::EBusTraits
{
public:
virtual ~SceneNotifications() = default;
//! There can be multiple listeners to changes in the scene system.
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
//! Bus is listened to using the pointer of the scene
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById;
//! Specifies that events are addressed by the pointer to the scene
using BusIdType = Scene*;
//! Called just before a scene is removed.
virtual void SceneAboutToBeRemoved() {};
//! Called when an entity context is mapped to this scene.
virtual void EntityContextMapped(EntityContextId /*entityContextId*/) {};
//! Called when an entity context is unmapped from this scene.
virtual void EntityContextUnmapped(EntityContextId /*entityContextId*/) {};
};
using SceneNotificationBus = AZ::EBus<SceneNotifications>;
} // AzFramework
@@ -14,7 +14,7 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzFramework/Scene/Scene.h>
#include <AzCore/std/smart_ptr/make_shared.h>
namespace AzFramework
{
@@ -41,14 +41,10 @@ namespace AzFramework
void SceneSystemComponent::Activate()
{
// Connect busses
SceneSystemRequestBus::Handler::BusConnect();
}
void SceneSystemComponent::Deactivate()
{
// Disconnect Busses
SceneSystemRequestBus::Handler::BusDisconnect();
}
void SceneSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
@@ -61,140 +57,105 @@ namespace AzFramework
incompatible.push_back(AZ_CRC("SceneSystemComponentService", 0xd8975435));
}
AZ::Outcome<Scene*, AZStd::string> SceneSystemComponent::CreateScene(AZStd::string_view name)
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> SceneSystemComponent::CreateScene(AZStd::string_view name)
{
Scene* existingScene = GetScene(name);
return CreateSceneWithParent(name, nullptr);
}
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> SceneSystemComponent::CreateSceneWithParent(
AZStd::string_view name, AZStd::shared_ptr<Scene> parent)
{
const AZStd::shared_ptr<Scene>& existingScene = GetScene(name);
if (existingScene)
{
return AZ::Failure<AZStd::string>("A scene already exists with this name.");
}
auto newScene = AZStd::make_unique<Scene>(name);
Scene* scenePointer = newScene.get();
m_scenes.push_back(AZStd::move(newScene));
SceneSystemNotificationBus::Broadcast(&SceneSystemNotificationBus::Events::SceneCreated, *scenePointer);
return AZ::Success(scenePointer);
auto newScene = AZStd::make_shared<Scene>(name, AZStd::move(parent));
m_activeScenes.push_back(newScene);
{
AZStd::lock_guard lock(m_eventMutex);
m_events.Signal(EventType::SceneCreated, newScene);
}
return AZ::Success(AZStd::move(newScene));
}
Scene* SceneSystemComponent::GetScene(AZStd::string_view name)
AZStd::shared_ptr<Scene> SceneSystemComponent::GetScene(AZStd::string_view name)
{
auto sceneIterator = AZStd::find_if(m_scenes.begin(), m_scenes.end(),
auto sceneIterator = AZStd::find_if(m_activeScenes.begin(), m_activeScenes.end(),
[name](auto& scene) -> bool
{
return scene->GetName() == name;
}
);
return sceneIterator == m_scenes.end() ? nullptr : sceneIterator->get();
return sceneIterator == m_activeScenes.end() ? nullptr : *sceneIterator;
}
AZStd::vector<Scene*> SceneSystemComponent::GetAllScenes()
void SceneSystemComponent::IterateActiveScenes(const ActiveIterationCallback& callback)
{
AZStd::vector<Scene*> scenes;
scenes.resize_no_construct(m_scenes.size());
for (size_t i = 0; i < m_scenes.size(); ++i)
bool keepGoing = true;
auto end = m_activeScenes.end();
for (auto it = m_activeScenes.begin(); it != end && keepGoing; ++it)
{
scenes.at(i) = m_scenes.at(i).get();
keepGoing = callback(*it);
}
}
void SceneSystemComponent::IterateZombieScenes(const ZombieIterationCallback& callback)
{
bool keepGoing = true;
auto end = m_zombieScenes.end();
for (auto it = m_zombieScenes.begin(); it != end && keepGoing;)
{
if (!it->expired())
{
keepGoing = callback(*(it->lock()));
++it;
}
else
{
*it = m_zombieScenes.back();
m_zombieScenes.pop_back();
end = m_zombieScenes.end();
}
}
return scenes;
}
bool SceneSystemComponent::RemoveScene(AZStd::string_view name)
{
for (size_t i = 0; i < m_scenes.size(); ++i)
for (AZStd::shared_ptr<Scene>& scene : m_activeScenes)
{
auto& scenePtr = m_scenes.at(i);
if (scenePtr->GetName() == name)
if (scene->GetName() == name)
{
// Remove any entityContext mappings.
Scene* scene = scenePtr.get();
for (auto entityContextScenePairIt = m_entityContextToScenes.begin(); entityContextScenePairIt != m_entityContextToScenes.end();)
MarkSceneForDestruction(*scene);
{
AZStd::pair<EntityContextId, Scene*>& pair = *entityContextScenePairIt;
if (pair.second == scene)
{
// swap and pop back.
*entityContextScenePairIt = m_entityContextToScenes.back();
m_entityContextToScenes.pop_back();
}
else
{
++entityContextScenePairIt;
}
AZStd::lock_guard lock(m_eventMutex);
m_events.Signal(EventType::ScenePendingRemoval, scene);
}
SceneSystemNotificationBus::Broadcast(&SceneSystemNotificationBus::Events::SceneAboutToBeRemoved, *scene);
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::SceneAboutToBeRemoved);
m_scenes.erase(&scenePtr);
// Zombies are weak pointers that are kept around for situations where there's a delay in deleting the scene. This can happen
// if there are outstanding calls like in-progress async calls or resources locked by hardware. A weak_ptr of the original
// scene is kept so the zombie scene can still be found through iteration as it may require additional calls such as Tick calls.
m_zombieScenes.push_back(scene);
scene = AZStd::move(m_activeScenes.back());
m_activeScenes.pop_back();
// The scene may not be held onto anymore, so check here to see if the previously added zombie can be released.
if (m_zombieScenes.back().expired())
{
m_zombieScenes.pop_back();
}
return true;
}
}
AZ_Warning("SceneSystemComponent", false, "Attempting to remove scene name \"%.*s\", but that scene was not found.", static_cast<int>(name.size()), name.data());
AZ_Warning("SceneSystemComponent", false, R"(Attempting to remove scene name "%.*s", but that scene was not found.)", AZ_STRING_ARG(name));
return false;
}
bool SceneSystemComponent::SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene)
void SceneSystemComponent::ConnectToEvents(SceneEvent::Handler& handler)
{
Scene* existingSceneForEntityContext = GetSceneFromEntityContextId(entityContextId);
if (existingSceneForEntityContext)
{
// This entity context is already mapped and must be unmapped explictely before it can be changed.
char entityContextIdString[EntityContextId::MaxStringBuffer];
entityContextId.ToString(entityContextIdString, sizeof(entityContextIdString));
AZ_Warning("SceneSystemComponent", false, "Failed to set a scene for entity context %s, scene is already set for that entity context.", entityContextIdString);
return false;
}
m_entityContextToScenes.emplace_back(entityContextId, scene);
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::EntityContextMapped, entityContextId);
return true;
AZStd::lock_guard lock(m_eventMutex);
handler.Connect(m_events);
}
bool SceneSystemComponent::RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene)
{
if (!scene || entityContextId.IsNull())
{
return false;
}
for (auto entityContextScenePairIt = m_entityContextToScenes.begin(); entityContextScenePairIt != m_entityContextToScenes.end();)
{
AZStd::pair<EntityContextId, Scene*>& pair = *entityContextScenePairIt;
if (!(pair.first == entityContextId && pair.second == scene))
{
++entityContextScenePairIt;
}
else
{
// swap and pop back.
*entityContextScenePairIt = m_entityContextToScenes.back();
m_entityContextToScenes.pop_back();
SceneNotificationBus::Event(scene, &SceneNotificationBus::Events::EntityContextUnmapped, entityContextId);
return true;
}
}
char entityContextIdString[EntityContextId::MaxStringBuffer];
entityContextId.ToString(entityContextIdString, sizeof(entityContextIdString));
AZ_Warning("SceneSystemComponent", false, "Failed to remove scene \"%.*s\" for entity context %s, entity context is not currently mapped to that scene.", static_cast<int>(scene->GetName().size()), scene->GetName().data(), entityContextIdString);
return false;
}
Scene* SceneSystemComponent::GetSceneFromEntityContextId(EntityContextId entityContextId)
{
for (AZStd::pair<EntityContextId, Scene*>& pair : m_entityContextToScenes)
{
if (pair.first == entityContextId)
{
return pair.second;
}
}
return nullptr;
}
} // AzFramework
} // namespace AzFramework
@@ -13,18 +13,18 @@
#include <AzCore/Component/Component.h>
#include <AzCore/std/containers/map.h>
#include <AzFramework/Scene/SceneSystemBus.h>
#include <AzCore/std/parallel/mutex.h>
#include <AzFramework/Scene/SceneSystemInterface.h>
#include <AzFramework/Entity/EntityContext.h>
namespace AzFramework
{
class SceneSystemComponent
: public AZ::Component
, public SceneSystemRequestBus::Handler
, public SceneSystemInterface::Registrar
{
public:
AZ_COMPONENT(SceneSystemComponent, "{7AC53AF0-BE1A-437C-BE3E-4D6A998DA945}", AZ::Component);
AZ_COMPONENT(SceneSystemComponent, "{7AC53AF0-BE1A-437C-BE3E-4D6A998DA945}", AZ::Component, ISceneSystem);
SceneSystemComponent();
~SceneSystemComponent() override;
@@ -41,24 +41,26 @@ namespace AzFramework
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
//////////////////////////////////////////////////////////////////////////
// SceneSystemRequestsBus::Handler
// SceneSystemInterface overrides
//////////////////////////////////////////////////////////////////////////
AZ::Outcome<Scene*, AZStd::string> CreateScene(AZStd::string_view name) override;
Scene* GetScene(AZStd::string_view name) override;
AZStd::vector<Scene*> GetAllScenes() override;
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateScene(AZStd::string_view name) override;
AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateSceneWithParent(
AZStd::string_view name, AZStd::shared_ptr<Scene> parent) override;
[[nodiscard]] AZStd::shared_ptr<Scene> GetScene(AZStd::string_view name) override;
void IterateActiveScenes(const ActiveIterationCallback& callback) override;
void IterateZombieScenes(const ZombieIterationCallback& callback) override;
bool RemoveScene(AZStd::string_view name) override;
bool SetSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) override;
bool RemoveSceneForEntityContextId(EntityContextId entityContextId, Scene* scene) override;
Scene* GetSceneFromEntityContextId(EntityContextId entityContextId) override;
void ConnectToEvents(SceneEvent::Handler& handler) override;
private:
AZ_DISABLE_COPY_MOVE(SceneSystemComponent);
AZ_DISABLE_COPY(SceneSystemComponent);
// Container of scene in order of creation
AZStd::vector<AZStd::unique_ptr<Scene>> m_scenes;
// Map of entity context Ids to scenes. Using a vector because lookups will be common, but the size will be small.
AZStd::vector<AZStd::pair<EntityContextId, Scene*>> m_entityContextToScenes;
AZStd::vector<AZStd::shared_ptr<Scene>> m_activeScenes;
AZStd::vector<AZStd::weak_ptr<Scene>> m_zombieScenes;
// Using a mutex around the events as other threads may respond to a new/deleted scene by making
// local updates and unregistering themselves. Since Scene is single threaded, no updates (other
// then unregistering an event) should be done from other threads though.
AZStd::recursive_mutex m_eventMutex;
SceneEvent m_events;
};
}
}
@@ -0,0 +1,88 @@
/*
* 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/EBus/Event.h>
#include <AzCore/Interface/Interface.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzCore/std/functional.h>
#include <AzFramework/Entity/EntityContext.h>
#include <AzFramework/Scene/Scene.h>
namespace AzFramework
{
//! Interface used to create, get, or destroy scenes.
//! This interface is single thread and is intended to be called from a single thread, commonly the main thread. The exception
//! is connecting events, which is thread safe.
class ISceneSystem
{
public:
AZ_RTTI(AzFramework::ISceneSystem, "{DAE482A8-88AE-4BD3-8A5B-52D19A96E15F}");
AZ_DISABLE_COPY_MOVE(ISceneSystem);
enum class EventType
{
SceneCreated,
ScenePendingRemoval
};
using SceneEvent = AZ::Event<EventType, const AZStd::shared_ptr<Scene>&>;
ISceneSystem() = default;
virtual ~ISceneSystem() = default;
using ActiveIterationCallback = AZStd::function<bool(const AZStd::shared_ptr<Scene>& scene)>;
using ZombieIterationCallback = AZStd::function<bool(Scene& scene)>;
//! Creates a scene with a given name.
//! - If there is already a scene with the provided name this will return AZ::Failure().
virtual AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateScene(AZStd::string_view name) = 0;
//! Creates a scene with a given name and a parent.
//! - If there is already a scene with the provided name this will return AZ::Failure().
virtual AZ::Outcome<AZStd::shared_ptr<Scene>, AZStd::string> CreateSceneWithParent(
AZStd::string_view name, AZStd::shared_ptr<Scene> parent) = 0;
//! Gets a scene with a given name
//! - If a scene does not exist with the given name, nullptr is returned.
[[nodiscard]] virtual AZStd::shared_ptr<Scene> GetScene(AZStd::string_view name) = 0;
//! Iterates over all scenes that are in active use. Iteration stops if the callback returns false or all scenes have been listed.
virtual void IterateActiveScenes(const ActiveIterationCallback& callback) = 0;
//! Iterates over all zombie scenes. Zombie scenes are scenes that have been removed but still have references held on to. This can
//! happen because scenes hold on to subsystems that can't immediately be deleted. These subsystems may still require being called
//! such as a periodic tick. Iteration stops if the callback returns false or all scenes have been listed.
virtual void IterateZombieScenes(const ZombieIterationCallback& callback) = 0;
//! Remove a scene with a given name and return if the operation was successful.
virtual bool RemoveScene(AZStd::string_view name) = 0;
//! Connects the provided handler to the events that are called after scenes are created or before they get removed.
virtual void ConnectToEvents(SceneEvent::Handler& handler) = 0;
protected:
// Strictly a forwarding function to call private functions on the scene.
void MarkSceneForDestruction(Scene& scene) { scene.MarkForDestruction(); }
};
using SceneSystemInterface = AZ::Interface<ISceneSystem>;
// EBus wrapper for ScriptCanvas
class ISceneSystemRequests
: public AZ::EBusTraits
{
public:
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
};
using ILoggerRequestBus = AZ::EBus<ISceneSystem, ISceneSystemRequests>;
} // AzFramework
@@ -103,4 +103,4 @@ namespace AzFramework
->Field("EBusses", &ScriptDebugRegisteredEBusesResult::m_ebusList);
}
}
} // namespace AzFramework
} // namespace AzFramework
@@ -570,4 +570,4 @@ namespace AzFramework
m_isDirty = false;
}
}
}
@@ -91,4 +91,4 @@ namespace AzFramework
};
}
#endif
#endif
@@ -81,7 +81,7 @@ namespace AzFramework
const char* SpawnableAssetHandler::GetBrowserIcon() const
{
return "Editor/Icons/Components/Viewport/EntityInSlice.png";
return "Icons/Components/Viewport/EntityInSlice.png";
}
void SpawnableAssetHandler::GetAssetTypeExtensions(AZStd::vector<AZStd::string>& extensions)
@@ -85,4 +85,4 @@ namespace AzFramework
DisplayContext* m_prevSetDisplayContext = nullptr;
DisplayContext* m_currSetDisplayContext = nullptr;
};
} // namespace AzFramework
} // namespace AzFramework
@@ -37,6 +37,7 @@ namespace AzFramework
// ViewportControllerInterface ...
bool HandleInputChannelEvent(const ViewportControllerInputEvent& event) override;
void ResetInputChannels() override;
void UpdateViewport(const ViewportControllerUpdateEvent& event) override;
void RegisterViewportContext(ViewportId viewport) override;
void UnregisterViewportContext(ViewportId viewport) override;
@@ -58,6 +59,7 @@ namespace AzFramework
ViewportId GetViewportId() const { return m_viewportId; }
virtual bool HandleInputChannelEvent([[maybe_unused]]const ViewportControllerInputEvent& event) { return false; }
virtual void ResetInputChannels() {}
virtual void UpdateViewport([[maybe_unused]]const ViewportControllerUpdateEvent& event) {}
private:
@@ -30,6 +30,15 @@ namespace AzFramework
return instanceIt->second->HandleInputChannelEvent(event);
}
template <class TViewportControllerInstance, ViewportControllerPriority Priority>
void MultiViewportController<TViewportControllerInstance, Priority>::ResetInputChannels()
{
for (auto instanceIt = m_instances.begin(); instanceIt != m_instances.end(); ++instanceIt)
{
instanceIt->second->ResetInputChannels();
}
}
template <class TViewportControllerInstance, ViewportControllerPriority Priority>
void MultiViewportController<TViewportControllerInstance, Priority>::UpdateViewport(const ViewportControllerUpdateEvent& event)
{
@@ -50,4 +50,4 @@ namespace AzFramework
const AZ::Color DefaultManipulatorHandleColor(0.06275f, 0.1647f, 0.1647f, 1.0f);
} // namespace ViewportColors
} // namespace AzFramework
} // namespace AzFramework
@@ -23,4 +23,4 @@ namespace AzFramework
/// Default linear manipulator axis length.
const float DefaultLinearManipulatorAxisLength = 2.0f;
}// namespace ViewportConstants
}// namespace AzFramework
}// namespace AzFramework
@@ -24,4 +24,4 @@ namespace AzFramework
extern const float DefaultLinearManipulatorAxisLength;
} // namespace ViewportConstants
} // namespace AzFramework
} // namespace AzFramework
@@ -49,6 +49,11 @@ namespace AzFramework
bool ViewportControllerList::HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
if (!IsEnabled())
{
return false;
}
// If our event priority is "custom", we should dispatch at all priority levels in order
using AzFramework::ViewportControllerPriority;
if (event.m_priority == AzFramework::ViewportControllerPriority::DispatchToAllPriorities)
@@ -76,6 +81,23 @@ namespace AzFramework
}
}
void ViewportControllerList::ResetInputChannels()
{
// We don't need to send this while we're disabled, we're guaranteed to call ResetInputChannels after being re-enabled.
if (!IsEnabled())
{
return;
}
for (const auto& controllerList : m_controllers)
{
for (const auto& controller : controllerList.second)
{
controller->ResetInputChannels();
}
}
}
bool ViewportControllerList::DispatchInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event)
{
if (auto priorityListIt = m_controllers.find(event.m_priority); priorityListIt != m_controllers.end())
@@ -106,6 +128,11 @@ namespace AzFramework
void ViewportControllerList::UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event)
{
if (!IsEnabled())
{
return;
}
// If our event priority is "custom", we should dispatch at all priority levels in reverse order
// Reverse order lets high priority controllers get the last say in viewport update operations
using AzFramework::ViewportControllerPriority;
@@ -174,4 +201,22 @@ namespace AzFramework
}
}
}
bool ViewportControllerList::IsEnabled() const
{
return m_enabled;
}
void ViewportControllerList::SetEnabled(bool enabled)
{
if (m_enabled != enabled)
{
m_enabled = enabled;
// If we've been re-enabled, reset our input channels as they may have missed state changes.
if (m_enabled)
{
ResetInputChannels();
}
}
}
} //namespace AzFramework
@@ -37,6 +37,9 @@ namespace AzFramework
//! either a controller returns true to consume the event in OnInputChannelEvent or the controller list is exhausted.
//! InputChannelEvents are sent to controllers in priority order (from the lowest priority value to the highest).
bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override;
//! Dispatches a ResetInputChannels call to all controllers registered to this list.
//! Calls to controllers are made in an undefined order.
void ResetInputChannels() override;
//! Dispatches an update tick to all controllers registered to this list.
//! This occurs in *reverse* priority order (i.e. from the highest priority value to the lowest) so that
//! controllers with the highest registration priority may override the transforms of the controllers with the
@@ -50,6 +53,12 @@ namespace AzFramework
//! All ViewportControllerLists have a priority of Custom to ensure
//! that they receive events at all priorities from any parent controllers.
AzFramework::ViewportControllerPriority GetPriority() const { return ViewportControllerPriority::DispatchToAllPriorities; }
//! Returns true if this controller list is enabled, i.e.
//! it is accepting and forwarding input and update events to its children.
bool IsEnabled() const;
//! Set this controller list's enabled state.
//! If a controller list is disabled, it will ignore all input and update events rather than dispatching them to its children.
void SetEnabled(bool enabled);
private:
void SortControllers();
@@ -58,5 +67,6 @@ namespace AzFramework
AZStd::unordered_map<AzFramework::ViewportControllerPriority, AZStd::vector<ViewportControllerPtr>> m_controllers;
AZStd::unordered_set<ViewportId> m_viewports;
bool m_enabled = true;
};
} //namespace AzFramework
@@ -194,10 +194,11 @@ set(FILES
Logging/MissingAssetLogger.h
Logging/MissingAssetNotificationBus.h
Scene/Scene.h
Scene/Scene.inl
Scene/Scene.cpp
Scene/SceneSystemBus.h
Scene/SceneSystemComponent.h
Scene/SceneSystemComponent.cpp
Scene/SceneSystemInterface.h
Script/ScriptComponent.h
Script/ScriptComponent.cpp
Script/ScriptDebugAgentBus.h
+2 -2
View File
@@ -33,12 +33,12 @@ ly_add_target(
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
PUBLIC
AZ::GridMate
3rdParty::md5
3rdParty::zlib
3rdParty::zstd
3rdParty::lz4
PUBLIC
AZ::GridMate
)
if(LY_ENABLE_STATISTICAL_PROFILING)
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/API/ApplicationAPI_Android.h>
#include <AzFramework/API/ApplicationAPI_Android.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/AzFramework_Traits_Android.h>
#include <AzFramework/AzFramework_Traits_Android.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Android.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Android.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/API/ApplicationAPI_Linux.h>
#include <AzFramework/API/ApplicationAPI_Linux.h>
@@ -13,4 +13,4 @@
#pragma once
#define STREAM_CACHE_DEFAULT 0
#define FRONTEND_SHADER_CACHE_DEFAULT 0
#define FRONTEND_SHADER_CACHE_DEFAULT 0
@@ -29,6 +29,20 @@ namespace AzFramework::AssetSystem::Platform
bool LaunchAssetProcessor(AZStd::string_view executableDirectory, AZStd::string_view engineRoot,
AZStd::string_view projectPath)
{
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
pid_t firstChildPid = fork();
if (firstChildPid == 0)
{
@@ -47,9 +61,6 @@ namespace AzFramework::AssetSystem::Platform
pid_t secondChildPid = fork();
if (secondChildPid == 0)
{
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor";
AZStd::array args {
assetProcessorPath.c_str(), assetProcessorPath.c_str(), "--start-hidden",
static_cast<const char*>(nullptr), static_cast<const char*>(nullptr), static_cast<const char*>(nullptr)
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/AzFramework_Traits_Linux.h>
#include <AzFramework/AzFramework_Traits_Linux.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/API/ApplicationAPI_Mac.h>
#include <AzFramework/API/ApplicationAPI_Mac.h>
@@ -13,4 +13,4 @@
#pragma once
#define STREAM_CACHE_DEFAULT 0
#define FRONTEND_SHADER_CACHE_DEFAULT 0
#define FRONTEND_SHADER_CACHE_DEFAULT 0
@@ -11,6 +11,7 @@
*/
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <sys/types.h>
@@ -20,6 +21,7 @@ namespace AzFramework::AssetSystem::Platform
{
void AllowAssetProcessorToForeground()
{}
bool LaunchAssetProcessor(AZStd::string_view executableDirectory, AZStd::string_view engineRoot,
AZStd::string_view projectPath)
{
@@ -29,6 +31,17 @@ namespace AzFramework::AssetSystem::Platform
assetProcessorPath /= "../../../AssetProcessor.app";
assetProcessorPath = assetProcessorPath.LexicallyNormal();
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.app";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"(open -g "%s" --args --start-hidden)", assetProcessorPath.c_str());
// Add the engine path to the launch command if not empty
if (!engineRoot.empty())
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/AzFramework_Traits_Mac.h>
#include <AzFramework/AzFramework_Traits_Mac.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Mac.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Mac.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/API/ApplicationAPI_Windows.h>
#include <AzFramework/API/ApplicationAPI_Windows.h>
@@ -13,4 +13,4 @@
#pragma once
#define STREAM_CACHE_DEFAULT 0
#define FRONTEND_SHADER_CACHE_DEFAULT 0
#define FRONTEND_SHADER_CACHE_DEFAULT 0
@@ -12,6 +12,7 @@
#include <AzCore/PlatformIncl.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <Psapi.h>
@@ -67,6 +68,17 @@ namespace AzFramework::AssetSystem::Platform
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
assetProcessorPath /= "AssetProcessor.exe";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.exe";
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
return false;
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"("%s" --start-hidden)", assetProcessorPath.c_str());
// Add the engine path to the launch command if not empty
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/AzFramework_Traits_Windows.h>
#include <AzFramework/AzFramework_Traits_Windows.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Windows.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Windows.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/API/ApplicationAPI_iOS.h>
#include <AzFramework/API/ApplicationAPI_iOS.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/AzFramework_Traits_iOS.h>
#include <AzFramework/AzFramework_Traits_iOS.h>
@@ -11,4 +11,4 @@
*/
#pragma once
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_iOS.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_iOS.h>