merge from development

Signed-off-by: greerdv <greerdv@amazon.com>
This commit is contained in:
greerdv
2022-02-07 18:48:03 +00:00
541 changed files with 221662 additions and 6392 deletions
+1 -1
View File
@@ -588,7 +588,7 @@ QMenu* LevelEditorMenuHandler::CreateGameMenu()
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
// Export to Engine
+7 -7
View File
@@ -706,7 +706,7 @@ void CCryEditApp::OnFileSave()
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
@@ -2364,7 +2364,7 @@ void CCryEditApp::ExportLevel(bool bExportToGame, bool bExportTexture, bool bAut
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
AZ_Assert(false, "Prefab system doesn't require level exports.");
@@ -2405,7 +2405,7 @@ bool CCryEditApp::UserExportToGame(bool bNoMsgBox)
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
AZ_Assert(false, "Export Level should no longer exist.");
@@ -2453,7 +2453,7 @@ void CCryEditApp::ExportToGame(bool bNoMsgBox)
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
AZ_Assert(false, "Prefab system no longer exports levels.");
@@ -2961,7 +2961,7 @@ CCryEditApp::ECreateLevelResult CCryEditApp::CreateLevel(const QString& levelNam
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
// If we are creating a new level and we're in simulate mode, then switch it off before we do anything else
if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
@@ -3107,7 +3107,7 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled)
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
QString str = QObject::tr("Level %1 has been changed. Save Level?").arg(GetIEditor()->GetGameEngine()->GetLevelName());
@@ -3321,7 +3321,7 @@ CCryEditDoc* CCryEditApp::OpenDocumentFile(const char* filename, bool addToMostR
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
// If we are loading and we're in simulate mode, then switch it off before we do anything else
if (GetIEditor()->GetGameEngine() && GetIEditor()->GetGameEngine()->GetSimulationMode())
+4 -4
View File
@@ -371,7 +371,7 @@ void CCryEditDoc::Load(TDocMultiArchive& arrXmlAr, const QString& szFilename)
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
@@ -636,7 +636,7 @@ bool CCryEditDoc::SaveModified()
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
QMessageBox saveModifiedMessageBox(AzToolsFramework::GetActiveWindow());
@@ -699,7 +699,7 @@ void CCryEditDoc::OnFileSaveAs()
CCryEditApp::instance()->AddToRecentFileList(levelFileDialog.GetFileName());
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
AzToolsFramework::Prefab::TemplateId rootPrefabTemplateId =
@@ -728,7 +728,7 @@ bool CCryEditDoc::BeforeOpenDocument(const QString& lpszPathName, TOpenDocContex
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
+1 -1
View File
@@ -489,7 +489,7 @@ bool CGameEngine::LoadLevel(
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
+1 -1
View File
@@ -100,7 +100,7 @@ bool CGameExporter::Export(unsigned int flags, [[maybe_unused]] EEndian eExportE
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
+1 -1
View File
@@ -70,7 +70,7 @@ private:
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
AZ_Assert(false, "Level.pak should no longer be used when prefabs are used for levels.");
+1 -1
View File
@@ -659,7 +659,7 @@ void MainWindow::InitActions()
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (!usePrefabSystemForLevels)
{
am->AddAction(ID_FILE_EXPORTTOGAMENOSURFACETEXTURE, tr("&Export to Engine"))
+2 -1
View File
@@ -143,7 +143,8 @@ bool CImageUtil::LoadPGM(const QString& fileName, CImageEx& image)
fseek(file, 0, SEEK_SET);
char* str = new char[fileSize];
fread(str, fileSize, 1, file);
[[maybe_unused]] auto bytesRead = fread(str, fileSize, 1, file);
[[maybe_unused]] char* nextToken = nullptr;
token = azstrtok(str, 0, seps, &nextToken);
@@ -136,7 +136,7 @@ namespace AZ::CommonOnDemandReflections
->template Constructor<typename ContainerType::value_type*>()
->Attribute(AZ::Script::Attributes::ConstructorOverride, &OnDemandLuaFunctions::ConstructStringView<ContainerType::value_type, ContainerType::traits_type>)
->Attribute(AZ::Script::Attributes::ReaderWriterOverride, ScriptContext::CustomReaderWriter(&OnDemandLuaFunctions::StringTypeToLua<ContainerType>, &OnDemandLuaFunctions::StringTypeFromLua<ContainerType>))
->Method("ToString", [](const ContainerType& stringView) { return static_cast<AZStd::string>(stringView).c_str(); }, { { { "Reference", "String view object being converted to string" } } })
->Method("ToString", [](const ContainerType& stringView) { return stringView.data(); }, { { { "Reference", "String view object being converted to string" } } })
->Attribute(AZ::Script::Attributes::ToolTip, "Converts string_view to string")
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString)
->template WrappingMember<const char*>(&ContainerType::data)
@@ -69,9 +69,11 @@ namespace UnitTest
// Note that ConvertToAbsolutePath will perform a realpath on the result. The result of AZ::Utils::GetExecutableDirectory
// uses AZ::Android::AndroidEnv::Get()->GetAppPrivateStoragePath() which will retrieve the storage path, but that path could
// be symlinked, so we need to perform a real path on it before comparison
char realExecutableDirectory[AZ::IO::MaxPathLength];
ASSERT_TRUE(realpath(executableDirectory, realExecutableDirectory));
char* realExecutableDirectory = realpath(executableDirectory, nullptr);
ASSERT_NE(realExecutableDirectory, nullptr);
EXPECT_STRCASEEQ(realExecutableDirectory, absolutePath->c_str());
free(realExecutableDirectory);
}
}
+32 -32
View File
@@ -447,13 +447,13 @@ namespace UnitTest
{
x -= 1;
});
// a <-- Root
// / \
// b c
// \ /
// d
/*
a <-- Root
/ \
b c
\ /
d
*/
a.Precedes(b, c);
d.Follows(b, c);
@@ -522,20 +522,20 @@ namespace UnitTest
{
x -= 1;
});
// NOTE: The ideal way to express this topology is without the wait on the subgraph
// at task g, but this is more an illustrative test. Better is to express the entire
// graph in a single larger graph.
// a <-- Root
// / \
// b c - f
// \ \ \
// \ e - g
// \ /
// \ /
// \ /
// d
/*
NOTE: The ideal way to express this topology is without the wait on the subgraph
at task g, but this is more an illustrative test. Better is to express the entire
graph in a single larger graph.
a <-- Root
/ \
b c - f
\ \ \
\ e - g
\ /
\ /
\ /
d
*/
a.Precedes(b);
a.Precedes(c);
b.Precedes(d);
@@ -593,17 +593,17 @@ namespace UnitTest
{
x += 0b1000;
});
// a <-- Root
// / \
// b c - f
// \ \ \
// \ e - g
// \ /
// \ /
// \ /
// d
/*
a <-- Root
/ \
b c - f
\ \ \
\ e - g
\ /
\ /
\ /
d
*/
a.Precedes(b, c);
b.Precedes(d);
c.Precedes(e, f);
@@ -112,6 +112,7 @@ namespace AzFramework
virtual void SetPrefabSystemEnabled([[maybe_unused]] bool enable) {}
/// Returns true if Prefab System is enabled for use with levels, false if legacy level system is enabled (level.pak)
/// @deprecated Use 'IsPrefabSystemEnabled' instead
virtual bool IsPrefabSystemForLevelsEnabled() const { return false; }
/// Returns true if code should assert when the Legacy Slice System is used
@@ -765,6 +765,7 @@ namespace AzFramework
bool Application::IsPrefabSystemForLevelsEnabled() const
{
AZ_Warning("Application", false, "'IsPrefabSystemForLevelsEnabled' is deprecated, please use 'IsPrefabSystemEnabled' instead.");
return IsPrefabSystemEnabled();
}
@@ -1208,7 +1208,7 @@ namespace AZ::IO
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
@@ -1274,7 +1274,7 @@ namespace AZ::IO
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
AZStd::unique_lock lock(m_csZips);
for (auto it = m_arrZips.begin(); it != m_arrZips.end();)
@@ -383,7 +383,7 @@ namespace AZ::IO::ZipDir
if (!AZ::IO::FileIOBase::GetDirectInstance()->Write(m_fileHandle, ptr, sizeToWrite))
{
char error[1024];
azstrerror_s(error, AZ_ARRAY_SIZE(error), errno);
[[maybe_unused]] auto azStrErrorResult = azstrerror_s(error, AZ_ARRAY_SIZE(error), errno);
AZ_Warning("Archive", false, "Cannot write to zip file!! error = (%d): %s", errno, error);
return ZD_ERROR_IO_FAILED;
}
@@ -531,7 +531,7 @@ namespace AZ::IO::ZipDir
if (!WriteCompressedData((uint8_t*)pUncompressed, nSegmentSize, encrypt))
{
char error[1024];
azstrerror_s(error, AZ_ARRAY_SIZE(error), errno);
[[maybe_unused]] auto azStrErrorResult = azstrerror_s(error, AZ_ARRAY_SIZE(error), errno);
AZ_Warning("Archive", false, "Cannot write to zip file!! error = (%d): %s", errno, error);
return ZD_ERROR_IO_FAILED;
}
@@ -1,90 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/std/string/string.h>
#include <AzFramework/Matchmaking/MatchmakingRequests.h>
namespace AzFramework
{
//! IMatchmakingRequests
//! Pure virtual session interface class to abstract the details of session handling from application code.
class IMatchmakingRequests
{
public:
AZ_RTTI(IMatchmakingRequests, "{BC0B74DA-A448-4F40-9B50-9D73142829D5}");
IMatchmakingRequests() = default;
virtual ~IMatchmakingRequests() = default;
//! Registers a player's acceptance or rejection of a proposed matchmaking.
//! @param acceptMatchRequest The request of AcceptMatch operation
virtual void AcceptMatch(const AcceptMatchRequest& acceptMatchRequest) = 0;
//! Create a game match for a group of players.
//! @param startMatchmakingRequest The request of StartMatchmaking operation
//! @return A unique identifier for a matchmaking ticket
virtual AZStd::string StartMatchmaking(const StartMatchmakingRequest& startMatchmakingRequest) = 0;
//! Cancels a matchmaking ticket that is currently being processed.
//! @param stopMatchmakingRequest The request of StopMatchmaking operation
virtual void StopMatchmaking(const StopMatchmakingRequest& stopMatchmakingRequest) = 0;
};
//! IMatchmakingAsyncRequests
//! Async version of IMatchmakingRequests
class IMatchmakingAsyncRequests
{
public:
AZ_RTTI(IMatchmakingAsyncRequests, "{53513480-2D02-493C-B44E-96AA27F42429}");
IMatchmakingAsyncRequests() = default;
virtual ~IMatchmakingAsyncRequests() = default;
//! AcceptMatch Async
//! @param acceptMatchRequest The request of AcceptMatch operation
virtual void AcceptMatchAsync(const AcceptMatchRequest& acceptMatchRequest) = 0;
//! StartMatchmaking Async
//! @param startMatchmakingRequest The request of StartMatchmaking operation
virtual void StartMatchmakingAsync(const StartMatchmakingRequest& startMatchmakingRequest) = 0;
//! StopMatchmaking Async
//! @param stopMatchmakingRequest The request of StopMatchmaking operation
virtual void StopMatchmakingAsync(const StopMatchmakingRequest& stopMatchmakingRequest) = 0;
};
//! MatchmakingAsyncRequestNotifications
//! The notifications correspond to matchmaking async requests
class MatchmakingAsyncRequestNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! OnAcceptMatchAsyncComplete is fired once AcceptMatchAsync completes
virtual void OnAcceptMatchAsyncComplete() = 0;
//! OnStartMatchmakingAsyncComplete is fired once StartMatchmakingAsync completes
//! @param matchmakingTicketId The unique identifier for the matchmaking ticket
virtual void OnStartMatchmakingAsyncComplete(const AZStd::string& matchmakingTicketId) = 0;
//! OnStopMatchmakingAsyncComplete is fired once StopMatchmakingAsync completes
virtual void OnStopMatchmakingAsyncComplete() = 0;
};
using MatchmakingAsyncRequestNotificationBus = AZ::EBus<MatchmakingAsyncRequestNotifications>;
} // namespace AzFramework
@@ -1,46 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace AzFramework
{
//! MatchmakingNotifications
//! The matchmaking notifications to listen for performing required operations
//! based on matchmaking ticket event
class MatchmakingNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! OnMatchAcceptance is fired when match is found and pending on acceptance
//! Use this notification to accept found match
virtual void OnMatchAcceptance() = 0;
//! OnMatchComplete is fired when match is complete
virtual void OnMatchComplete() = 0;
//! OnMatchError is fired when match is processed with error
virtual void OnMatchError() = 0;
//! OnMatchFailure is fired when match is failed to complete
virtual void OnMatchFailure() = 0;
};
using MatchmakingNotificationBus = AZ::EBus<MatchmakingNotifications>;
} // namespace AzFramework
@@ -1,78 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Matchmaking/MatchmakingRequests.h>
namespace AzFramework
{
void AcceptMatchRequest::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<AcceptMatchRequest>()
->Version(0)
->Field("acceptMatch", &AcceptMatchRequest::m_acceptMatch)
->Field("playerIds", &AcceptMatchRequest::m_playerIds)
->Field("ticketId", &AcceptMatchRequest::m_ticketId);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<AcceptMatchRequest>("AcceptMatchRequest", "The container for AcceptMatch request parameters")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &AcceptMatchRequest::m_acceptMatch, "AcceptMatch",
"Player response to accept or reject match")
->DataElement(AZ::Edit::UIHandlers::Default, &AcceptMatchRequest::m_playerIds, "PlayerIds",
"A list of unique identifiers for players delivering the response")
->DataElement(AZ::Edit::UIHandlers::Default, &AcceptMatchRequest::m_ticketId, "TicketId",
"A unique identifier for a matchmaking ticket");
}
}
}
void StartMatchmakingRequest::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<StartMatchmakingRequest>()
->Version(0)
->Field("ticketId", &StartMatchmakingRequest::m_ticketId);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<StartMatchmakingRequest>("StartMatchmakingRequest", "The container for StartMatchmaking request parameters")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &StartMatchmakingRequest::m_ticketId, "TicketId",
"A unique identifier for a matchmaking ticket");
}
}
}
void StopMatchmakingRequest::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<StopMatchmakingRequest>()
->Version(0)
->Field("ticketId", &StopMatchmakingRequest::m_ticketId);
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<StopMatchmakingRequest>("StopMatchmakingRequest", "The container for StopMatchmaking request parameters")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &StopMatchmakingRequest::m_ticketId, "TicketId",
"A unique identifier for a matchmaking ticket");
}
}
}
} // namespace AzFramework
@@ -1,67 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/vector.h>
#include <AzCore/std/string/string.h>
namespace AZ
{
class ReflectContext;
}
namespace AzFramework
{
//! AcceptMatchRequest
//! The container for AcceptMatch request parameters.
struct AcceptMatchRequest
{
AZ_RTTI(AcceptMatchRequest, "{AD289D76-CEE2-424F-847E-E62AA83B7D79}");
static void Reflect(AZ::ReflectContext* context);
AcceptMatchRequest() = default;
virtual ~AcceptMatchRequest() = default;
//! Player response to accept or reject match
bool m_acceptMatch;
//! A list of unique identifiers for players delivering the response
AZStd::vector<AZStd::string> m_playerIds;
//! A unique identifier for a matchmaking ticket
AZStd::string m_ticketId;
};
//! StartMatchmakingRequest
//! The container for StartMatchmaking request parameters.
struct StartMatchmakingRequest
{
AZ_RTTI(StartMatchmakingRequest, "{70B47776-E8E7-4993-BEC3-5CAEC3D48E47}");
static void Reflect(AZ::ReflectContext* context);
StartMatchmakingRequest() = default;
virtual ~StartMatchmakingRequest() = default;
//! A unique identifier for a matchmaking ticket
AZStd::string m_ticketId;
};
//! StopMatchmakingRequest
//! The container for StopMatchmaking request parameters.
struct StopMatchmakingRequest
{
AZ_RTTI(StopMatchmakingRequest, "{6132E293-65EF-4DC2-A8A0-00269697229D}");
static void Reflect(AZ::ReflectContext* context);
StopMatchmakingRequest() = default;
virtual ~StopMatchmakingRequest() = default;
//! A unique identifier for a matchmaking ticket
AZStd::string m_ticketId;
};
} // namespace AzFramework
@@ -1,94 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/IO/Path/Path.h>
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/string/string.h>
namespace AzFramework
{
//! SessionConnectionConfig
//! The properties for handling join session request.
struct SessionConnectionConfig
{
//! A unique identifier for registered player in session.
AZStd::string m_playerSessionId;
//! The DNS identifier assigned to the instance that is running the session.
AZStd::string m_dnsName;
//! The IP address of the session.
AZStd::string m_ipAddress;
//! The port number for the session.
uint16_t m_port = 0;
};
//! SessionConnectionConfig
//! The properties for handling player connect/disconnect
struct PlayerConnectionConfig
{
//! A unique identifier for player connection.
uint32_t m_playerConnectionId = 0;
//! A unique identifier for registered player in session.
AZStd::string m_playerSessionId;
};
//! ISessionHandlingClientRequests
//! Requests made to the client to manage their membership in a session
class ISessionHandlingClientRequests
{
public:
AZ_RTTI(ISessionHandlingClientRequests, "{41DE6BD3-72BC-4443-BFF9-5B1B9396657A}");
ISessionHandlingClientRequests() = default;
virtual ~ISessionHandlingClientRequests() = default;
//! Request the player join session
//! @param sessionConnectionConfig The required properties to handle the player join session process
//! @return The result of player join session process
virtual bool RequestPlayerJoinSession(const SessionConnectionConfig& sessionConnectionConfig) = 0;
//! Request the connected player leave session
virtual void RequestPlayerLeaveSession() = 0;
};
//! ISessionProviderRequests
//! Requests made to the service providing server/fleet management by the server
class ISessionHandlingProviderRequests
{
public:
AZ_RTTI(ISessionHandlingProviderRequests, "{4F0C17BA-F470-4242-A8CB-EC7EA805257C}");
ISessionHandlingProviderRequests() = default;
virtual ~ISessionHandlingProviderRequests() = default;
//! Handle the destroy session process
virtual void HandleDestroySession() = 0;
//! Validate the player join session process
//! @param playerConnectionConfig The required properties to validate the player join session process
//! @return The result of player join session validation
virtual bool ValidatePlayerJoinSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
//! Handle the player leave session process
//! @param playerConnectionConfig The required properties to handle the player leave session process
virtual void HandlePlayerLeaveSession(const PlayerConnectionConfig& playerConnectionConfig) = 0;
//! Retrieves the file location of a pem-encoded TLS certificate for Client to Server communication
//! @return If successful, returns the file location of TLS certificate file; if not successful, returns
//! empty string.
virtual AZ::IO::Path GetExternalSessionCertificate() = 0;
//! Retrieves the file location of a pem-encoded TLS certificate for Server to Server communication
//! @return If successful, returns the file location of TLS certificate file; if not successful, returns
//! empty string.
virtual AZ::IO::Path GetInternalSessionCertificate() = 0;
};
} // namespace AzFramework
@@ -1,104 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/std/string/string.h>
#include <AzFramework/Session/SessionRequests.h>
namespace AzFramework
{
//! ISessionRequests
//! Pure virtual session interface class to abstract the details of session handling from application code.
class ISessionRequests
{
public:
AZ_RTTI(ISessionRequests, "{D6C41A71-DD8D-47FE-8515-FAF90670AE2F}");
ISessionRequests() = default;
virtual ~ISessionRequests() = default;
//! Create a session for players to find and join.
//! @param createSessionRequest The request of CreateSession operation
//! @return The request id if session creation request succeeds; empty if it fails
virtual AZStd::string CreateSession(const CreateSessionRequest& createSessionRequest) = 0;
//! Retrieve all active sessions that match the given search criteria and sorted in specific order.
//! @param searchSessionsRequest The request of SearchSessions operation
//! @return The response of SearchSessions operation
virtual SearchSessionsResponse SearchSessions(const SearchSessionsRequest& searchSessionsRequest) const = 0;
//! Reserve an open player slot in a session, and perform connection from client to server.
//! @param joinSessionRequest The request of JoinSession operation
//! @return True if joining session succeeds; False otherwise
virtual bool JoinSession(const JoinSessionRequest& joinSessionRequest) = 0;
//! Disconnect player from session.
virtual void LeaveSession() = 0;
};
//! ISessionAsyncRequests
//! Async version of ISessionRequests
class ISessionAsyncRequests
{
public:
AZ_RTTI(ISessionAsyncRequests, "{471542AF-96B9-4930-82FE-242A4E68432D}");
ISessionAsyncRequests() = default;
virtual ~ISessionAsyncRequests() = default;
//! CreateSession Async
//! @param createSessionRequest The request of CreateSession operation
virtual void CreateSessionAsync(const CreateSessionRequest& createSessionRequest) = 0;
//! SearchSessions Async
//! @param searchSessionsRequest The request of SearchSessions operation
virtual void SearchSessionsAsync(const SearchSessionsRequest& searchSessionsRequest) const = 0;
//! JoinSession Async
//! @param joinSessionRequest The request of JoinSession operation
virtual void JoinSessionAsync(const JoinSessionRequest& joinSessionRequest) = 0;
//! LeaveSession Async
virtual void LeaveSessionAsync() = 0;
};
//! SessionAsyncRequestNotifications
//! The notifications correspond to session async requests
class SessionAsyncRequestNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! OnCreateSessionAsyncComplete is fired once CreateSessionAsync completes
//! @param createSessionResponse The request id if session creation request succeeds; empty if it fails
virtual void OnCreateSessionAsyncComplete(const AZStd::string& createSessionReponse) = 0;
//! OnSearchSessionsAsyncComplete is fired once SearchSessionsAsync completes
//! @param searchSessionsResponse The response of SearchSessions call
virtual void OnSearchSessionsAsyncComplete(const SearchSessionsResponse& searchSessionsResponse) = 0;
//! OnJoinSessionAsyncComplete is fired once JoinSessionAsync completes
//! @param joinSessionsResponse True if joining session succeeds; False otherwise
virtual void OnJoinSessionAsyncComplete(bool joinSessionsResponse) = 0;
//! OnLeaveSessionAsyncComplete is fired once LeaveSessionAsync completes
virtual void OnLeaveSessionAsyncComplete() = 0;
};
using SessionAsyncRequestNotificationBus = AZ::EBus<SessionAsyncRequestNotifications>;
} // namespace AzFramework
@@ -1,73 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Session/SessionConfig.h>
namespace AzFramework
{
void SessionConfig::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<SessionConfig>()
->Version(0)
->Field("creationTime", &SessionConfig::m_creationTime)
->Field("terminationTime", &SessionConfig::m_terminationTime)
->Field("creatorId", &SessionConfig::m_creatorId)
->Field("sessionProperties", &SessionConfig::m_sessionProperties)
->Field("matchmakingData", &SessionConfig::m_matchmakingData)
->Field("sessionId", &SessionConfig::m_sessionId)
->Field("sessionName", &SessionConfig::m_sessionName)
->Field("dnsName", &SessionConfig::m_dnsName)
->Field("ipAddress", &SessionConfig::m_ipAddress)
->Field("port", &SessionConfig::m_port)
->Field("maxPlayer", &SessionConfig::m_maxPlayer)
->Field("currentPlayer", &SessionConfig::m_currentPlayer)
->Field("status", &SessionConfig::m_status)
->Field("statusReason", &SessionConfig::m_statusReason)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<SessionConfig>("SessionConfig", "Properties describing a session")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creationTime,
"CreationTime", "A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_terminationTime,
"TerminationTime", "A time stamp indicating when this data object was terminated. Same format as creation time.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_creatorId,
"CreatorId", "A unique identifier for a player or entity creating the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionProperties,
"SessionProperties", "A collection of custom properties for a session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_matchmakingData,
"MatchmakingData", "The matchmaking process information that was used to create the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionId,
"SessionId", "A unique identifier for the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_sessionName,
"SessionName", "A descriptive label that is associated with a session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_dnsName,
"DnsName", "The DNS identifier assigned to the instance that is running the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_ipAddress,
"IpAddress", "The IP address of the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_port,
"Port", "The port number for the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_maxPlayer,
"MaxPlayer", "The maximum number of players that can be connected simultaneously to the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_currentPlayer,
"CurrentPlayer", "Number of players currently in the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_status,
"Status", "Current status of the session.")
->DataElement(AZ::Edit::UIHandlers::Default, &AzFramework::SessionConfig::m_statusReason,
"StatusReason", "Provides additional information about session status.");
}
}
}
} // namespace AzFramework
@@ -1,69 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/string/string.h>
namespace AzFramework
{
//! SessionConfig
//! Properties describing a session.
struct SessionConfig
{
AZ_RTTI(SessionConfig, "{992DD4BE-8BA5-4071-8818-B99FD2952086}");
static void Reflect(AZ::ReflectContext* context);
SessionConfig() = default;
virtual ~SessionConfig() = default;
//! A time stamp indicating when this session was created. Format is a number expressed in Unix time as milliseconds.
uint64_t m_creationTime = 0;
//! A time stamp indicating when this data object was terminated. Same format as creation time.
uint64_t m_terminationTime = 0;
//! A unique identifier for a player or entity creating the session.
AZStd::string m_creatorId;
//! A collection of custom properties for a session.
AZStd::unordered_map<AZStd::string, AZStd::string> m_sessionProperties;
//! The matchmaking process information that was used to create the session.
AZStd::string m_matchmakingData;
//! A unique identifier for the session.
AZStd::string m_sessionId;
//! A descriptive label that is associated with a session.
AZStd::string m_sessionName;
//! The DNS identifier assigned to the instance that is running the session.
AZStd::string m_dnsName;
//! The IP address of the session.
AZStd::string m_ipAddress;
//! The port number for the session.
uint16_t m_port = 0;
//! The maximum number of players that can be connected simultaneously to the session.
uint64_t m_maxPlayer = 0;
//! Number of players currently in the session.
uint64_t m_currentPlayer = 0;
//! Current status of the session.
AZStd::string m_status;
//! Provides additional information about session status.
AZStd::string m_statusReason;
};
} // namespace AzFramework
@@ -1,71 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/EBus/EBus.h>
namespace AzFramework
{
struct SessionConfig;
//! SessionNotifications
//! The session notifications to listen for performing required operations
class SessionNotifications
: public AZ::EBusTraits
{
public:
// Safeguard handler for multi-threaded use case
using MutexType = AZStd::recursive_mutex;
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
//////////////////////////////////////////////////////////////////////////
//! OnSessionHealthCheck is fired in health check process
//! Use this notification to perform any custom health check
//! @return True if OnSessionHealthCheck succeeds, false otherwise
virtual bool OnSessionHealthCheck() = 0;
//! OnCreateSessionBegin is fired at the beginning of session creation process
//! Use this notification to perform any necessary configuration or initialization before
//! creating session
//! @param sessionConfig The properties to describe a session
//! @return True if OnCreateSessionBegin succeeds, false otherwise
virtual bool OnCreateSessionBegin(const SessionConfig& sessionConfig) = 0;
//! OnCreateSessionEnd is fired at the end of session creation process
//! Use this notification to perform any follow-up operation after session is created and active
virtual void OnCreateSessionEnd() = 0;
//! OnDestroySessionBegin is fired at the beginning of session termination process
//! Use this notification to perform any cleanup operation before destroying session,
//! like gracefully disconnect players, cleanup data, etc.
//! @return True if OnDestroySessionBegin succeeds, false otherwise
virtual bool OnDestroySessionBegin() = 0;
//! OnDestroySessionEnd is fired at the end of session termination process
//! Use this notification to perform any follow-up operation after session is destroyed,
//! like shutdown application process, etc.
virtual void OnDestroySessionEnd() = 0;
//! OnUpdateSessionBegin is fired at the beginning of session update process
//! Use this notification to perform any configuration or initialization to handle
//! the session settings changing
//! @param sessionConfig The properties to describe a session
//! @param updateReason The reason for session update
virtual void OnUpdateSessionBegin(const SessionConfig& sessionConfig, const AZStd::string& updateReason) = 0;
//! OnUpdateSessionBegin is fired at the end of session update process
//! Use this notification to perform any follow-up operations after session is updated
virtual void OnUpdateSessionEnd() = 0;
};
using SessionNotificationBus = AZ::EBus<SessionNotifications>;
} // namespace AzFramework
@@ -1,127 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include <AzCore/RTTI/ReflectContext.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzFramework/Session/SessionRequests.h>
#include <AzFramework/Session/SessionConfig.h>
namespace AzFramework
{
void CreateSessionRequest::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<CreateSessionRequest>()
->Version(0)
->Field("creatorId", &CreateSessionRequest::m_creatorId)
->Field("sessionProperties", &CreateSessionRequest::m_sessionProperties)
->Field("sessionName", &CreateSessionRequest::m_sessionName)
->Field("maxPlayer", &CreateSessionRequest::m_maxPlayer)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<CreateSessionRequest>("CreateSessionRequest", "The container for CreateSession request parameters")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_creatorId,
"CreatorId", "A unique identifier for a player or entity creating the session")
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionProperties,
"SessionProperties", "A collection of custom properties for a session")
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_sessionName,
"SessionName", "A descriptive label that is associated with a session")
->DataElement(AZ::Edit::UIHandlers::Default, &CreateSessionRequest::m_maxPlayer,
"MaxPlayer", "The maximum number of players that can be connected simultaneously to the session")
;
}
}
}
void SearchSessionsRequest::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<SearchSessionsRequest>()
->Version(0)
->Field("filterExpression", &SearchSessionsRequest::m_filterExpression)
->Field("sortExpression", &SearchSessionsRequest::m_sortExpression)
->Field("maxResult", &SearchSessionsRequest::m_maxResult)
->Field("nextToken", &SearchSessionsRequest::m_nextToken)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<SearchSessionsRequest>("SearchSessionsRequest", "The container for SearchSessions request parameters")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_filterExpression,
"FilterExpression", "String containing the search criteria for the session search")
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_sortExpression,
"SortExpression", "Instructions on how to sort the search results")
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_maxResult,
"MaxResult", "The maximum number of results to return")
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsRequest::m_nextToken,
"NextToken", "A token that indicates the start of the next sequential page of results")
;
}
}
}
void SearchSessionsResponse::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<SearchSessionsResponse>()
->Version(0)
->Field("sessionConfigs", &SearchSessionsResponse::m_sessionConfigs)
->Field("nextToken", &SearchSessionsResponse::m_nextToken)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<SearchSessionsResponse>("SearchSessionsResponse", "The container for SearchSession request results")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_sessionConfigs,
"SessionConfigs", "A collection of sessions that match the search criteria and sorted in specific order")
->DataElement(AZ::Edit::UIHandlers::Default, &SearchSessionsResponse::m_nextToken,
"NextToken", "A token that indicates the start of the next sequential page of results")
;
}
}
}
void JoinSessionRequest::Reflect(AZ::ReflectContext* context)
{
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
{
serializeContext->Class<JoinSessionRequest>()
->Version(0)
->Field("sessionId", &JoinSessionRequest::m_sessionId)
->Field("playerId", &JoinSessionRequest::m_playerId)
->Field("playerData", &JoinSessionRequest::m_playerData)
;
if (AZ::EditContext* editContext = serializeContext->GetEditContext())
{
editContext->Class<JoinSessionRequest>("JoinSessionRequest", "The container for JoinSession request parameters")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_sessionId,
"SessionId", "A unique identifier for the session")
->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerId,
"PlayerId", "A unique identifier for a player. Player IDs are developer-defined")
->DataElement(AZ::Edit::UIHandlers::Default, &JoinSessionRequest::m_playerData,
"PlayerData", "Developer-defined information related to a player")
;
}
}
}
} // namespace AzFramework
@@ -1,107 +0,0 @@
/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/RTTI/RTTI.h>
#include <AzCore/std/containers/unordered_map.h>
#include <AzCore/std/string/string.h>
namespace AZ
{
class ReflectContext;
}
namespace AzFramework
{
struct SessionConfig;
//! CreateSessionRequest
//! The container for CreateSession request parameters.
struct CreateSessionRequest
{
AZ_RTTI(CreateSessionRequest, "{E39C2A45-89C9-4CFB-B337-9734DC798930}");
static void Reflect(AZ::ReflectContext* context);
CreateSessionRequest() = default;
virtual ~CreateSessionRequest() = default;
//! A unique identifier for a player or entity creating the session.
AZStd::string m_creatorId;
//! A collection of custom properties for a session.
AZStd::unordered_map<AZStd::string, AZStd::string> m_sessionProperties;
//! A descriptive label that is associated with a session.
AZStd::string m_sessionName;
//! The maximum number of players that can be connected simultaneously to the session.
uint64_t m_maxPlayer = 0;
};
//! SearchSessionsRequest
//! The container for SearchSessions request parameters.
struct SearchSessionsRequest
{
AZ_RTTI(SearchSessionsRequest, "{B49207A8-8549-4ADB-B7D9-D7A4932F9B4B}");
static void Reflect(AZ::ReflectContext* context);
SearchSessionsRequest() = default;
virtual ~SearchSessionsRequest() = default;
//! String containing the search criteria for the session search. If no filter expression is included, the request returns results
//! for all active sessions.
AZStd::string m_filterExpression;
//! Instructions on how to sort the search results. If no sort expression is included, the request returns results in random order.
AZStd::string m_sortExpression;
//! The maximum number of results to return.
uint8_t m_maxResult = 0;
//! A token that indicates the start of the next sequential page of results.
AZStd::string m_nextToken;
};
//! SearchSessionsResponse
//! The container for SearchSession request results.
struct SearchSessionsResponse
{
AZ_RTTI(SearchSessionsResponse, "{F93DE7DC-D381-4E08-8A3B-0B08F7C38714}");
static void Reflect(AZ::ReflectContext* context);
SearchSessionsResponse() = default;
virtual ~SearchSessionsResponse() = default;
//! A collection of sessions that match the search criteria and sorted in specific order.
AZStd::vector<SessionConfig> m_sessionConfigs;
//! A token that indicates the start of the next sequential page of results.
AZStd::string m_nextToken;
};
//! JoinSessionRequest
//! The container for JoinSession request parameters.
struct JoinSessionRequest
{
AZ_RTTI(JoinSessionRequest, "{519769E8-3CDE-4385-A0D7-24DBB3685657}");
static void Reflect(AZ::ReflectContext* context);
JoinSessionRequest() = default;
virtual ~JoinSessionRequest() = default;
//! A unique identifier for the session.
AZStd::string m_sessionId;
//! A unique identifier for a player. Player IDs are developer-defined.
AZStd::string m_playerId;
//! Developer-defined information related to a player.
AZStd::string m_playerData;
};
} // namespace AzFramework
@@ -29,6 +29,19 @@ namespace AzFramework::SurfaceData
{
}
//! Equality comparison operator for SurfaceTagWeight.
bool operator==(const SurfaceTagWeight& rhs) const
{
return (m_surfaceType == rhs.m_surfaceType) && (m_weight == rhs.m_weight);
}
//! Inequality comparison operator for SurfaceTagWeight.
bool operator!=(const SurfaceTagWeight& rhs) const
{
return !(*this == rhs);
}
AZ::Crc32 m_surfaceType = AZ::Crc32(Constants::s_unassignedTagName);
float m_weight = 0.0f; //! A Value in the range [0.0f .. 1.0f]
@@ -165,10 +165,6 @@ set(FILES
Logging/MissingAssetLogger.cpp
Logging/MissingAssetLogger.h
Logging/MissingAssetNotificationBus.h
Matchmaking/IMatchmakingRequests.h
Matchmaking/MatchmakingRequests.cpp
Matchmaking/MatchmakingRequests.h
Matchmaking/MatchmakingNotifications.h
Scene/Scene.h
Scene/Scene.inl
Scene/Scene.cpp
@@ -182,13 +178,6 @@ set(FILES
Script/ScriptDebugMsgReflection.h
Script/ScriptRemoteDebugging.cpp
Script/ScriptRemoteDebugging.h
Session/ISessionHandlingRequests.h
Session/ISessionRequests.h
Session/SessionRequests.cpp
Session/SessionRequests.h
Session/SessionConfig.cpp
Session/SessionConfig.h
Session/SessionNotifications.h
StreamingInstall/StreamingInstall.h
StreamingInstall/StreamingInstall.cpp
StreamingInstall/StreamingInstallRequests.h
@@ -120,7 +120,7 @@ namespace AzFramework
int res = chdir(processLaunchInfo.m_workingDirectory.c_str());
if (res != 0)
{
write(errorPipe[1], &errno, sizeof(int));
[[maybe_unused]] auto writeResult = write(errorPipe[1], &errno, sizeof(int));
// We *have* to _exit as we are the child process and simply
// returning at this point would mean we would start running
// the code from our parent process and that will just wreck
@@ -132,15 +132,19 @@ namespace AzFramework
switch (processLaunchInfo.m_processPriority)
{
case PROCESSPRIORITY_BELOWNORMAL:
nice(1);
{
[[maybe_unused]] auto niceResult = nice(1);
// also reduce disk impact:
// setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_UTILITY);
break;
}
case PROCESSPRIORITY_IDLE:
nice(20);
{
[[maybe_unused]] auto niceResult = nice(20);
// also reduce disk impact:
// setiopolicy_np(IOPOL_TYPE_DISK, IOPOL_SCOPE_PROCESS, IOPOL_THROTTLE);
break;
}
}
startupInfo.SetupHandlesForChildProcess();
@@ -153,7 +157,7 @@ namespace AzFramework
// to stop it from continuing to run as a clone of the parent.
// Communicate the error code back to the parent via a pipe for the
// parent to read.
write(errorPipe[1], &errval, sizeof(errval));
[[maybe_unused]] auto writeResult = write(errorPipe[1], &errval, sizeof(errval));
_exit(0);
}
@@ -317,7 +321,7 @@ namespace AzFramework
// Set up a pipe to communicate the error code from the subprocess's execvpe call
AZStd::array<int, 2> childErrorPipeFds{};
pipe(childErrorPipeFds.data());
[[maybe_unused]] auto pipeResult = pipe(childErrorPipeFds.data());
// This configures the write end of the pipe to close on calls to `exec`
fcntl(childErrorPipeFds[1], F_SETFD, fcntl(childErrorPipeFds[1], F_GETFD) | FD_CLOEXEC);
@@ -71,7 +71,7 @@ namespace AzNetworking
const char* GetNetworkErrorDesc(int32_t errorCode)
{
static AZ_THREAD_LOCAL char buffer[1024];
strerror_r(errorCode, buffer, sizeof(buffer));
[[maybe_unused]] auto strErrorResult = strerror_r(errorCode, buffer, sizeof(buffer));
return buffer;
}
}
@@ -295,7 +295,7 @@ namespace AzToolsFramework
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
for (const AzToolsFramework::AssetFileInfo& assetFileInfo : assetFileInfoList.m_fileInfoList)
{
@@ -19,45 +19,69 @@
namespace AzToolsFramework
{
namespace Prefab
{
//! A RootAliasPath can be used to store an alias path that starts from the Prefab EOS root instance.
//! The root instance itself is included in the path. These can be used as Instance handles across systems
//! that do not have visibility over InstanceOptionalReferences, or that need to store Instance handles
//! for longer than just the span of a function without the risk of them going out of scope.
using RootAliasPath = AliasPath;
}
class PrefabEditorEntityOwnershipInterface
{
public:
AZ_RTTI(PrefabEditorEntityOwnershipInterface,"{38E764BA-A089-49F3-848F-46018822CE2E}");
AZ_RTTI(PrefabEditorEntityOwnershipInterface, "{38E764BA-A089-49F3-848F-46018822CE2E}");
//! Returns whether the system has a root instance assigned.
//! @return True if a root prefab is assigned, false otherwise.
virtual bool IsRootPrefabAssigned() const = 0;
//! Returns an optional reference to the root prefab instance.
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
//! Returns the template id for the root prefab instance.
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
//! Creates a prefab instance with the provided entities and nestedPrefabInstances.
//! /param entities The entities to put under the new prefab.
//! /param nestedPrefabInstances The nested prefab instances to put under the new prefab.
//! /param filePath The filepath corresponding to the prefab file to be created.
//! /param instanceToParentUnder The instance the newly created prefab instance is parented under.
//! /return The optional reference to the prefab created.
//! @param entities The entities to put under the new prefab.
//! @param nestedPrefabInstances The nested prefab instances to put under the new prefab.
//! @param filePath The filepath corresponding to the prefab file to be created.
//! @param instanceToParentUnder The instance the newly created prefab instance is parented under.
//! @return The optional reference to the prefab created.
virtual Prefab::InstanceOptionalReference CreatePrefab(
const AZStd::vector<AZ::Entity*>& entities, AZStd::vector<AZStd::unique_ptr<Prefab::Instance>>&& nestedPrefabInstances,
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
//! Instantiate the prefab file provided.
//! /param filePath The filepath for the prefab file the instance should be created from.
//! /param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
//! /return The optional reference to the prefab instance.
//! @param filePath The filepath for the prefab file the instance should be created from.
//! @param instanceToParentUnder The instance the newly instantiated prefab instance is parented under.
//! @return The optional reference to the prefab instance.
virtual Prefab::InstanceOptionalReference InstantiatePrefab(
AZ::IO::PathView filePath, Prefab::InstanceOptionalReference instanceToParentUnder = AZStd::nullopt) = 0;
virtual Prefab::InstanceOptionalReference GetRootPrefabInstance() = 0;
virtual Prefab::TemplateId GetRootPrefabTemplateId() = 0;
virtual void StartPlayInEditor() = 0;
virtual void StopPlayInEditor() = 0;
//! Get all Assets generated by Prefab processing when entering Play-In Editor mode (Ctrl+G)
//! /return The vector of Assets generated by Prefab processing
//! @return The vector of Assets generated by Prefab processing
virtual const Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer::SpawnableAssets& GetPlayInEditorAssetData() const = 0;
virtual bool LoadFromStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
virtual bool SaveToStream(AZ::IO::GenericStream& stream, AZStd::string_view filename) = 0;
virtual void StartPlayInEditor() = 0;
virtual void StopPlayInEditor() = 0;
virtual void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) = 0;
//! Returns the reference to the instance corresponding to the RootAliasPath provided.
//! @param rootAliasPath The RootAliasPath to be queried.
//! @return A reference to the instance if valid, AZStd::nullopt otherwise.
virtual Prefab::InstanceOptionalReference GetInstanceReferenceFromRootAliasPath(Prefab::RootAliasPath rootAliasPath) const = 0;
virtual bool IsRootPrefabAssigned() const = 0;
//! Allows to iterate through all instances referenced in the path, from the root down.
//! @param rootAliasPath The RootAliasPath to iterate through. If invalid, callback will not be called.
//! @param callback The function to call on each instance. If it returns true, it prevents the rest of the path from being called.
//! @return True if the iteration was halted by a callback returning true, false otherwise. Also returns false if the path is invalid.
virtual bool GetInstancesInRootAliasPath(
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const = 0;
};
}
@@ -510,6 +510,70 @@ namespace AzToolsFramework
m_playInEditorData.m_isEnabled = false;
}
bool PrefabEditorEntityOwnershipService::IsValidRootAliasPath(Prefab::RootAliasPath rootAliasPath) const
{
return GetInstanceReferenceFromRootAliasPath(rootAliasPath) != AZStd::nullopt;
}
Prefab::InstanceOptionalReference PrefabEditorEntityOwnershipService::GetInstanceReferenceFromRootAliasPath(
Prefab::RootAliasPath rootAliasPath) const
{
Prefab::InstanceOptionalReference instance = *m_rootInstance;
for (const auto& pathElement : rootAliasPath)
{
if (pathElement.Native() == rootAliasPath.begin()->Native())
{
// If the root is not the root Instance, the rootAliasPath is invalid.
if (pathElement.Native() != instance->get().GetInstanceAlias())
{
return Prefab::InstanceOptionalReference();
}
}
else
{
// If the instance alias can't be found, the rootAliasPath is invalid.
instance = instance->get().FindNestedInstance(pathElement.Native());
if (!instance.has_value())
{
return Prefab::InstanceOptionalReference();
}
}
}
return instance;
}
bool PrefabEditorEntityOwnershipService::GetInstancesInRootAliasPath(
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const
{
if (!IsValidRootAliasPath(rootAliasPath))
{
return false;
}
Prefab::InstanceOptionalReference instance;
for (const auto& pathElement : rootAliasPath)
{
if (!instance.has_value())
{
instance = *m_rootInstance;
}
else
{
instance = instance->get().FindNestedInstance(pathElement.Native());
}
if(callback(instance))
{
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
// Slice Buses implementation with Assert(false), this will exist only during Slice->Prefab
// development to pinpoint and replace specific calls to Slice system
@@ -169,11 +169,17 @@ namespace AzToolsFramework
void CreateNewLevelPrefab(AZStd::string_view filename, const AZStd::string& templateFilename) override;
bool IsRootPrefabAssigned() const override;
Prefab::InstanceOptionalReference GetInstanceReferenceFromRootAliasPath(Prefab::RootAliasPath rootAliasPath) const override;
bool GetInstancesInRootAliasPath(
Prefab::RootAliasPath rootAliasPath, const AZStd::function<bool(const Prefab::InstanceOptionalReference)>& callback) const override;
protected:
AZ::SliceComponent::SliceInstanceAddress GetOwningSlice() override;
private:
bool IsValidRootAliasPath(Prefab::RootAliasPath rootAliasPath) const;
struct PlayInEditorData
{
AzToolsFramework::Prefab::PrefabConversionUtils::InMemorySpawnableAssetContainer m_assetsCache;
@@ -177,7 +177,6 @@ namespace AzToolsFramework
AZStd::pair<Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath);
AZStd::pair<const Instance*, AZ::EntityId> GetInstanceAndEntityIdFromAliasPath(AliasPathView relativeAliasPath) const;
/**
* Gets the aliases of all the nested instances, which are sourced by the template with the given id.
*
@@ -11,7 +11,6 @@
#include <AzToolsFramework/Commands/SelectionCommand.h>
#include <AzToolsFramework/ContainerEntity/ContainerEntityInterface.h>
#include <AzToolsFramework/Entity/EditorEntityHelpers.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/Entity/ReadOnly/ReadOnlyEntityInterface.h>
#include <AzToolsFramework/Prefab/Instance/Instance.h>
#include <AzToolsFramework/Prefab/Instance/InstanceEntityMapperInterface.h>
@@ -97,9 +96,9 @@ namespace AzToolsFramework::Prefab
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
}
// Edit Prefab
// Add undo element
{
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
auto editUndo = aznew PrefabFocusUndo("Focus Prefab");
editUndo->Capture(entityId);
editUndo->SetParent(undoBatch.GetUndoBatch());
FocusOnPrefabInstanceOwningEntityId(entityId);
@@ -112,15 +111,24 @@ namespace AzToolsFramework::Prefab
[[maybe_unused]] AzFramework::EntityContextId entityContextId)
{
// If only one instance is in the hierarchy, this operation is invalid
size_t hierarchySize = m_instanceFocusHierarchy.size();
if (hierarchySize <= 1)
if (m_rootAliasFocusPathLength <= 1)
{
return AZ::Failure(
AZStd::string("Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
return AZ::Failure(AZStd::string(
"Prefab Focus Handler: Could not complete FocusOnParentOfFocusedPrefab operation while focusing on the root."));
}
RootAliasPath parentPath = m_rootAliasFocusPath;
parentPath.RemoveFilename();
// Retrieve parent of currently focused prefab.
InstanceOptionalReference parentInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[hierarchySize - 2]);
InstanceOptionalReference parentInstance = GetInstanceReference(parentPath);
// If only one instance is in the hierarchy, this operation is invalid
if (!parentInstance.has_value())
{
return AZ::Failure(AZStd::string(
"Prefab Focus Handler: Could not retrieve parent of current focus in FocusOnParentOfFocusedPrefab."));
}
// Use container entity of parent Instance for focus operations.
AZ::EntityId entityId = parentInstance->get().GetContainerEntityId();
@@ -136,9 +144,9 @@ namespace AzToolsFramework::Prefab
ToolsApplicationRequestBus::Broadcast(&ToolsApplicationRequestBus::Events::SetSelectedEntities, selectedEntities);
}
// Edit Prefab
// Add undo element
{
auto editUndo = aznew PrefabFocusUndo("Edit Prefab");
auto editUndo = aznew PrefabFocusUndo("Focus Prefab");
editUndo->Capture(entityId);
editUndo->SetParent(undoBatch.GetUndoBatch());
FocusOnPrefabInstanceOwningEntityId(entityId);
@@ -149,12 +157,31 @@ namespace AzToolsFramework::Prefab
PrefabFocusOperationResult PrefabFocusHandler::FocusOnPathIndex([[maybe_unused]] AzFramework::EntityContextId entityContextId, int index)
{
if (index < 0 || index >= m_instanceFocusHierarchy.size())
if (index < 0 || index >= m_rootAliasFocusPathLength)
{
return AZ::Failure(AZStd::string("Prefab Focus Handler: Invalid index on FocusOnPathIndex."));
}
InstanceOptionalReference focusedInstance = GetReferenceFromContainerEntityId(m_instanceFocusHierarchy[index]);
int i = 0;
RootAliasPath indexedPath;
for (const auto& pathElement : m_rootAliasFocusPath)
{
indexedPath.Append(pathElement);
if (i == index)
{
break;
}
++i;
}
InstanceOptionalReference focusedInstance = GetInstanceReference(indexedPath);
if (!focusedInstance.has_value())
{
return AZ::Failure(AZStd::string::format("Prefab Focus Handler: Could not retrieve instance at index %i.", index));
}
return FocusOnOwningPrefab(focusedInstance->get().GetContainerEntityId());
}
@@ -192,13 +219,14 @@ namespace AzToolsFramework::Prefab
}
// Close all container entities in the old path.
CloseInstanceContainers(m_instanceFocusHierarchy);
SetInstanceContainersOpenState(m_rootAliasFocusPath, false);
AZ::EntityId previousContainerEntityId = m_focusedInstanceContainerEntityId;
const RootAliasPath previousContainerRootAliasPath = m_rootAliasFocusPath;
const InstanceOptionalReference previousFocusedInstance = GetInstanceReference(previousContainerRootAliasPath);
// Do not store the container for the root instance, use an invalid EntityId instead.
m_focusedInstanceContainerEntityId = focusedInstance->get().GetParentInstance().has_value() ? focusedInstance->get().GetContainerEntityId() : AZ::EntityId();
m_rootAliasFocusPath = focusedInstance->get().GetAbsoluteInstanceAliasPath();
m_focusedTemplateId = focusedInstance->get().GetTemplateId();
m_rootAliasFocusPathLength = aznumeric_cast<int>(AZStd::distance(m_rootAliasFocusPath.begin(), m_rootAliasFocusPath.end()));
// Focus on the descendants of the container entity in the Editor, if the interface is initialized.
if (m_focusModeInterface)
@@ -214,15 +242,22 @@ namespace AzToolsFramework::Prefab
// Refresh the read-only cache, if the interface is initialized.
if (m_readOnlyEntityQueryInterface)
{
m_readOnlyEntityQueryInterface->RefreshReadOnlyState({ previousContainerEntityId, m_focusedInstanceContainerEntityId });
EntityIdList containerEntities;
if (previousFocusedInstance.has_value())
{
containerEntities.push_back(previousFocusedInstance->get().GetContainerEntityId());
}
containerEntities.push_back(focusedInstance->get().GetContainerEntityId());
m_readOnlyEntityQueryInterface->RefreshReadOnlyState(containerEntities);
}
// Refresh path variables.
RefreshInstanceFocusList();
RefreshInstanceFocusPath();
// Open all container entities in the new path.
OpenInstanceContainers(m_instanceFocusHierarchy);
SetInstanceContainersOpenState(m_rootAliasFocusPath, true);
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
@@ -237,17 +272,12 @@ namespace AzToolsFramework::Prefab
InstanceOptionalReference PrefabFocusHandler::GetFocusedPrefabInstance(
[[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
return GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
return GetInstanceReference(m_rootAliasFocusPath);
}
AZ::EntityId PrefabFocusHandler::GetFocusedPrefabContainerEntityId([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
if (m_focusedInstanceContainerEntityId.IsValid())
{
return m_focusedInstanceContainerEntityId;
}
if (auto instance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId); instance.has_value())
if (const InstanceOptionalReference instance = GetInstanceReference(m_rootAliasFocusPath); instance.has_value())
{
return instance->get().GetContainerEntityId();
}
@@ -262,19 +292,13 @@ namespace AzToolsFramework::Prefab
return false;
}
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
const InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
if (!instance.has_value())
{
return false;
}
// If this is owned by the root instance, that corresponds to an invalid m_focusedInstanceContainerEntityId.
if (!instance->get().GetParentInstance().has_value())
{
return !m_focusedInstanceContainerEntityId.IsValid();
}
return (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId);
return (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath);
}
bool PrefabFocusHandler::IsOwningPrefabInFocusHierarchy(AZ::EntityId entityId) const
@@ -284,18 +308,10 @@ namespace AzToolsFramework::Prefab
return false;
}
// If the focus is on the root, m_focusedInstanceContainerEntityId will be the invalid id.
// In those case all entities are in the focus hierarchy and should return true.
if (!m_focusedInstanceContainerEntityId.IsValid())
{
return true;
}
InstanceOptionalReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
InstanceOptionalConstReference instance = m_instanceEntityMapperInterface->FindOwningInstance(entityId);
while (instance.has_value())
{
if (instance->get().GetContainerEntityId() == m_focusedInstanceContainerEntityId)
if (instance->get().GetAbsoluteInstanceAliasPath() == m_rootAliasFocusPath)
{
return true;
}
@@ -308,40 +324,47 @@ namespace AzToolsFramework::Prefab
const AZ::IO::Path& PrefabFocusHandler::GetPrefabFocusPath([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
return m_instanceFocusPath;
return m_filenameFocusPath;
}
const int PrefabFocusHandler::GetPrefabFocusPathLength([[maybe_unused]] AzFramework::EntityContextId entityContextId) const
{
return aznumeric_cast<int>(m_instanceFocusHierarchy.size());
return m_rootAliasFocusPathLength;
}
void PrefabFocusHandler::OnContextReset()
{
// Clear the old focus vector
m_instanceFocusHierarchy.clear();
// Focus on the root prefab (AZ::EntityId() will default to it)
FocusOnPrefabInstanceOwningEntityId(AZ::EntityId());
}
void PrefabFocusHandler::OnEntityInfoUpdatedName(AZ::EntityId entityId, [[maybe_unused]]const AZStd::string& name)
{
// Determine if the entityId is the container for any of the instances in the vector.
auto result = AZStd::find_if(
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
[&, entityId](const AZ::EntityId& containerEntityId)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
return (instance->get().GetContainerEntityId() == entityId);
}
);
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (result != m_instanceFocusHierarchy.end())
if (prefabEditorEntityOwnershipInterface)
{
// Refresh the path and notify changes.
RefreshInstanceFocusPath();
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
// Determine if the entityId is the container for any of the instances in the vector.
bool match = prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
m_rootAliasFocusPath,
[&](const Prefab::InstanceOptionalReference instance)
{
if (instance->get().GetContainerEntityId() == entityId)
{
return true;
}
return false;
}
);
if (match)
{
// Refresh the path and notify changes.
RefreshInstanceFocusPath();
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
}
}
}
@@ -354,108 +377,81 @@ namespace AzToolsFramework::Prefab
void PrefabFocusHandler::OnPrefabTemplateDirtyFlagUpdated(TemplateId templateId, [[maybe_unused]] bool status)
{
// Determine if the templateId matches any of the instances in the vector.
auto result = AZStd::find_if(
m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end(),
[&, templateId](const AZ::EntityId& containerEntityId)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
return (instance->get().GetTemplateId() == templateId);
}
);
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (result != m_instanceFocusHierarchy.end())
if (prefabEditorEntityOwnershipInterface)
{
// Refresh the path and notify changes.
RefreshInstanceFocusPath();
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
}
}
// Determine if the templateId matches any of the instances in the vector.
bool match = prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
m_rootAliasFocusPath,
[&](const Prefab::InstanceOptionalReference instance)
{
if (instance->get().GetTemplateId() == templateId)
{
return true;
}
void PrefabFocusHandler::RefreshInstanceFocusList()
{
m_instanceFocusHierarchy.clear();
return false;
}
);
AZStd::list<InstanceOptionalReference> instanceFocusList;
InstanceOptionalReference currentInstance = GetReferenceFromContainerEntityId(m_focusedInstanceContainerEntityId);
while (currentInstance.has_value())
{
if (currentInstance->get().GetParentInstance().has_value())
if (match)
{
m_instanceFocusHierarchy.emplace_back(currentInstance->get().GetContainerEntityId());
// Refresh the path and notify changes.
RefreshInstanceFocusPath();
PrefabFocusNotificationBus::Broadcast(&PrefabFocusNotifications::OnPrefabFocusChanged);
}
else
{
m_instanceFocusHierarchy.emplace_back(AZ::EntityId());
}
currentInstance = currentInstance->get().GetParentInstance();
}
// Invert the vector, since we need the top instance to be at index 0.
AZStd::reverse(m_instanceFocusHierarchy.begin(), m_instanceFocusHierarchy.end());
}
void PrefabFocusHandler::RefreshInstanceFocusPath()
{
auto prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
m_instanceFocusPath.clear();
size_t index = 0;
size_t maxIndex = m_instanceFocusHierarchy.size() - 1;
for (const AZ::EntityId& containerEntityId : m_instanceFocusHierarchy)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
if (instance.has_value())
{
AZStd::string prefabName;
if (index < maxIndex)
{
// Get the filename without the extension (stem).
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
}
else
{
// Get the full filename.
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
}
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
{
prefabName += "*";
}
m_instanceFocusPath.Append(prefabName);
}
++index;
}
}
void PrefabFocusHandler::OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
{
// If this is called outside the Editor, this interface won't be initialized.
if (!m_containerEntityInterface)
{
return;
}
m_filenameFocusPath.clear();
for (const AZ::EntityId& containerEntityId : instances)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
PrefabSystemComponentInterface* prefabSystemComponentInterface = AZ::Interface<PrefabSystemComponentInterface>::Get();
if (instance.has_value())
{
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), true);
}
if (prefabEditorEntityOwnershipInterface && prefabSystemComponentInterface)
{
int i = 0;
prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
m_rootAliasFocusPath,
[&](const Prefab::InstanceOptionalReference instance)
{
if (instance.has_value())
{
AZStd::string prefabName;
if (i == m_rootAliasFocusPathLength - 1)
{
// Get the full filename.
prefabName = instance->get().GetTemplateSourcePath().Filename().Native();
}
else
{
// Get the filename without the extension (stem).
prefabName = instance->get().GetTemplateSourcePath().Stem().Native();
}
if (prefabSystemComponentInterface->IsTemplateDirty(instance->get().GetTemplateId()))
{
prefabName += "*";
}
m_filenameFocusPath.Append(prefabName);
}
++i;
return false;
}
);
}
}
void PrefabFocusHandler::CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const
void PrefabFocusHandler::SetInstanceContainersOpenState(const RootAliasPath& rootAliasPath, bool openState) const
{
// If this is called outside the Editor, this interface won't be initialized.
if (!m_containerEntityInterface)
@@ -463,33 +459,34 @@ namespace AzToolsFramework::Prefab
return;
}
for (const AZ::EntityId& containerEntityId : instances)
{
InstanceOptionalReference instance = GetReferenceFromContainerEntityId(containerEntityId);
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (instance.has_value())
{
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), false);
}
if (prefabEditorEntityOwnershipInterface)
{
prefabEditorEntityOwnershipInterface->GetInstancesInRootAliasPath(
rootAliasPath,
[&](const Prefab::InstanceOptionalReference instance)
{
m_containerEntityInterface->SetContainerOpen(instance->get().GetContainerEntityId(), openState);
return false;
}
);
}
}
InstanceOptionalReference PrefabFocusHandler::GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const
InstanceOptionalReference PrefabFocusHandler::GetInstanceReference(RootAliasPath rootAliasPath) const
{
if (!containerEntityId.IsValid())
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (prefabEditorEntityOwnershipInterface)
{
PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<PrefabEditorEntityOwnershipInterface>::Get();
if (!prefabEditorEntityOwnershipInterface)
{
return AZStd::nullopt;
}
return prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
return prefabEditorEntityOwnershipInterface->GetInstanceReferenceFromRootAliasPath(rootAliasPath);
}
return m_instanceEntityMapperInterface->FindOwningInstance(containerEntityId);
return AZStd::nullopt;
}
} // namespace AzToolsFramework::Prefab
@@ -12,6 +12,7 @@
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
#include <AzToolsFramework/Entity/PrefabEditorEntityOwnershipInterface.h>
#include <AzToolsFramework/FocusMode/FocusModeInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusInterface.h>
#include <AzToolsFramework/Prefab/PrefabFocusPublicInterface.h>
@@ -28,6 +29,7 @@ namespace AzToolsFramework
namespace AzToolsFramework::Prefab
{
class InstanceEntityMapperInterface;
class PrefabSystemComponentInterface;
//! Handles Prefab Focus mode, determining which prefab file entity changes will target.
class PrefabFocusHandler final
@@ -73,23 +75,20 @@ namespace AzToolsFramework::Prefab
private:
PrefabFocusOperationResult FocusOnPrefabInstance(InstanceOptionalReference focusedInstance);
void RefreshInstanceFocusList();
void RefreshInstanceFocusPath();
void OpenInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
void CloseInstanceContainers(const AZStd::vector<AZ::EntityId>& instances) const;
void SetInstanceContainersOpenState(const RootAliasPath& rootAliasPath, bool openState) const;
InstanceOptionalReference GetReferenceFromContainerEntityId(AZ::EntityId containerEntityId) const;
InstanceOptionalReference GetInstanceReference(RootAliasPath rootAliasPath) const;
//! The EntityId of the prefab container entity for the instance the editor is currently focusing on.
AZ::EntityId m_focusedInstanceContainerEntityId = AZ::EntityId();
//! The alias path for the instance the editor is currently focusing on, starting from the root instance.
RootAliasPath m_rootAliasFocusPath = RootAliasPath();
//! The templateId of the focused instance.
TemplateId m_focusedTemplateId;
//! The list of instances going from the root (index 0) to the focused instance,
//! referenced by their prefab container's EntityId.
AZStd::vector<AZ::EntityId> m_instanceFocusHierarchy;
//! A path containing the filenames of the instances in the focus hierarchy, separated with a /.
AZ::IO::Path m_instanceFocusPath;
AZ::IO::Path m_filenameFocusPath;
//! The length of the current focus path. Stored to simplify internal checks.
int m_rootAliasFocusPathLength = 0;
ContainerEntityInterface* m_containerEntityInterface = nullptr;
FocusModeInterface* m_focusModeInterface = nullptr;
@@ -815,7 +815,8 @@ namespace AzToolsFramework
if (templateRef.has_value())
{
return templateRef->get().IsDirty();
return !templateRef->get().IsProcedural() && // all procedural prefabs are read-only
templateRef->get().IsDirty();
}
return false;
@@ -349,7 +349,7 @@ namespace AzToolsFramework
return false;
}
StatementPrototype stmt("SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=:1;");
StatementPrototype stmt("SELECT COUNT(*) FROM sqlite_schema WHERE type='table' AND name=:1;");
Statement* execute = stmt.Prepare(m_db); // execute now belongs to stmt and will die when stmt leaves scope.
if (!execute->Prepared())
{
@@ -501,7 +501,7 @@ namespace AzToolsFramework
// https://www.sqlite.org/c3ref/prepare.html ^^^^^^^^^
int res = sqlite3_prepare_v2(db, m_parentPrototype->GetSqlText().c_str(), (int)m_parentPrototype->GetSqlText().length() + 1, &m_statement, NULL);
AZ_Assert(res == SQLITE_OK, "Statement::PrepareFirstTime: failed! %s ( prototype is '%s'). Error code returned is %d.", sqlite3_errmsg(db), m_parentPrototype->GetSqlText().c_str(), res);
return ((res == SQLITE_OK)&&(m_statement));
}
@@ -703,7 +703,7 @@ namespace AzToolsFramework
int res = sqlite3_clear_bindings(m_statement);
AZ_Assert(res == SQLITE_OK, "Statement::sqlite3_clear_bindings: failed!");
return (res == SQLITE_OK);
}
int Statement::GetNamedParamIdx(const char* name)
@@ -783,6 +783,7 @@ namespace AzToolsFramework
}
EBUS_EVENT(ToolsApplicationEvents::Bus, InvalidatePropertyDisplay, Refresh_EntireTree);
ToolsApplicationRequests::Bus::Broadcast(&ToolsApplicationRequests::Bus::Events::AddDirtyEntity, GetEntityId());
}
void ScriptEditorComponent::LoadProperties()
@@ -41,6 +41,11 @@ namespace UnitTest
&AzToolsFramework::EditorEntityContextRequests::HandleEntitiesAdded,
AzToolsFramework::EntityList{ m_entityMap[Passenger1EntityName], m_entityMap[Passenger2EntityName], m_entityMap[CityEntityName] });
// Initialize Prefab EOS Interface
AzToolsFramework::PrefabEditorEntityOwnershipInterface* prefabEditorEntityOwnershipInterface =
AZ::Interface<AzToolsFramework::PrefabEditorEntityOwnershipInterface>::Get();
ASSERT_TRUE(prefabEditorEntityOwnershipInterface);
// Create a car prefab from the passenger1 entity. The container entity will be created as part of the process.
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> carInstance =
m_prefabSystemComponent->CreatePrefab({ m_entityMap[Passenger1EntityName] }, {}, "test/car");
@@ -59,11 +64,14 @@ namespace UnitTest
ASSERT_TRUE(streetInstance);
m_instanceMap[StreetEntityName] = streetInstance.get();
// Create a city prefab that nests the street instances created above and the city entity. The container entity will be created as part of the process.
m_rootInstance =
m_prefabSystemComponent->CreatePrefab({ m_entityMap[CityEntityName] }, MakeInstanceList(AZStd::move(streetInstance)), "test/city");
ASSERT_TRUE(m_rootInstance);
m_instanceMap[CityEntityName] = m_rootInstance.get();
// Use the Prefab EOS root instance as the City instance. This will ensure functions that go through the EOS work in these tests too.
m_rootInstance = prefabEditorEntityOwnershipInterface->GetRootPrefabInstance();
ASSERT_TRUE(m_rootInstance.has_value());
m_rootInstance->get().AddEntity(*m_entityMap[CityEntityName]);
m_rootInstance->get().AddInstance(AZStd::move(streetInstance));
m_instanceMap[CityEntityName] = &m_rootInstance->get();
}
void SetUpEditorFixtureImpl() override
@@ -84,7 +92,7 @@ namespace UnitTest
void TearDownEditorFixtureImpl() override
{
m_rootInstance.release();
m_rootInstance->get().Reset();
PrefabTestFixture::TearDownEditorFixtureImpl();
}
@@ -92,7 +100,7 @@ namespace UnitTest
AZStd::unordered_map<AZStd::string, AZ::Entity*> m_entityMap;
AZStd::unordered_map<AZStd::string, Instance*> m_instanceMap;
AZStd::unique_ptr<AzToolsFramework::Prefab::Instance> m_rootInstance;
InstanceOptionalReference m_rootInstance;
PrefabFocusInterface* m_prefabFocusInterface = nullptr;
PrefabFocusPublicInterface* m_prefabFocusPublicInterface = nullptr;
@@ -106,9 +114,7 @@ namespace UnitTest
inline static const char* Passenger2EntityName = "Passenger2";
};
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
// which is not used by our test environment. This can be restored once Instance handles are implemented.
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootContainer)
TEST_F(PrefabFocusTests, FocusOnOwningPrefabRootContainer)
{
// Verify FocusOnOwningPrefab works when passing the container entity of the root prefab.
{
@@ -123,9 +129,7 @@ namespace UnitTest
}
}
// Test was disabled because the implementation of GetFocusedPrefabInstance now relies on the Prefab EOS,
// which is not used by our test environment. This can be restored once Instance handles are implemented.
TEST_F(PrefabFocusTests, DISABLED_PrefabFocus_FocusOnOwningPrefab_RootEntity)
TEST_F(PrefabFocusTests, FocusOnOwningPrefabRootEntity)
{
// Verify FocusOnOwningPrefab works when passing a nested entity of the root prefab.
{
@@ -140,7 +144,7 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_NestedContainer)
TEST_F(PrefabFocusTests, FocusOnOwningPrefabNestedContainer)
{
// Verify FocusOnOwningPrefab works when passing the container entity of a nested prefab.
{
@@ -154,7 +158,7 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_NestedEntity)
TEST_F(PrefabFocusTests, FocusOnOwningPrefabNestedEntity)
{
// Verify FocusOnOwningPrefab works when passing a nested entity of the a nested prefab.
{
@@ -168,7 +172,7 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_FocusOnOwningPrefab_Clear)
TEST_F(PrefabFocusTests, FocusOnOwningPrefabClear)
{
// Verify FocusOnOwningPrefab points to the root prefab when the focus is cleared.
{
@@ -188,7 +192,32 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_Content)
TEST_F(PrefabFocusTests, FocusOnParentOfFocusedPrefabLeaf)
{
// Call FocusOnParentOfFocusedPrefab on a leaf instance and verify the parent is focused correctly.
{
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CarEntityName]->GetContainerEntityId());
m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(m_editorEntityContextId);
EXPECT_EQ(
&m_prefabFocusInterface->GetFocusedPrefabInstance(m_editorEntityContextId)->get(),
m_instanceMap[StreetEntityName]
);
}
}
TEST_F(PrefabFocusTests, FocusOnParentOfFocusedPrefabRoot)
{
// Call FocusOnParentOfFocusedPrefab on the root instance and verify the operation fails.
{
m_prefabFocusPublicInterface->FocusOnOwningPrefab(m_instanceMap[CityEntityName]->GetContainerEntityId());
auto outcome = m_prefabFocusPublicInterface->FocusOnParentOfFocusedPrefab(m_editorEntityContextId);
EXPECT_FALSE(outcome.IsSuccess());
}
}
TEST_F(PrefabFocusTests, IsOwningPrefabBeingFocusedContent)
{
// Verify IsOwningPrefabBeingFocused returns true for all entities in a focused prefab (container/nested)
{
@@ -199,7 +228,7 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_AncestorsDescendants)
TEST_F(PrefabFocusTests, IsOwningPrefabBeingFocusedAncestorsDescendants)
{
// Verify IsOwningPrefabBeingFocused returns false for all entities not in a focused prefab (ancestors/descendants)
{
@@ -213,7 +242,7 @@ namespace UnitTest
}
}
TEST_F(PrefabFocusTests, PrefabFocus_IsOwningPrefabBeingFocused_Siblings)
TEST_F(PrefabFocusTests, IsOwningPrefabBeingFocusedSiblings)
{
// Verify IsOwningPrefabBeingFocused returns false for all entities not in a focused prefab (siblings)
{
@@ -19,13 +19,15 @@
#define AZ_DebugSecureSocket(...)
#define AZ_DebugSecureSocketConnection(window, fmt, ...)
//#define AZ_DebugUseSocketDebugLog
//#define AZ_DebugSecureSocket AZ_TracePrintf
//#define AZ_DebugSecureSocketConnection(window, fmt, ...) \
//{\
// AZStd::string line = AZStd::string::format(fmt, __VA_ARGS__);\
// this->m_dbgLog += line;\
//}
/*
#define AZ_DebugUseSocketDebugLog
#define AZ_DebugSecureSocket AZ_TracePrintf
#define AZ_DebugSecureSocketConnection(window, fmt, ...) \
{\
AZStd::string line = AZStd::string::format(fmt, __VA_ARGS__);\
this->m_dbgLog += line;\
}
*/
#if AZ_TRAIT_GRIDMATE_SECURE_SOCKET_DRIVER_HOOK_ENABLED
struct ssl_st;
@@ -41,7 +41,7 @@ bool CLevelInfo::OpenLevelPak()
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
// The prefab system doesn't use level.pak
if (usePrefabSystemForLevels)
@@ -62,7 +62,7 @@ void CLevelInfo::CloseLevelPak()
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
// The prefab system doesn't use level.pak
if (usePrefabSystemForLevels)
@@ -82,7 +82,7 @@ bool CLevelInfo::ReadInfo()
{
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
// Set up a default game type for legacy code.
m_defaultGameTypeName = "mission0";
+1 -1
View File
@@ -1046,7 +1046,7 @@ AZ_POP_DISABLE_WARNING
// LEVEL SYSTEM
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
if (usePrefabSystemForLevels)
{
+4 -2
View File
@@ -44,8 +44,6 @@ ly_add_target(
AZ::AssetBuilderSDK
AZ::AssetBuilder.Static
${additional_dependencies}
RUNTIME_DEPENDENCIES
AZ::AssetBuilder
)
# Aggregates all combined AssetBuilders into a single LY_ASSET_BUILDERS #define
@@ -76,6 +74,8 @@ ly_add_target(
BUILD_DEPENDENCIES
PRIVATE
AZ::AssetProcessor.Static
RUNTIME_DEPENDENCIES
AZ::AssetBuilder
)
# Adds the AssetProcessor target as a C preprocessor define so that it can be used as a Settings Registry
@@ -122,6 +122,8 @@ ly_add_target(
BUILD_DEPENDENCIES
PRIVATE
AZ::AssetProcessorBatch.Static
RUNTIME_DEPENDENCIES
AZ::AssetBuilder
)
if(LY_DEFAULT_PROJECT_PATH)
@@ -2942,11 +2942,20 @@ namespace AssetProcessor
// File is a source file that has been processed before
AZStd::string fingerprintFromDatabase = sourceFileItr->m_analysisFingerprint.toUtf8().data();
AZStd::string_view builderEntries(fingerprintFromDatabase.begin() + s_lengthOfUuid + 1, fingerprintFromDatabase.end());
AZStd::string_view dependencyFingerprint(fingerprintFromDatabase.begin(), fingerprintFromDatabase.begin() + s_lengthOfUuid);
int numBuildersEmittingSourceDependencies = 0;
if (!fingerprintFromDatabase.empty() && AreBuildersUnchanged(builderEntries, numBuildersEmittingSourceDependencies))
{
// Builder(s) have not changed since last time
AZStd::string currentFingerprint = ComputeRecursiveDependenciesFingerprint(
fileInfo.m_filePath.toUtf8().constData(), sourceFileItr->m_sourceDatabaseName.toUtf8().constData());
if(dependencyFingerprint != currentFingerprint)
{
// Dependencies have changed
return false;
}
// Success - we can skip this file, nothing has changed!
// Remove it from the list of to-be-processed files, otherwise the AP will assume the file was deleted
@@ -4311,6 +4320,32 @@ namespace AssetProcessor
}
}
AZStd::string AssetProcessorManager::ComputeRecursiveDependenciesFingerprint(const AZStd::string& fileAbsolutePath, const AZStd::string& fileDatabaseName)
{
AZStd::string concatenatedFingerprints;
// QSet is not ordered.
SourceFilesForFingerprintingContainer knownDependenciesAbsolutePaths;
// this automatically adds the input file to the list:
QueryAbsolutePathDependenciesRecursive(QString::fromUtf8(fileDatabaseName.c_str()), knownDependenciesAbsolutePaths,
AzToolsFramework::AssetDatabase::SourceFileDependencyEntry::DEP_Any, false);
AddMetadataFilesForFingerprinting(QString::fromUtf8(fileAbsolutePath.c_str()), knownDependenciesAbsolutePaths);
// reserve 17 chars for each since its a 64 bit hex number, and then one more for the dash inbetween each.
constexpr int bytesPerFingerprint = (sizeof(AZ::u64) * 2) + 1; // 2 HEX characters per byte +1 for the `-` we will add between each fingerprint
concatenatedFingerprints.reserve((knownDependenciesAbsolutePaths.size() * bytesPerFingerprint));
for (const auto& element : knownDependenciesAbsolutePaths)
{
// if its a placeholder then don't bother hitting the disk to find it.
concatenatedFingerprints.append(AssetUtilities::GetFileFingerprint(element.first, element.second));
concatenatedFingerprints.append("-");
}
// to keep this from growing out of hand, we don't use the full string, we use a hash of it:
return AZ::Uuid::CreateName(concatenatedFingerprints.c_str()).ToString<AZStd::string>();
}
void AssetProcessorManager::FinishAnalysis(AZStd::string fileToCheck)
{
using namespace AzToolsFramework::AssetDatabase;
@@ -4378,29 +4413,9 @@ namespace AssetProcessor
if (found)
{
// construct the analysis fingerprint
// the format for this data is "modtimefingerprint:builder0:builder1:builder2:...:buildern"
source.m_analysisFingerprint.clear();
// compute mod times:
// get the appropriate modtimes:
AZStd::string modTimeArray;
// the format for this data is "hashfingerprint:builder0:builder1:builder2:...:buildern"
source.m_analysisFingerprint = ComputeRecursiveDependenciesFingerprint(fileToCheck, analysisTracker->m_databaseSourceName);
// QSet is not ordered.
SourceFilesForFingerprintingContainer knownDependenciesAbsolutePaths;
// this automatically adds the input file to the list:
QueryAbsolutePathDependenciesRecursive(QString::fromUtf8(analysisTracker->m_databaseSourceName.c_str()), knownDependenciesAbsolutePaths, SourceFileDependencyEntry::DEP_Any, false);
AddMetadataFilesForFingerprinting(QString::fromUtf8(fileToCheck.c_str()), knownDependenciesAbsolutePaths);
// reserve 17 chars for each since its a 64 bit hex number, and then one more for the dash inbetween each.
modTimeArray.reserve((knownDependenciesAbsolutePaths.size() * 17));
for (const auto& element : knownDependenciesAbsolutePaths)
{
// if its a placeholder then don't bother hitting the disk to find it.
modTimeArray.append(AssetUtilities::GetFileFingerprint(element.first, element.second));
modTimeArray.append("-");
}
// to keep this from growing out of hand, we don't use the full string, we use a hash of it:
source.m_analysisFingerprint = AZ::Uuid::CreateName(modTimeArray.c_str()).ToString<AZStd::string>();
for (const AZ::Uuid& builderID : analysisTracker->m_buildersInvolved)
{
source.m_analysisFingerprint.append(":");
@@ -4423,7 +4438,7 @@ namespace AssetProcessor
const ScanFolderInfo* scanFolder = m_platformConfig->GetScanFolderForFile(fileToCheck.c_str());
scanFolderPk = aznumeric_cast<int>(scanFolder->ScanFolderID());
m_platformConfig->ConvertToRelativePath(fileToCheck.c_str(), scanFolder, databaseSourceName);
PlatformConfiguration::ConvertToRelativePath(fileToCheck.c_str(), scanFolder, databaseSourceName);
}
// Record the modtime for the file so we know we processed it
@@ -485,6 +485,7 @@ namespace AssetProcessor
};
void ComputeBuilderDirty();
AZStd::string ComputeRecursiveDependenciesFingerprint(const AZStd::string& fileAbsolutePath, const AZStd::string& fileDatabaseName);
AZStd::unordered_map<AZ::Uuid, BuilderData> m_builderDataCache;
bool m_buildersAddedOrRemoved = true; //< true if any new builders exist. If this happens we actually need to re-analyze everything.
bool m_anyBuilderChange = true;
@@ -516,6 +516,79 @@ namespace UnitTests
ASSERT_EQ(m_data->m_processResults.size(), 2);
}
TEST_F(ModtimeScanningTest, AssetProcessorIsRestartedBeforeDependencyIsProcessed_DependencyIsProcessedOnStart)
{
using namespace AzToolsFramework::AssetSystem;
auto theFile = m_data->m_absolutePath[1].toUtf8();
const char* theFileString = theFile.constData();
SetFileContents(theFileString, "hello world");
// Enable the features we're testing
m_assetProcessorManager->SetEnableModtimeSkippingFeature(true);
AssetUtilities::SetUseFileHashOverride(true, true);
QSet<AssetFileInfo> filePaths = BuildFileSet();
SimulateAssetScanner(filePaths);
// Even though we're only updating one file, we're expecting 2 createJob calls because our test file is a dependency that triggers
// the other test file to process as well
ExpectWork(2, 2);
// Sort the results and process the first one, which should always be the modtimeTestDependency.txt file
// which is the same file we modified above. modtimeTestFile.txt depends on this file but we're not going to process it yet.
{
std::sort(
m_data->m_processResults.begin(), m_data->m_processResults.end(),
[](decltype(m_data->m_processResults[0])& left, decltype(left)& right)
{
return left.m_jobEntry.m_databaseSourceName < right.m_jobEntry.m_databaseSourceName;
});
const auto& processResult = m_data->m_processResults[0];
auto file =
QDir(processResult.m_destinationPath).absoluteFilePath(processResult.m_jobEntry.m_databaseSourceName.toLower() + ".arc1");
m_data->m_productPaths.emplace(
QDir(processResult.m_jobEntry.m_watchFolderPath)
.absoluteFilePath(processResult.m_jobEntry.m_databaseSourceName)
.toUtf8()
.constData(),
file);
// Create the file on disk
ASSERT_TRUE(UnitTestUtils::CreateDummyFile(file, "products."));
AssetBuilderSDK::ProcessJobResponse response;
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(file.toUtf8().constData(), AZ::Uuid::CreateNull(), 1));
using JobEntry = AssetProcessor::JobEntry;
QMetaObject::invokeMethod(
m_assetProcessorManager.get(), "AssetProcessed", Qt::QueuedConnection, Q_ARG(JobEntry, processResult.m_jobEntry),
Q_ARG(AssetBuilderSDK::ProcessJobResponse, response));
}
ASSERT_TRUE(BlockUntilIdle(5000));
// Shutdown and restart the APM
m_assetProcessorManager.reset();
m_assetProcessorManager = AZStd::make_unique<AssetProcessorManager_Test>(m_config.get());
SetUpAssetProcessorManager();
m_data->m_mockBuilderInfoHandler.m_createJobsCount = 0;
m_data->m_processResults.clear();
m_data->m_deletedSources.clear();
// Re-run the scanner on our files
filePaths = BuildFileSet();
SimulateAssetScanner(filePaths);
// Expect processing to resume on the job we didn't process before
ExpectWork(1, 1);
}
void DeleteTest::SetUp()
{
AssetProcessorManagerTest::SetUp();
@@ -13,7 +13,7 @@ namespace AzTestRunner
{
void set_quiet_mode()
{
freopen("/dev/null", "a", stdout);
[[maybe_unused]] auto freopenResult = freopen("/dev/null", "a", stdout);
}
const char* get_current_working_directory()
@@ -24,7 +24,7 @@ namespace AzTestRunner
void pause_on_completion()
{
system("pause");
[[maybe_unused]] auto systemResult = system("pause");
}
}
@@ -108,7 +108,7 @@ namespace LUAEditor
m_settingsDialog = aznew LUAEditorSettingsDialog(this);
actionTabForwards = new QAction(tr("Next Document Tab"), this);
actionTabBackwards = new QAction(tr("Prev Document Tab"), this);
actionTabBackwards = new QAction(tr("Previous Document Tab"), this);
actionTabForwards->setShortcut(QKeySequence("Ctrl+Tab"));
connect(actionTabForwards, SIGNAL(triggered(bool)), this, SLOT(OnTabForwards()));
@@ -115,22 +115,22 @@ namespace AZ
const aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[sdkMeshIndex]];
if(mesh->mTextureCoords[texCoordIndex])
{
if (mesh->mTextureCoordsNames[texCoordIndex].length > 0)
if (mesh->HasTextureCoordsName(texCoordIndex))
{
if (!customNameFound)
{
name = mesh->mTextureCoordsNames[texCoordIndex].C_Str();
name = mesh->GetTextureCoordsName(texCoordIndex)->C_Str();
customNameFound = true;
}
else
{
AZ_Warning(Utilities::WarningWindow,
strcmp(name.c_str(), mesh->mTextureCoordsNames[texCoordIndex].C_Str()) == 0,
strcmp(name.c_str(), mesh->GetTextureCoordsName(texCoordIndex)->C_Str()) == 0,
"Node %s has conflicting mesh coordinate names at index %d, %s and %s. Using %s.",
currentNode->mName.C_Str(),
texCoordIndex,
name.c_str(),
mesh->mTextureCoordsNames[texCoordIndex].C_Str(),
mesh->GetTextureCoordsName(texCoordIndex)->C_Str(),
name.c_str());
}
}
@@ -29,6 +29,7 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IAnimationData>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetKeyFrameCount", &SceneAPI::DataTypes::IAnimationData::GetKeyFrameCount)
@@ -97,6 +98,7 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IBlendShapeAnimationData>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetBlendShapeName", &SceneAPI::DataTypes::IBlendShapeAnimationData::GetBlendShapeName)
@@ -37,6 +37,7 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IBlendShapeData>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetUsedControlPointCount", &SceneAPI::DataTypes::IBlendShapeData::GetUsedControlPointCount)
@@ -47,6 +47,7 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IBoneData>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene");
behaviorContext->Class<AZ::SceneData::GraphData::BoneData>()
@@ -304,6 +304,7 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IMaterialData>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene");
@@ -33,6 +33,7 @@ namespace AZ
if (behaviorContext)
{
behaviorContext->Class<SceneAPI::DataTypes::IMeshData>()
->Attribute(Script::Attributes::ExcludeFrom, Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
->Attribute(AZ::Script::Attributes::Module, "scene")
->Method("GetUnitSizeInMeters", &MeshData::GetUnitSizeInMeters)