Merge branch 'development' of https://github.com/o3de/o3de into Network/olexl/nettransform_local_for_children_cr
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/UserSettings/UserSettings.h>
|
||||
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include <AzToolsFramework/UI/SearchWidget/SearchCriteriaWidget.hxx>
|
||||
#include <AzToolsFramework/Editor/EditorSettingsAPIBus.h>
|
||||
|
||||
//AzCore
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
// Editor
|
||||
#include "Clipboard.h"
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include "Include/EditorCoreAPI.h"
|
||||
#include "ReflectedPropertyItem.h"
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#define CRYINCLUDE_EDITOR_UTILS_REFLECTEDVAR_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "Util/VariablePropertyType.h"
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
|
||||
@@ -44,7 +44,7 @@ enum
|
||||
{
|
||||
// in milliseconds
|
||||
GameModeIdleFrequency = 0,
|
||||
EditorModeIdleFrequency = 0,
|
||||
EditorModeIdleFrequency = 1,
|
||||
InactiveModeFrequency = 10,
|
||||
UninitializedFrequency = 9999,
|
||||
};
|
||||
|
||||
@@ -175,27 +175,15 @@ namespace SandboxEditor
|
||||
m_pivotCamera = AZStd::make_shared<AzFramework::PivotCameraInput>(SandboxEditor::CameraPivotChannelId());
|
||||
|
||||
m_pivotCamera->SetPivotFn(
|
||||
[viewportId = m_viewportId]([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
|
||||
[]([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
|
||||
{
|
||||
AZStd::optional<AZ::Vector3> lookAtAfterInterpolation;
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
|
||||
lookAtAfterInterpolation, viewportId,
|
||||
&AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::LookAtAfterInterpolation);
|
||||
|
||||
// initially attempt to use the last set look at point after an interpolation has finished
|
||||
// note: ignore this if it is the same location as the camera (e.g. after go to position)
|
||||
if (lookAtAfterInterpolation.has_value() && !lookAtAfterInterpolation->IsClose(position))
|
||||
{
|
||||
return *lookAtAfterInterpolation;
|
||||
}
|
||||
|
||||
// otherwise fall back to the selected entity pivot
|
||||
// use the manipulator transform as the pivot point
|
||||
AZStd::optional<AZ::Transform> entityPivot;
|
||||
AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult(
|
||||
entityPivot, AzToolsFramework::GetEntityContextId(),
|
||||
&AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
|
||||
|
||||
// finally just use the identity
|
||||
// otherwise just use the identity
|
||||
return entityPivot.value_or(AZ::Transform::CreateIdentity()).GetTranslation();
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include "EditorPreferencesTreeWidgetItem.h"
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/UI/PropertyEditor/ReflectedPropertyEditor.hxx>
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace SandboxEditor
|
||||
{
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
viewportContext->GetId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(CameraRotation(pitch, yaw), position), 0.0f);
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(CameraRotation(pitch, yaw), position));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace UnitTest
|
||||
AZ::Quaternion::CreateRotationZ(AZ::DegToRad(90.0f)), AZ::Vector3(20.0f, 40.0f, 60.0f));
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
|
||||
transformToInterpolateTo, 0.0f);
|
||||
transformToInterpolateTo);
|
||||
|
||||
// simulate interpolation
|
||||
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(0.5f), AZ::ScriptTimePoint() });
|
||||
@@ -193,7 +193,7 @@ namespace UnitTest
|
||||
// When
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
|
||||
transformToInterpolateTo, 0.0f);
|
||||
transformToInterpolateTo);
|
||||
|
||||
// simulate interpolation
|
||||
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(0.5f), AZ::ScriptTimePoint() });
|
||||
|
||||
@@ -27,10 +27,11 @@ AZ_POP_DISABLE_WARNING
|
||||
#endif
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
|
||||
@@ -1739,8 +1739,7 @@ void SandboxIntegrationManager::GoToEntitiesInViewports(const AzToolsFramework::
|
||||
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
viewportContext->GetId(),
|
||||
&AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform, nextCameraTransform,
|
||||
distanceToLookAt);
|
||||
&AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform, nextCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
|
||||
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
|
||||
|
||||
|
||||
@@ -36,9 +36,6 @@
|
||||
#include "CryEdit.h"
|
||||
#include "Viewport.h"
|
||||
|
||||
// Atom Renderer
|
||||
#include <Atom/RPI.Public/RPISystemInterface.h>
|
||||
|
||||
AZ_PUSH_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
#include <TrackView/ui_SequenceBatchRenderDialog.h>
|
||||
AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING
|
||||
@@ -1237,13 +1234,6 @@ void CSequenceBatchRenderDialog::OnKickIdleTimout()
|
||||
{
|
||||
componentApplication->TickSystem();
|
||||
}
|
||||
|
||||
// Directly tick the renderer, as it's no longer part of the system tick
|
||||
if (auto rpiSystem = AZ::RPI::RPISystemInterface::Get())
|
||||
{
|
||||
rpiSystem->SimulationTick();
|
||||
rpiSystem->RenderTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
// Editor
|
||||
#include "AnimationContext.h"
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "ViewportTitleDlg.h"
|
||||
|
||||
// Qt
|
||||
#include <QLabel>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include <AtomLyIntegration/AtomViewportDisplayInfo/AtomViewportInfoDisplayBus.h>
|
||||
@@ -36,8 +37,10 @@
|
||||
#include "MathConversion.h"
|
||||
#include "EditorViewportSettings.h"
|
||||
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzFramework/API/ApplicationAPI.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
|
||||
@@ -145,6 +148,11 @@ CViewportTitleDlg::~CViewportTitleDlg()
|
||||
AZ::VR::VREventBus::Handler::BusDisconnect();
|
||||
GetISystem()->GetISystemEventDispatcher()->RemoveListener(this);
|
||||
GetIEditor()->UnregisterNotifyListener(this);
|
||||
|
||||
if (m_prefabViewportFocusPathHandler)
|
||||
{
|
||||
delete m_prefabViewportFocusPathHandler;
|
||||
}
|
||||
}
|
||||
|
||||
void CViewportTitleDlg::SetupCameraDropdownMenu()
|
||||
@@ -292,8 +300,6 @@ void CViewportTitleDlg::SetViewPane(CLayoutViewPane* pViewPane)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::OnInitDialog()
|
||||
{
|
||||
m_ui->m_titleBtn->setText(m_title);
|
||||
|
||||
// Add a child parented to us that listens for r_displayInfo changes.
|
||||
auto displayInfoHelper = new CViewportTitleDlgDisplayInfoHelper(this);
|
||||
connect(displayInfoHelper, &CViewportTitleDlgDisplayInfoHelper::ViewportInfoStatusUpdated, this, &CViewportTitleDlg::UpdateDisplayInfo);
|
||||
@@ -314,13 +320,28 @@ void CViewportTitleDlg::OnInitDialog()
|
||||
|
||||
m_cameraSpeed->setFixedWidth(width);
|
||||
|
||||
bool isPrefabSystemEnabled = false;
|
||||
AzFramework::ApplicationRequests::Bus::BroadcastResult(isPrefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled);
|
||||
|
||||
if (isPrefabSystemEnabled)
|
||||
{
|
||||
m_prefabViewportFocusPathHandler = new AzToolsFramework::Prefab::PrefabViewportFocusPathHandler();
|
||||
m_prefabViewportFocusPathHandler->Initialize(m_ui->m_prefabFocusPath, m_ui->m_prefabFocusBackButton);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->m_prefabFocusPath->setEnabled(false);
|
||||
m_ui->m_prefabFocusBackButton->setEnabled(false);
|
||||
m_ui->m_prefabFocusPath->hide();
|
||||
m_ui->m_prefabFocusBackButton->hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CViewportTitleDlg::SetTitle(const QString& title)
|
||||
{
|
||||
m_title = title;
|
||||
m_ui->m_titleBtn->setText(m_title);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <QWidgetAction>
|
||||
#include <QComboBox>
|
||||
|
||||
#include <AzToolsFramework/UI/Prefab/PrefabViewportFocusPathHandler.h>
|
||||
#include <AzQtComponents/Components/Widgets/SpinBox.h>
|
||||
|
||||
#include <HMDBus.h>
|
||||
@@ -176,6 +177,8 @@ protected:
|
||||
QWidgetAction* m_gridSizeActionWidget = nullptr;
|
||||
QWidgetAction* m_angleSizeActionWidget = nullptr;
|
||||
|
||||
AzToolsFramework::Prefab::PrefabViewportFocusPathHandler* m_prefabViewportFocusPathHandler = nullptr;
|
||||
|
||||
QScopedPointer<Ui::ViewportTitleDlg> m_ui;
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<height>29</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0,0,0,0,0,0,0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0,0,0,0,0,0,0">
|
||||
<property name="leftMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
@@ -42,102 +42,112 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_titleBtn">
|
||||
<widget class="QToolButton" name="m_prefabFocusBackButton">
|
||||
<property name="toolTip">
|
||||
<string>Up one level</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Breadcrumb/img/UI20/Breadcrumb/arrow_left-default.svg</normaloff>:/Breadcrumb/img/UI20/Breadcrumb/arrow_left-default.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AzQtComponents::BreadCrumbs" name="m_prefabFocusPath" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::NoContextMenu</enum>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Static</string>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>11</number>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_cameraMenu">
|
||||
<property name="toolTip">
|
||||
<string>Camera settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/camera.svg</normaloff>:/Menu/camera.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_cameraMenu">
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/camera.svg</normaloff>:/Menu/camera.svg
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Camera settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_debugInformationMenu">
|
||||
<property name="toolTip">
|
||||
<string>Debug information</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/debug.svg</normaloff>:/Menu/debug.svg
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_helpers">
|
||||
<property name="toolTip">
|
||||
<string>Toggle viewport helpers</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/helpers.svg</normaloff>:/Menu/helpers.svg
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_resolutionMenu">
|
||||
<property name="toolTip">
|
||||
<string>Viewport resolution</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/resolution.svg</normaloff>:/Menu/resolution.svg
|
||||
</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolButton" name="m_debugInformationMenu">
|
||||
<property name="toolTip">
|
||||
<string>Debug information</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/debug.svg</normaloff>:/Menu/debug.svg</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_overflowBtn">
|
||||
<property name="toolTip">
|
||||
<string>Other settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/menu.svg</normaloff>:/Menu/menu.svg
|
||||
</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QToolButton" name="m_helpers">
|
||||
<property name="toolTip">
|
||||
<string>Toggle viewport helpers</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/helpers.svg</normaloff>:/Menu/helpers.svg</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_resolutionMenu">
|
||||
<property name="toolTip">
|
||||
<string>Viewport resolution</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/resolution.svg</normaloff>:/Menu/resolution.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="m_overflowBtn">
|
||||
<property name="toolTip">
|
||||
<string>Other settings</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/Menu/menu.svg</normaloff>:/Menu/menu.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AzQtComponents::ButtonDivider</class>
|
||||
<class>AzQtComponents::BreadCrumbs</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>AzQtComponents/Components/ButtonDivider.h</header>
|
||||
<header>AzQtComponents/Components/Widgets/BreadCrumbs.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../Framework/AzQtComponents/AzQtComponents/Images/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
<resources>
|
||||
<include location="../../Framework/AzQtComponents/AzQtComponents/Images/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -89,6 +89,9 @@ namespace AZ
|
||||
|
||||
// Tracks the asset type used to create the instance.
|
||||
AssetType m_assetType;
|
||||
|
||||
// Boolean to indicate if the instance has been orphaned from the instance database
|
||||
bool m_isOrphaned = false;
|
||||
};
|
||||
|
||||
/// @cond EXCLUDE_DOCS
|
||||
|
||||
@@ -203,6 +203,16 @@ namespace AZ
|
||||
//! Calls FindOrCreate using a random InstanceId
|
||||
Data::Instance<Type> Create(const Asset<AssetData>& asset, const AZStd::any* param = nullptr);
|
||||
|
||||
/**
|
||||
* Removes the instance data from the database. Does not release it.
|
||||
* References to existing instances will remain valid, but new calls to Create/FindOrCreate will create a new instance
|
||||
* This function is temporary, to provide functionality needed for Model hot-reloading, but will be removed
|
||||
* once the Model class does not need it anymore.
|
||||
*
|
||||
* @param id The id of the instance to remove
|
||||
*/
|
||||
void TEMPOrphan(const InstanceId& id);
|
||||
|
||||
private:
|
||||
InstanceDatabase(const AssetType& assetType);
|
||||
~InstanceDatabase();
|
||||
@@ -356,6 +366,20 @@ namespace AZ
|
||||
return FindOrCreate(Data::InstanceId::CreateRandom(), asset, param);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::TEMPOrphan(const InstanceId& id)
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> lock(m_databaseMutex);
|
||||
// Check if the instance is still in the database, in case it was orphaned twice
|
||||
auto instanceItr = m_database.find(id);
|
||||
if (instanceItr != m_database.end())
|
||||
{
|
||||
// Mark the instance as orphaned, and remove it from the database
|
||||
instanceItr->second->m_isOrphaned = true;
|
||||
m_database.erase(instanceItr);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::ReleaseInstance(InstanceData* instance, const InstanceId& instanceId)
|
||||
{
|
||||
@@ -374,6 +398,12 @@ namespace AZ
|
||||
m_database.erase(instance->GetId());
|
||||
m_instanceHandler.m_deleteFunction(static_cast<Type*>(instance));
|
||||
}
|
||||
else if (instance->m_isOrphaned && instance->m_useCount.compare_exchange_strong(expectedRefCount, -1))
|
||||
{
|
||||
// If the instance was orphaned, it has already been removed from the database,
|
||||
// but still needs to be deleted when the refcount drops to 0
|
||||
m_instanceHandler.m_deleteFunction(static_cast<Type*>(instance));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
|
||||
@@ -181,7 +181,76 @@ namespace UnitTest
|
||||
EXPECT_EQ(instance, instance3);
|
||||
}
|
||||
|
||||
void ParallelInstanceCreateHelper(size_t threadCountMax, size_t assetIdCount, size_t durationSeconds)
|
||||
TEST_F(InstanceDatabaseTest, InstanceOrphan)
|
||||
{
|
||||
auto& assetManager = AssetManager::Instance();
|
||||
auto& instanceDatabase = InstanceDatabase<TestInstanceA>::Instance();
|
||||
|
||||
Asset<TestAssetType> someAsset = assetManager.CreateAsset<TestAssetType>(s_assetId0, AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
Instance<TestInstanceA> orphanedInstance = instanceDatabase.FindOrCreate(s_instanceId0, someAsset);
|
||||
EXPECT_NE(orphanedInstance, nullptr);
|
||||
|
||||
instanceDatabase.TEMPOrphan(s_instanceId0);
|
||||
// After orphan, the instance should not be found in the database, but it should still be valid
|
||||
EXPECT_EQ(instanceDatabase.Find(s_instanceId0), nullptr);
|
||||
EXPECT_NE(orphanedInstance, nullptr);
|
||||
|
||||
instanceDatabase.TEMPOrphan(s_instanceId0);
|
||||
// Orphaning twice should be a no-op
|
||||
EXPECT_EQ(instanceDatabase.Find(s_instanceId0), nullptr);
|
||||
EXPECT_NE(orphanedInstance, nullptr);
|
||||
|
||||
Instance<TestInstanceA> instance2 = instanceDatabase.FindOrCreate(s_instanceId0, someAsset);
|
||||
// Creating another instance with the same id should return a different instance than the one that was orphaned
|
||||
EXPECT_NE(orphanedInstance, instance2);
|
||||
}
|
||||
|
||||
enum class ParallelInstanceTestCases
|
||||
{
|
||||
Create,
|
||||
CreateAndDeferRemoval,
|
||||
CreateAndOrphan,
|
||||
CreateDeferRemovalAndOrphan
|
||||
};
|
||||
|
||||
enum class ParralleInstanceCurrentAction
|
||||
{
|
||||
Create,
|
||||
DeferredRemoval,
|
||||
Orphan
|
||||
};
|
||||
|
||||
ParralleInstanceCurrentAction ParallelInstanceGetCurrentAction(ParallelInstanceTestCases testCase)
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case ParallelInstanceTestCases::CreateAndDeferRemoval:
|
||||
switch (rand() % 2)
|
||||
{
|
||||
case 0: return ParralleInstanceCurrentAction::Create;
|
||||
case 1: return ParralleInstanceCurrentAction::DeferredRemoval;
|
||||
}
|
||||
case ParallelInstanceTestCases::CreateAndOrphan:
|
||||
switch (rand() % 2)
|
||||
{
|
||||
case 0: return ParralleInstanceCurrentAction::Create;
|
||||
case 1: return ParralleInstanceCurrentAction::Orphan;
|
||||
}
|
||||
case ParallelInstanceTestCases::CreateDeferRemovalAndOrphan:
|
||||
switch (rand() % 3)
|
||||
{
|
||||
case 0: return ParralleInstanceCurrentAction::Create;
|
||||
case 1: return ParralleInstanceCurrentAction::DeferredRemoval;
|
||||
case 2: return ParralleInstanceCurrentAction::Orphan;
|
||||
}
|
||||
case ParallelInstanceTestCases::Create:
|
||||
default:
|
||||
return ParralleInstanceCurrentAction::Create;
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelInstanceCreateHelper(size_t threadCountMax, size_t assetIdCount, float durationSeconds, ParallelInstanceTestCases testCase)
|
||||
{
|
||||
printf("Testing threads=%zu assetIds=%zu ... ", threadCountMax, assetIdCount);
|
||||
|
||||
@@ -192,6 +261,7 @@ namespace UnitTest
|
||||
auto& instanceManager = InstanceDatabase<TestInstanceA>::Instance();
|
||||
|
||||
AZStd::vector<Uuid> guids;
|
||||
AZStd::vector<Data::Instance<Data::InstanceData>> instances;
|
||||
AZStd::vector<Asset<TestAssetType>> assets;
|
||||
|
||||
for (size_t i = 0; i < assetIdCount; ++i)
|
||||
@@ -199,6 +269,7 @@ namespace UnitTest
|
||||
Uuid guid = Uuid::CreateRandom();
|
||||
|
||||
guids.emplace_back(guid);
|
||||
instances.emplace_back(nullptr);
|
||||
|
||||
// Pre-create asset so we don't attempt to load it from the catalog.
|
||||
assets.emplace_back(assetManager.CreateAsset<TestAssetType>(guid, AZ::Data::AssetLoadBehavior::Default));
|
||||
@@ -206,6 +277,7 @@ namespace UnitTest
|
||||
|
||||
AZStd::vector<AZStd::thread> threads;
|
||||
AZStd::mutex mutex;
|
||||
AZStd::mutex referenceTableMutex;
|
||||
AZStd::atomic<int> threadCount((int)threadCountMax);
|
||||
AZStd::condition_variable cv;
|
||||
AZStd::atomic_bool keepDispatching(true);
|
||||
@@ -225,11 +297,15 @@ namespace UnitTest
|
||||
for (size_t i = 0; i < threadCountMax; ++i)
|
||||
{
|
||||
threads.emplace_back(
|
||||
[&instanceManager, &threadCount, &cv, &guids, &assets, &durationSeconds]()
|
||||
[&instanceManager, &threadCount, &cv, &guids, &instances, &assets, &durationSeconds, &testCase, &referenceTableMutex]()
|
||||
{
|
||||
AZ::Debug::Timer timer;
|
||||
timer.Stamp();
|
||||
|
||||
bool deferRemoval = testCase == ParallelInstanceTestCases::CreateAndDeferRemoval ||
|
||||
testCase == ParallelInstanceTestCases::CreateDeferRemovalAndOrphan
|
||||
? true : false;
|
||||
|
||||
while (timer.GetDeltaTimeInSeconds() < durationSeconds)
|
||||
{
|
||||
const size_t index = rand() % guids.size();
|
||||
@@ -237,11 +313,36 @@ namespace UnitTest
|
||||
const InstanceId instanceId{ uuid };
|
||||
const AssetId assetId{ uuid };
|
||||
|
||||
Instance<TestInstanceA> instance =
|
||||
instanceManager.FindOrCreate(instanceId, Asset<TestAssetType>(assetId, azrtti_typeid<TestAssetType>()));
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
ParralleInstanceCurrentAction currentAction = ParallelInstanceGetCurrentAction(testCase);
|
||||
|
||||
if (currentAction == ParralleInstanceCurrentAction::Orphan)
|
||||
{
|
||||
// Orphan the instance, but don't decrease its refcount
|
||||
instanceManager.TEMPOrphan(instanceId);
|
||||
}
|
||||
else if (currentAction == ParralleInstanceCurrentAction::DeferredRemoval)
|
||||
{
|
||||
// Drop the refcount to zero so the instance will be released
|
||||
referenceTableMutex.lock();
|
||||
instances[index] = nullptr;
|
||||
referenceTableMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, add a new instance
|
||||
Instance<TestInstanceA> instance = instanceManager.FindOrCreate(instanceId, assets[index]);
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
|
||||
if (deferRemoval)
|
||||
{
|
||||
// Keep a reference to the instance alive so it can be removed later
|
||||
referenceTableMutex.lock();
|
||||
instances[index] = instance;
|
||||
referenceTableMutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
threadCount--;
|
||||
@@ -254,10 +355,12 @@ namespace UnitTest
|
||||
// Used to detect a deadlock. If we wait for more than 10 seconds, it's likely a deadlock has occurred
|
||||
while (threadCount > 0 && !timedOut)
|
||||
{
|
||||
size_t durationSecondsRoundedUp = static_cast<size_t>(std::ceil(durationSeconds));
|
||||
|
||||
AZStd::unique_lock<AZStd::mutex> lock(mutex);
|
||||
timedOut =
|
||||
(AZStd::cv_status::timeout ==
|
||||
cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSeconds * 2)));
|
||||
cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSecondsRoundedUp * 2)));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(threadCount == 0) << "One or more threads appear to be deadlocked at " << timer.GetDeltaTimeInSeconds() << " seconds";
|
||||
@@ -273,11 +376,11 @@ namespace UnitTest
|
||||
printf("Took %f seconds\n", timer.GetDeltaTimeInSeconds());
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreate)
|
||||
void ParallelCreateTest(ParallelInstanceTestCases testCase)
|
||||
{
|
||||
// This is the original test scenario from when InstanceDatabase was first implemented
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(8, 100, 5);
|
||||
ParallelInstanceCreateHelper(8, 100, 5, testCase);
|
||||
|
||||
// This value is checked in as 1 so this test doesn't take too much time, but can be increased locally to soak the test.
|
||||
const size_t attempts = 1;
|
||||
@@ -289,11 +392,11 @@ namespace UnitTest
|
||||
// The idea behind this series of tests is that there are two threads sharing one Instance, and both threads try to
|
||||
// create or release that instance at the same time.
|
||||
// At the time, this set of scenarios has something like a 10% failure rate.
|
||||
const size_t duration = 2;
|
||||
const float duration = 2.0f;
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(8, 1, duration);
|
||||
ParallelInstanceCreateHelper(2, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 1, duration, testCase);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < attempts; ++i)
|
||||
@@ -301,19 +404,39 @@ namespace UnitTest
|
||||
printf("Attempt %zu of %zu... \n", i, attempts);
|
||||
|
||||
// Here we try a bunch of different threadCount:assetCount ratios to be thorough
|
||||
const size_t duration = 2;
|
||||
const float duration = 2.0f;
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 2, duration);
|
||||
ParallelInstanceCreateHelper(4, 4, duration);
|
||||
ParallelInstanceCreateHelper(8, 1, duration);
|
||||
ParallelInstanceCreateHelper(8, 2, duration);
|
||||
ParallelInstanceCreateHelper(8, 3, duration);
|
||||
ParallelInstanceCreateHelper(8, 4, duration);
|
||||
ParallelInstanceCreateHelper(2, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 2, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 4, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 2, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 3, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 4, duration, testCase);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreate)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::Create);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreateAndDeferRemoval)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::CreateAndDeferRemoval);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreateAndOrphan)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::CreateAndOrphan);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreateDeferRemovalAndOrphan)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::CreateDeferRemovalAndOrphan);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, InstanceCreateNoDatabase)
|
||||
{
|
||||
bool m_deleted = false;
|
||||
|
||||
@@ -340,6 +340,14 @@ namespace AZ
|
||||
// (Load jobs will attempt to reuse blocked threads before spinning off new job threads)
|
||||
ProcessLoadJob();
|
||||
}
|
||||
|
||||
// Pump the AssetBus function queue once more after the load has completed in case additional
|
||||
// functions have been queued between the last call to DispatchEvents and the completion
|
||||
// of the current load job
|
||||
if (m_shouldDispatchEvents)
|
||||
{
|
||||
AssetManager::Instance().DispatchEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void Finish()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <AzCore/Slice/SliceAssetHandler.h>
|
||||
#include <AzCore/Slice/SliceComponent.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
namespace AZ {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h> // Used as the allocator for most components.
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -74,8 +74,6 @@
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
|
||||
AZ_CVAR(float, g_simulation_tick_rate, 0, nullptr, AZ::ConsoleFunctorFlags::Null, "The rate at which the game simulation tick loop runs, or 0 for as fast as possible");
|
||||
|
||||
static void PrintEntityName(const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
if (arguments.empty())
|
||||
@@ -1396,23 +1394,6 @@ namespace AZ
|
||||
AZ_PROFILE_SCOPE(AzCore, "ComponentApplication::Tick:OnTick");
|
||||
EBUS_EVENT(TickBus, OnTick, m_deltaTime, ScriptTimePoint(now));
|
||||
}
|
||||
|
||||
// If tick rate limiting is on, ensure (1 / g_simulation_tick_rate) ms has elapsed since the last frame,
|
||||
// sleeping if there's still time remaining.
|
||||
if (g_simulation_tick_rate > 0.f)
|
||||
{
|
||||
now = AZStd::chrono::system_clock::now();
|
||||
|
||||
// Work in microsecond durations here as that's the native measurement time for time_point
|
||||
constexpr float microsecondsPerSecond = 1000.f * 1000.f;
|
||||
const AZStd::chrono::microseconds timeBudgetPerTick(static_cast<int>(microsecondsPerSecond / g_simulation_tick_rate));
|
||||
AZStd::chrono::microseconds timeUntilNextTick = m_currentTime + timeBudgetPerTick - now;
|
||||
|
||||
if (timeUntilNextTick.count() > 0)
|
||||
{
|
||||
AZStd::this_thread::sleep_for(timeUntilNextTick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_ENTITY_UTILS_H
|
||||
#define AZCORE_ENTITY_UTILS_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
@@ -217,6 +216,3 @@ namespace AZ
|
||||
|
||||
} // namespace EntityUtils
|
||||
} // namespace AZ
|
||||
|
||||
#endif // AZCORE_ENTITY_UTILS_H
|
||||
#pragma once
|
||||
|
||||
@@ -46,8 +46,6 @@ namespace AZ
|
||||
|
||||
TICK_PRE_RENDER = 750, ///< Suggested tick handler position to update render-related data.
|
||||
|
||||
TICK_RENDER = 800, ///< Suggested tick handler position for rendering.
|
||||
|
||||
TICK_DEFAULT = 1000, ///< Default tick handler position when the handler is constructed.
|
||||
|
||||
TICK_UI = 2000, ///< Suggested tick handler position for UI components.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/EBus/Policies.h>
|
||||
|
||||
|
||||
@@ -19,14 +19,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/BusImpl.h>
|
||||
#include <AzCore/EBus/Environment.h>
|
||||
#include <AzCore/EBus/Results.h>
|
||||
#include <AzCore/EBus/Internal/Debug.h>
|
||||
|
||||
// Included for backwards compatibility purposes
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/typetraits/is_same.h>
|
||||
// End backwards compat
|
||||
|
||||
#include <AzCore/std/utils.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
@@ -90,14 +87,14 @@ namespace AZ
|
||||
* For available settings, see AZ::EBusHandlerPolicy.
|
||||
* By default, an EBus supports any number of handlers.
|
||||
*/
|
||||
static const EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple;
|
||||
static constexpr EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple;
|
||||
|
||||
/**
|
||||
* Defines how many addresses exist on the EBus.
|
||||
* For available settings, see AZ::EBusAddressPolicy.
|
||||
* By default, an EBus uses a single address.
|
||||
*/
|
||||
static const EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
|
||||
static constexpr EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
|
||||
|
||||
/**
|
||||
* The type of ID that is used to address the EBus.
|
||||
@@ -152,14 +149,14 @@ namespace AZ
|
||||
* `<BusName>::ExecuteQueuedEvents()`.
|
||||
* By default, the event queue is disabled.
|
||||
*/
|
||||
static const bool EnableEventQueue = false;
|
||||
static constexpr bool EnableEventQueue = false;
|
||||
|
||||
/**
|
||||
* Specifies whether the bus should accept queued messages by default or not.
|
||||
* If set to false, Bus::AllowFunctionQueuing(true) must be called before events are accepted.
|
||||
* Used only when #EnableEventQueue is true.
|
||||
*/
|
||||
static const bool EventQueueingActiveByDefault = true;
|
||||
static constexpr bool EventQueueingActiveByDefault = true;
|
||||
|
||||
/**
|
||||
* Specifies whether the EBus supports queueing functions which take reference
|
||||
@@ -168,7 +165,7 @@ namespace AZ
|
||||
* You should only use this if you know that the data being passed as arguments will
|
||||
* outlive the dispatch of the queued event.
|
||||
*/
|
||||
static const bool EnableQueuedReferences = false;
|
||||
static constexpr bool EnableQueuedReferences = false;
|
||||
|
||||
/**
|
||||
* Locking primitive that is used when adding and removing
|
||||
@@ -197,7 +194,7 @@ namespace AZ
|
||||
* to do.
|
||||
* By default, the standard policy is used, which locks around all dispatches
|
||||
*/
|
||||
static const bool LocklessDispatch = false;
|
||||
static constexpr bool LocklessDispatch = false;
|
||||
|
||||
/**
|
||||
* Specifies where EBus data is stored.
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/RTTI/TypeSafeIntegral.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
#include <AzCore/std/function/invoke.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
#include <AzCore/std/containers/intrusive_set.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/EBus/Environment.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -251,29 +250,21 @@ namespace AZ
|
||||
void Execute()
|
||||
{
|
||||
AZ_Warning("System", m_isActive, "You are calling execute queued functions on a bus which has not activated its function queuing! Call YourBus::AllowFunctionQueuing(true)!");
|
||||
while (true)
|
||||
|
||||
MessageQueueType localMessages;
|
||||
|
||||
// Swap the current list of queue functions with a local instance
|
||||
{
|
||||
BusMessageCall invoke;
|
||||
AZStd::scoped_lock lock(m_messagesMutex);
|
||||
AZStd::swap(localMessages, m_messages);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Pop element from the queue.
|
||||
{
|
||||
AZStd::lock_guard<MutexType> lock(m_messagesMutex);
|
||||
size_t numMessages = m_messages.size();
|
||||
if (numMessages == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
AZStd::swap(invoke, m_messages.front());
|
||||
m_messages.pop();
|
||||
if (numMessages == 1)
|
||||
{
|
||||
m_messages = {};
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
invoke();
|
||||
// Execute the queue functions safely now that are owned by the function
|
||||
while (!localMessages.empty())
|
||||
{
|
||||
const BusMessageCall& localMessage = localMessages.front();
|
||||
localMessage();
|
||||
localMessages.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Name/NameSerializer.h>
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/function/invoke.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Script/lua/lua.h>
|
||||
#include <AzCore/Script/ScriptProperty.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_SCRIPT_SCRIPTPROPERTY_H
|
||||
#define AZCORE_SCRIPT_SCRIPTPROPERTY_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
@@ -490,5 +489,4 @@ namespace AZ
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/DataPatch.h>
|
||||
#include <AzCore/Serialization/DataPatchBus.h>
|
||||
#include <AzCore/Serialization/DataPatchUpgradeManager.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "AzCore/RTTI/TypeInfo.h"
|
||||
#include <AzCore/Math/UuidSerializer.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/CastingHelpers.h>
|
||||
#include <AzCore/Serialization/Json/JsonDeserializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonStringConversionUtils.h>
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerializer.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/BasicContainerSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/MapSerializer.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/ObjectStream.h>
|
||||
#include <AzCore/Serialization/DataOverlayInstanceMsgs.h>
|
||||
#include <AzCore/Serialization/DataOverlayProviderMsgs.h>
|
||||
|
||||
@@ -37,7 +37,8 @@ namespace AZ
|
||||
class GenericStream;
|
||||
}
|
||||
|
||||
namespace ObjectStreamInternal {
|
||||
namespace ObjectStreamInternal
|
||||
{
|
||||
class ObjectStreamImpl;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/DataOverlay.h>
|
||||
#include <AzCore/Serialization/DynamicSerializableField.h>
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_SERIALIZE_CONTEXT_H
|
||||
#define AZCORE_SERIALIZE_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
|
||||
@@ -43,6 +42,12 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Data
|
||||
{
|
||||
template<typename T>
|
||||
class Asset;
|
||||
}
|
||||
|
||||
class EditContext;
|
||||
|
||||
class ObjectStream;
|
||||
@@ -2562,11 +2567,13 @@ namespace AZ
|
||||
#include <AzCore/Serialization/AZStdContainers.inl>
|
||||
#include <AzCore/Serialization/std/VariantReflection.inl>
|
||||
|
||||
/// include asset generics
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
// Forward declare asset serialization helper specialization
|
||||
namespace AZ
|
||||
{
|
||||
template<typename T>
|
||||
struct SerializeGenericTypeInfo< Data::Asset<T> >;
|
||||
}
|
||||
|
||||
/// include implementation of SerializeContext::EnumBuilder
|
||||
#include <AzCore/Serialization/SerializeContextEnum.inl>
|
||||
|
||||
#endif // AZCORE_SERIALIZE_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/EBus/BusImpl.h> //Just to get AZ::NullMutex
|
||||
#include <AzCore/std/chrono/types.h>
|
||||
#include <AzCore/Statistics/StatisticsManager.h>
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -243,7 +244,7 @@ namespace AZ
|
||||
|
||||
//! This one is needed because running statistics are collected many times across
|
||||
//! several frames. This value is used to calculate a per frame sample for @m_totalTimePerFrameStat,
|
||||
//! by subtracting @m_prevAccumulatedSums from the accumulated sum in @m_statisticsManager.
|
||||
//! by subtracting @m_prevAccumulatedSums from the accumulated sum in @m_statisticsManager.
|
||||
double m_prevAccumulatedSums;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <SerializeContextFixture.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
@@ -365,6 +366,42 @@ namespace UnitTest
|
||||
|
||||
};
|
||||
|
||||
static constexpr AZStd::chrono::seconds MaxDispatchTimeoutSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds * 12;
|
||||
|
||||
template <typename Pred>
|
||||
bool DispatchEventsUntilCondition(AZ::Data::AssetManager& assetManager, Pred&& conditionPredicate,
|
||||
AZStd::chrono::seconds logIntervalSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds,
|
||||
AZStd::chrono::seconds maxTimeoutSeconds = MaxDispatchTimeoutSeconds)
|
||||
{
|
||||
// If the Max Timeout is hit the test will be marked as a failure
|
||||
|
||||
AZStd::chrono::time_point dispatchEventTimeStart = AZStd::chrono::system_clock::now();
|
||||
AZStd::chrono::seconds dispatchEventNextLogTime = logIntervalSeconds;
|
||||
|
||||
while (!conditionPredicate())
|
||||
{
|
||||
AZStd::chrono::time_point currentTime = AZStd::chrono::system_clock::now();
|
||||
if (AZStd::chrono::seconds elapsedTime{ currentTime - dispatchEventTimeStart };
|
||||
elapsedTime >= dispatchEventNextLogTime)
|
||||
{
|
||||
const testing::TestInfo* test_info = ::testing::UnitTest::GetInstance()->current_test_info();
|
||||
AZ_Printf("AssetManagerLoadingTest", "The DispatchEventsUntiTimeout function has been waiting for %llu seconds"
|
||||
" in test %s.%s", elapsedTime.count(), test_info->test_case_name(), test_info->name());
|
||||
// Update the next log time to be the next multiple of DefaultTimeout Seconds
|
||||
// after current elapsed time
|
||||
dispatchEventNextLogTime = elapsedTime + logIntervalSeconds - ((elapsedTime + logIntervalSeconds) % logIntervalSeconds);
|
||||
if (elapsedTime >= maxTimeoutSeconds)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
assetManager.DispatchEvents();
|
||||
AZStd::this_thread::yield();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_ASSET_MANAGER_FLOOD_TEST
|
||||
TEST_F(AssetJobsFloodTest, DISABLED_FloodTest)
|
||||
#else
|
||||
@@ -1357,42 +1394,74 @@ namespace UnitTest
|
||||
m_assetHandlerAndCatalog->m_numCreations = 0;
|
||||
m_assetHandlerAndCatalog->m_numDestructions = 0;
|
||||
{
|
||||
ContainerReadyListener containerLoadingCompleteListener(NoLoadAssetId);
|
||||
OnAssetReadyListener readyListener(NoLoadAssetId, azrtti_typeid<AssetWithAssetReference>());
|
||||
OnAssetReadyListener depenencyListener(MyAsset2Id, azrtti_typeid<AssetWithAssetReference>());
|
||||
OnAssetReadyListener dependencyListener(MyAsset2Id, azrtti_typeid<AssetWithAssetReference>());
|
||||
|
||||
SCOPED_TRACE("LoadDependencies_BehaviorObeyed");
|
||||
|
||||
auto AssetOnlyReady = [&readyListener]() -> bool
|
||||
{
|
||||
return readyListener.m_ready;
|
||||
};
|
||||
auto AssetAndDependencyReady = [&readyListener, &dependencyListener]() -> bool
|
||||
{
|
||||
return readyListener.m_ready && dependencyListener.m_ready;
|
||||
};
|
||||
auto AssetContainerReady = [&containerLoadingCompleteListener]() -> bool
|
||||
{
|
||||
return containerLoadingCompleteListener.m_ready;
|
||||
};
|
||||
|
||||
auto noLoadRef = m_testAssetManager->GetAsset(NoLoadAssetId, azrtti_typeid<AssetWithAssetReference>(),
|
||||
AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
auto maxTimeout = AZStd::chrono::system_clock::now() + DefaultTimeoutSeconds;
|
||||
// Dispatch AssetBus events until the NoLoadAssetId has signaled an OnAssetReady
|
||||
// event or the timeout has been reached
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetOnlyReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
|
||||
// Dispatch AssetBus events until the asset container used to load
|
||||
// NoLoadAssetId has signaled an OnAssetContainerReady event
|
||||
// or the timeout has been reached
|
||||
// Wait until the current asset container has finished loading the NoLoadAssetId
|
||||
// before trigger another load
|
||||
// If the wait does not occur here, most likely what would occur is
|
||||
// the AssetManager::m_ownedAssetContainers object is still loading the NoLoadAssetId
|
||||
// using the default AssetLoadParameters
|
||||
// If a call to GetAsset occurs at this point while the Asset is still loading
|
||||
// it will ignore the new loadParams below and instead just re-use the existing
|
||||
// AssetContainerReader instance, resulting in the dependent MyAsset2Id not
|
||||
// being loaded
|
||||
// The function that can return an existing AssetContainer instance is the
|
||||
// AssetManager::GetAssetContainer. Since it can be in the middle of a load,
|
||||
// updating the AssetLoadParams would have an effect on the current in progress
|
||||
// load
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetContainerReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
|
||||
// Reset the ContainerLoadingComplete ready status back to 0
|
||||
containerLoadingCompleteListener.m_ready = 0;
|
||||
|
||||
while (!readyListener.m_ready)
|
||||
{
|
||||
m_testAssetManager->DispatchEvents();
|
||||
if (AZStd::chrono::system_clock::now() > maxTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
AZStd::this_thread::yield();
|
||||
}
|
||||
EXPECT_EQ(readyListener.m_ready, 1);
|
||||
EXPECT_EQ(depenencyListener.m_ready, 0);
|
||||
|
||||
AZ::Data::AssetLoadParameters loadParams(nullptr, AZ::Data::AssetDependencyLoadRules::LoadAll);
|
||||
loadParams.m_reloadMissingDependencies = true;
|
||||
auto loadDependencyRef = m_testAssetManager->GetAsset(NoLoadAssetId, azrtti_typeid<AssetWithAssetReference>(),
|
||||
AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
|
||||
while (!depenencyListener.m_ready || !readyListener.m_ready)
|
||||
{
|
||||
m_testAssetManager->DispatchEvents();
|
||||
if (AZStd::chrono::system_clock::now() > maxTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
AZStd::this_thread::yield();
|
||||
}
|
||||
// Dispatch AssetBus events until the NoLoadAssetId and the MyAsset2Id has signaled
|
||||
// an OnAssetReady event or the timeout has been reached
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetAndDependencyReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
|
||||
EXPECT_EQ(readyListener.m_ready, 1);
|
||||
EXPECT_EQ(depenencyListener.m_ready, 1);
|
||||
EXPECT_EQ(dependencyListener.m_ready, 1);
|
||||
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetContainerReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
}
|
||||
|
||||
CheckFinishedCreationsAndDestructions();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <Tests/Asset/BaseAssetManagerTest.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/Asset/AssetJsonSerializer.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/Jobs/JobManagerComponent.h>
|
||||
#include <AzCore/Jobs/JobManager.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "FileIOBaseTestTypes.h"
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_base.h>
|
||||
#include <AzFramework/Archive/Codec.h>
|
||||
#include <AzFramework/Archive/ZipDirStructures.h>
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Asset/AssetSeedList.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Asset/Benchmark/BenchmarkAsset.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Asset/SimpleAsset.h>
|
||||
|
||||
namespace AzFramework
|
||||
@@ -36,4 +37,36 @@ namespace AzFramework
|
||||
|
||||
return "";
|
||||
}
|
||||
void SimpleAssetReferenceBase::Reflect(AZ::ReflectContext *context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SimpleAssetReferenceBase>()
|
||||
->Version(1)
|
||||
->Field("AssetPath", &SimpleAssetReferenceBase::m_assetPath);
|
||||
|
||||
AZ::EditContext* edit = serializeContext->GetEditContext();
|
||||
if (edit)
|
||||
{
|
||||
edit->Class<SimpleAssetReferenceBase>("Asset path", "Asset reference as a project-relative path")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SimpleAssetReferenceBase>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Asset")
|
||||
->Attribute(AZ::Script::Attributes::Module, "asset")
|
||||
->Property("assetPath", &SimpleAssetReferenceBase::GetAssetPath, nullptr)
|
||||
->Property("assetType", &SimpleAssetReferenceBase::GetAssetType, nullptr)
|
||||
->Property("fileFilter", &SimpleAssetReferenceBase::GetFileFilter, nullptr)
|
||||
->Method("SetAssetPath", &SimpleAssetReferenceBase::SetAssetPath)
|
||||
->Attribute(AZ::Script::Attributes::Alias, "set_asset_path")
|
||||
;
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
@@ -74,38 +73,7 @@ namespace AzFramework
|
||||
virtual AZ::Data::AssetType GetAssetType() const = 0;
|
||||
virtual const char* GetFileFilter() const = 0;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SimpleAssetReferenceBase>()
|
||||
->Version(1)
|
||||
->Field("AssetPath", &SimpleAssetReferenceBase::m_assetPath);
|
||||
|
||||
AZ::EditContext* edit = serializeContext->GetEditContext();
|
||||
if (edit)
|
||||
{
|
||||
edit->Class<SimpleAssetReferenceBase>("Asset path", "Asset reference as a project-relative path")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SimpleAssetReferenceBase>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Asset")
|
||||
->Attribute(AZ::Script::Attributes::Module, "asset")
|
||||
->Property("assetPath", &SimpleAssetReferenceBase::GetAssetPath, nullptr)
|
||||
->Property("assetType", &SimpleAssetReferenceBase::GetAssetType, nullptr)
|
||||
->Property("fileFilter", &SimpleAssetReferenceBase::GetFileFilter, nullptr)
|
||||
->Method("SetAssetPath", &SimpleAssetReferenceBase::SetAssetPath)
|
||||
->Attribute(AZ::Script::Attributes::Alias, "set_asset_path")
|
||||
;
|
||||
}
|
||||
}
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class Entity;
|
||||
}
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
using EntityContextId = AZ::Uuid;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzFramework/Logging/MissingAssetNotificationBus.h>
|
||||
|
||||
namespace AzFramework { class LogFile; }
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzFramework/Physics/Ragdoll.h>
|
||||
#include <AzFramework/Physics/Shape.h>
|
||||
#include <AzFramework/Physics/SystemBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzFramework/Physics/Collision/CollisionEvents.h>
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <AzFramework/Physics/Collision/CollisionGroups.h>
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzFramework/Physics/CollisionBus.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzFramework/Physics/Configuration/SystemConfiguration.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Configuration/SceneConfiguration.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
|
||||
namespace AzPhysics
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzPhysics
|
||||
{
|
||||
void SystemInterface::Reflect(AZ::ReflectContext* context)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Physics/Material.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionGroups.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionLayers.h>
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/PropertyTypes.h>
|
||||
#include <AzFramework/Physics/SystemBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace Physics
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
#include "Utils.h"
|
||||
#include "Material.h"
|
||||
#include "Shape.h"
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/AnimationConfiguration.h>
|
||||
#include <AzFramework/Physics/CharacterBus.h>
|
||||
#include <AzFramework/Physics/Character.h>
|
||||
#include <AzFramework/Physics/Ragdoll.h>
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/CollisionBus.h>
|
||||
#include <AzFramework/Physics/Components/SimulatedBodyComponentBus.h>
|
||||
#include <AzFramework/Physics/WindBus.h>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Component/ComponentBus.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
//! Common structures for Render geometry queries
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Spawnable/SpawnableMetaData.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/StreamingInstall/StreamingInstallNotifications.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include "StreamingInstall.h"
|
||||
|
||||
namespace AzFramework
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
NAMESPACE AZ
|
||||
FILES_CMAKE
|
||||
Tests/frameworktests_files.cmake
|
||||
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Tests
|
||||
@@ -93,6 +94,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
|
||||
NAME AZ::AzFramework.Tests
|
||||
)
|
||||
|
||||
include(${pal_dir}/platform_specific_test_targets.cmake)
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzFramework/XcbApplication.h>
|
||||
#include <AzFramework/XcbEventHandler.h>
|
||||
#include <AzFramework/XcbInterface.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
@@ -17,8 +18,8 @@ namespace AzFramework
|
||||
{
|
||||
public:
|
||||
XcbConnectionManagerImpl()
|
||||
: m_xcbConnection(xcb_connect(nullptr, nullptr))
|
||||
{
|
||||
m_xcbConnection = xcb_connect(nullptr, nullptr);
|
||||
AZ_Error("Application", m_xcbConnection != nullptr, "Unable to connect to X11 Server.");
|
||||
XcbConnectionManagerBus::Handler::BusConnect();
|
||||
}
|
||||
@@ -26,16 +27,15 @@ namespace AzFramework
|
||||
~XcbConnectionManagerImpl() override
|
||||
{
|
||||
XcbConnectionManagerBus::Handler::BusDisconnect();
|
||||
xcb_disconnect(m_xcbConnection);
|
||||
}
|
||||
|
||||
xcb_connection_t* GetXcbConnection() const override
|
||||
{
|
||||
return m_xcbConnection;
|
||||
return m_xcbConnection.get();
|
||||
}
|
||||
|
||||
private:
|
||||
xcb_connection_t* m_xcbConnection = nullptr;
|
||||
XcbUniquePtr<xcb_connection_t, xcb_disconnect> m_xcbConnection = nullptr;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -65,10 +65,9 @@ namespace AzFramework
|
||||
{
|
||||
if (xcb_connection_t* xcbConnection = m_xcbConnectionManager->GetXcbConnection())
|
||||
{
|
||||
if (xcb_generic_event_t* event = xcb_poll_for_event(xcbConnection))
|
||||
if (auto event = XcbStdFreePtr<xcb_generic_event_t>{xcb_poll_for_event(xcbConnection)})
|
||||
{
|
||||
XcbEventHandlerBus::Broadcast(&XcbEventHandlerBus::Events::HandleXcbEvent, event);
|
||||
free(event);
|
||||
XcbEventHandlerBus::Broadcast(&XcbEventHandlerBus::Events::HandleXcbEvent, event.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,10 +77,9 @@ namespace AzFramework
|
||||
{
|
||||
if (xcb_connection_t* xcbConnection = m_xcbConnectionManager->GetXcbConnection())
|
||||
{
|
||||
while (xcb_generic_event_t* event = xcb_poll_for_event(xcbConnection))
|
||||
while (auto event = XcbStdFreePtr<xcb_generic_event_t>{xcb_poll_for_event(xcbConnection)})
|
||||
{
|
||||
XcbEventHandlerBus::Broadcast(&XcbEventHandlerBus::Events::HandleXcbEvent, event);
|
||||
free(event);
|
||||
XcbEventHandlerBus::Broadcast(&XcbEventHandlerBus::Events::HandleXcbEvent, event.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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 <AzTest/AzTest.h>
|
||||
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
ACTION_TEMPLATE(ReturnMalloc,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
AND_1_VALUE_PARAMS(p0)) {
|
||||
T* value = static_cast<T*>(malloc(sizeof(T)));
|
||||
*value = T{ p0 };
|
||||
return value;
|
||||
}
|
||||
ACTION_TEMPLATE(ReturnMalloc,
|
||||
HAS_1_TEMPLATE_PARAMS(typename, T),
|
||||
AND_2_VALUE_PARAMS(p0, p1)) {
|
||||
T* value = static_cast<T*>(malloc(sizeof(T)));
|
||||
*value = T{ p0, p1 };
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
* 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 <AzTest/AzTest.h>
|
||||
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 "MockXcbInterface.h"
|
||||
|
||||
// The functions defined in this file will take precedence over those defined
|
||||
// in the real libxcb.so, allowing the test code to use a mock implementation
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// xcb
|
||||
xcb_connection_t* xcb_connect(const char* displayname, int* screenp)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xcb_connect(displayname, screenp);
|
||||
}
|
||||
void xcb_disconnect(xcb_connection_t* c)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xcb_disconnect(c);
|
||||
}
|
||||
xcb_generic_event_t* xcb_poll_for_event(xcb_connection_t* c)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xcb_poll_for_event(c);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// xcb-xkb
|
||||
xcb_xkb_use_extension_cookie_t xcb_xkb_use_extension(xcb_connection_t* c, uint16_t wantedMajor, uint16_t wantedMinor)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xcb_xkb_use_extension(c, wantedMajor, wantedMinor);
|
||||
}
|
||||
xcb_xkb_use_extension_reply_t* xcb_xkb_use_extension_reply(xcb_connection_t* c, xcb_xkb_use_extension_cookie_t cookie, xcb_generic_error_t** e)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xcb_xkb_use_extension_reply(c, cookie, e);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// xkb-x11
|
||||
int32_t xkb_x11_get_core_keyboard_device_id(xcb_connection_t* connection)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_x11_get_core_keyboard_device_id(connection);
|
||||
}
|
||||
struct xkb_keymap* xkb_x11_keymap_new_from_device(struct xkb_context* context, xcb_connection_t* connection, int32_t device_id, enum xkb_keymap_compile_flags flags)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_x11_keymap_new_from_device(context, connection, device_id, flags);
|
||||
}
|
||||
xkb_state* xkb_x11_state_new_from_device(xkb_keymap* keymap, xcb_connection_t* connection, int32_t device_id)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_x11_state_new_from_device(keymap, connection, device_id);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// xkbcommon
|
||||
xkb_context* xkb_context_new(enum xkb_context_flags flags)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_context_new(flags);
|
||||
}
|
||||
void xkb_context_unref(xkb_context *context)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_context_unref(context);
|
||||
}
|
||||
void xkb_keymap_unref(xkb_keymap *keymap)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_keymap_unref(keymap);
|
||||
}
|
||||
void xkb_state_unref(xkb_state *state)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_state_unref(state);
|
||||
}
|
||||
xkb_keysym_t xkb_state_key_get_one_sym(xkb_state *state, xkb_keycode_t key)
|
||||
{
|
||||
return MockXcbInterface::Instance()->xkb_state_key_get_one_sym(state, key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#define explicit ExplicitIsACXXKeyword
|
||||
#include <xcb/xkb.h>
|
||||
#undef explicit
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include "Printers.h"
|
||||
|
||||
// xcb / xkb do not provide definitions of these structs, but the tests need some concrete value for them.
|
||||
struct xcb_connection_t
|
||||
{
|
||||
};
|
||||
|
||||
struct xkb_context
|
||||
{
|
||||
};
|
||||
|
||||
struct xkb_keymap
|
||||
{
|
||||
};
|
||||
|
||||
struct xkb_state
|
||||
{
|
||||
};
|
||||
|
||||
class MockXcbInterface
|
||||
{
|
||||
public:
|
||||
MockXcbInterface()
|
||||
{
|
||||
self = this;
|
||||
}
|
||||
MockXcbInterface(const MockXcbInterface&) = delete;
|
||||
MockXcbInterface(MockXcbInterface&&) = delete;
|
||||
MockXcbInterface& operator=(const MockXcbInterface&) = delete;
|
||||
MockXcbInterface& operator=(MockXcbInterface&&) = delete;
|
||||
~MockXcbInterface()
|
||||
{
|
||||
self = nullptr;
|
||||
}
|
||||
|
||||
static MockXcbInterface* Instance() { return self; }
|
||||
|
||||
// xcb
|
||||
MOCK_CONST_METHOD2(xcb_connect, xcb_connection_t*(const char* displayname, int* screenp));
|
||||
MOCK_CONST_METHOD1(xcb_disconnect, void(xcb_connection_t* c));
|
||||
MOCK_CONST_METHOD1(xcb_poll_for_event, xcb_generic_event_t*(xcb_connection_t* c));
|
||||
|
||||
// xcb-xkb
|
||||
MOCK_CONST_METHOD3(xcb_xkb_use_extension, xcb_xkb_use_extension_cookie_t(xcb_connection_t* c, uint16_t wantedMajor, uint16_t wantedMinor));
|
||||
MOCK_CONST_METHOD3(xcb_xkb_use_extension_reply, xcb_xkb_use_extension_reply_t*(xcb_connection_t* c, xcb_xkb_use_extension_cookie_t cookie, xcb_generic_error_t** e));
|
||||
|
||||
// xkb-x11
|
||||
MOCK_CONST_METHOD1(xkb_x11_get_core_keyboard_device_id, int32_t(xcb_connection_t* connection));
|
||||
MOCK_CONST_METHOD4(xkb_x11_keymap_new_from_device, xkb_keymap*(xkb_context* context, xcb_connection_t* connection, int32_t device_id, xkb_keymap_compile_flags flags));
|
||||
MOCK_CONST_METHOD3(xkb_x11_state_new_from_device, xkb_state*(xkb_keymap* keymap, xcb_connection_t* connection, int32_t device_id));
|
||||
|
||||
// xkbcommon
|
||||
MOCK_CONST_METHOD1(xkb_context_new, xkb_context*(xkb_context_flags flags));
|
||||
MOCK_CONST_METHOD1(xkb_context_unref, void(xkb_context* context));
|
||||
MOCK_CONST_METHOD1(xkb_keymap_unref, void(xkb_keymap* keymap));
|
||||
MOCK_CONST_METHOD1(xkb_state_unref, void(xkb_state* state));
|
||||
MOCK_CONST_METHOD2(xkb_state_key_get_one_sym, xkb_keysym_t(xkb_state *state, xkb_keycode_t key));
|
||||
|
||||
private:
|
||||
static inline MockXcbInterface* self = nullptr;
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 "Printers.h"
|
||||
#include <ostream>
|
||||
#include <AzFramework/Input/Channels/InputChannel.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void PrintTo(const InputChannel::State& state, std::ostream* os)
|
||||
{
|
||||
switch(state)
|
||||
{
|
||||
case InputChannel::State::Began:
|
||||
*os << "Began";
|
||||
break;
|
||||
case InputChannel::State::Ended:
|
||||
*os << "Ended";
|
||||
break;
|
||||
case InputChannel::State::Idle:
|
||||
*os << "Idle";
|
||||
break;
|
||||
case InputChannel::State::Updated:
|
||||
*os << "Updated";
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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 <iosfwd>
|
||||
#include <AzFramework/Input/Channels/InputChannel.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
void PrintTo(const InputChannel::State& state, std::ostream* os);
|
||||
} // namespace AzFramework
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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 <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include <AzFramework/XcbApplication.h>
|
||||
#include <AzFramework/XcbInputDeviceKeyboard.h>
|
||||
#include "MockXcbInterface.h"
|
||||
#include "Actions.h"
|
||||
|
||||
template<typename T>
|
||||
xcb_generic_event_t MakeEvent(T event)
|
||||
{
|
||||
return *reinterpret_cast<xcb_generic_event_t*>(&event);
|
||||
}
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
TEST(XcbInputDeviceKeyboard, InputChannelsUpdateStateFromXcbEvents)
|
||||
{
|
||||
using testing::Return;
|
||||
using testing::Eq;
|
||||
using testing::_;
|
||||
MockXcbInterface interface;
|
||||
|
||||
xcb_connection_t connection{};
|
||||
xkb_context xkbContext{};
|
||||
xkb_keymap xkbKeymap{};
|
||||
xkb_state xkbState{};
|
||||
const int32_t coreDeviceId{1};
|
||||
|
||||
constexpr xcb_keycode_t keycodeForAKey = 38;
|
||||
|
||||
const AZStd::array events
|
||||
{
|
||||
MakeEvent(xcb_key_press_event_t{
|
||||
/*.response_type = */ XCB_KEY_PRESS,
|
||||
/*.detail = */ keycodeForAKey,
|
||||
/*.sequence = */ 0,
|
||||
/*.time = */ 0,
|
||||
/*.root = */ 0,
|
||||
/*.event = */ 0,
|
||||
/*.child = */ 0,
|
||||
/*.root_x = */ 0,
|
||||
/*.root_y = */ 0,
|
||||
/*.event_x = */ 0,
|
||||
/*.event_y = */ 0,
|
||||
/*.state = */ 0,
|
||||
/*.same_screen = */ 0,
|
||||
/*.pad0 = */ 0
|
||||
}),
|
||||
MakeEvent(xcb_key_release_event_t{
|
||||
/*.response_type = */ XCB_KEY_RELEASE,
|
||||
/*.detail = */ keycodeForAKey,
|
||||
/*.sequence = */ 0,
|
||||
/*.time = */ 0,
|
||||
/*.root = */ 0,
|
||||
/*.event = */ 0,
|
||||
/*.child = */ 0,
|
||||
/*.root_x = */ 0,
|
||||
/*.root_y = */ 0,
|
||||
/*.event_x = */ 0,
|
||||
/*.event_y = */ 0,
|
||||
/*.state = */ 0,
|
||||
/*.same_screen = */ 0,
|
||||
/*.pad0 = */ 0
|
||||
}),
|
||||
};
|
||||
|
||||
EXPECT_CALL(interface, xcb_connect(_, _))
|
||||
.WillOnce(Return(&connection));
|
||||
EXPECT_CALL(interface, xcb_disconnect(&connection))
|
||||
.Times(1);
|
||||
|
||||
EXPECT_CALL(interface, xkb_context_new(XKB_CONTEXT_NO_FLAGS))
|
||||
.WillOnce(Return(&xkbContext));
|
||||
EXPECT_CALL(interface, xkb_context_unref(&xkbContext))
|
||||
.Times(1);
|
||||
|
||||
EXPECT_CALL(interface, xkb_x11_keymap_new_from_device(&xkbContext, &connection, coreDeviceId, XKB_KEYMAP_COMPILE_NO_FLAGS))
|
||||
.WillOnce(Return(&xkbKeymap));
|
||||
EXPECT_CALL(interface, xkb_keymap_unref(&xkbKeymap))
|
||||
.Times(1);
|
||||
|
||||
EXPECT_CALL(interface, xkb_x11_state_new_from_device(&xkbKeymap, &connection, coreDeviceId))
|
||||
.WillOnce(Return(&xkbState));
|
||||
EXPECT_CALL(interface, xkb_state_unref(&xkbState))
|
||||
.Times(1);
|
||||
|
||||
EXPECT_CALL(interface, xcb_xkb_use_extension(&connection, 1, 0));
|
||||
EXPECT_CALL(interface, xcb_xkb_use_extension_reply(&connection, _, _))
|
||||
.WillOnce(ReturnMalloc<xcb_xkb_use_extension_reply_t>(
|
||||
/* .response_type =*/static_cast<uint8_t>(XCB_XKB_USE_EXTENSION),
|
||||
/* .supported =*/ static_cast<uint8_t>(1))
|
||||
);
|
||||
EXPECT_CALL(interface, xkb_x11_get_core_keyboard_device_id(&connection))
|
||||
.WillRepeatedly(Return(coreDeviceId));
|
||||
|
||||
// Set the expectations for the events that will be generated
|
||||
// nullptr entries represent when the event queue is empty, and will cause
|
||||
// PumpSystemEventLoopUntilEmpty to return
|
||||
// event pointers are freed by the calling code, so we malloc new copies
|
||||
// here
|
||||
EXPECT_CALL(interface, xcb_poll_for_event(&connection))
|
||||
.WillOnce(ReturnMalloc<xcb_generic_event_t>(events[0]))
|
||||
.WillOnce(Return(nullptr))
|
||||
.WillOnce(ReturnMalloc<xcb_generic_event_t>(events[1]))
|
||||
.WillOnce(Return(nullptr))
|
||||
;
|
||||
|
||||
EXPECT_CALL(interface, xkb_state_key_get_one_sym(&xkbState, keycodeForAKey))
|
||||
.WillOnce(Return(XKB_KEY_a))
|
||||
.WillOnce(Return(XKB_KEY_a))
|
||||
;
|
||||
|
||||
Application application;
|
||||
application.Start({}, {});
|
||||
|
||||
const InputChannel* inputChannel = InputChannelRequests::FindInputChannel(InputDeviceKeyboard::Key::AlphanumericA);
|
||||
ASSERT_TRUE(inputChannel);
|
||||
EXPECT_THAT(inputChannel->GetState(), Eq(InputChannel::State::Idle));
|
||||
|
||||
application.PumpSystemEventLoopUntilEmpty();
|
||||
application.TickSystem();
|
||||
application.Tick();
|
||||
|
||||
EXPECT_THAT(inputChannel->GetState(), Eq(InputChannel::State::Began));
|
||||
|
||||
application.PumpSystemEventLoopUntilEmpty();
|
||||
application.TickSystem();
|
||||
application.Tick();
|
||||
|
||||
EXPECT_THAT(inputChannel->GetState(), Eq(InputChannel::State::Ended));
|
||||
|
||||
application.Stop();
|
||||
}
|
||||
} // namespace AzFramework
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Actions.h
|
||||
Main.cpp
|
||||
MockXcbInterface.cpp
|
||||
MockXcbInterface.h
|
||||
Printers.cpp
|
||||
Printers.h
|
||||
XcbInputDeviceKeyboardTests.cpp
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
|
||||
if (${PAL_TRAIT_LINUX_WINDOW_MANAGER} STREQUAL "xcb")
|
||||
# This library defines local implementations of all the used xcb functions,
|
||||
# in order to allow tests to run in the absence of a running X server.
|
||||
# These have to be in a separate library, so that the normal AzFramework
|
||||
# tests do not need to set up a mock Xcb interface.
|
||||
ly_add_target(
|
||||
NAME AzFramework.Xcb.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
|
||||
NAMESPACE AZ
|
||||
FILES_CMAKE
|
||||
Tests/Platform/Common/Xcb/azframework_xcb_tests_files.cmake
|
||||
INCLUDE_DIRECTORIES
|
||||
PRIVATE
|
||||
Tests
|
||||
${pal_dir}
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzFramework
|
||||
AZ::AzTest
|
||||
AZ::AzTestShared
|
||||
AZ::AzFrameworkTestShared
|
||||
)
|
||||
ly_add_googletest(
|
||||
NAME AZ::AzFramework.Xcb.Tests
|
||||
)
|
||||
endif()
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
@@ -7,7 +7,7 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
../../AzCore/Tests/Main.cpp
|
||||
Main.cpp
|
||||
Spawnable/SpawnableEntitiesInterfaceTests.cpp
|
||||
Spawnable/SpawnableEntitiesManagerTests.cpp
|
||||
ArchiveCompressionTests.cpp
|
||||
|
||||
@@ -32,17 +32,14 @@ namespace AzGameFramework
|
||||
// at the Assets alias, otherwise to attempting to mount the engine pak
|
||||
// from the Cache folder
|
||||
AZ::IO::FixedMaxPath enginePakPath = AZ::Utils::GetExecutableDirectory();
|
||||
enginePakPath /= "Engine.pak";
|
||||
if (m_archiveFileIO->Exists(enginePakPath.c_str()))
|
||||
enginePakPath /= "engine.pak";
|
||||
if (!m_archive->OpenPack("@assets@", enginePakPath.Native()))
|
||||
{
|
||||
m_archive->OpenPack("@assets@", enginePakPath.Native());
|
||||
}
|
||||
else if (enginePakPath.clear(); m_settingsRegistry->Get(enginePakPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
|
||||
{
|
||||
// fall back to checking if there is an Engine.pak in the Asset Cache
|
||||
enginePakPath /= "Engine.pak";
|
||||
if (m_archiveFileIO->Exists(enginePakPath.c_str()))
|
||||
enginePakPath.clear();
|
||||
if (m_settingsRegistry->Get(enginePakPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
|
||||
{
|
||||
// fall back to checking Project Cache Root.
|
||||
enginePakPath /= "engine.pak";
|
||||
m_archive->OpenPack("@assets@", enginePakPath.Native());
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user