diff --git a/Code/Editor/EditorViewportWidget.cpp b/Code/Editor/EditorViewportWidget.cpp
index 96a7e77ecd..28e8cce33e 100644
--- a/Code/Editor/EditorViewportWidget.cpp
+++ b/Code/Editor/EditorViewportWidget.cpp
@@ -630,7 +630,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
if (m_renderViewport)
{
- m_renderViewport->GetControllerList()->SetEnabled(true);
+ m_renderViewport->SetInputProcessingEnabled(true);
}
break;
@@ -2697,8 +2697,7 @@ void EditorViewportWidget::RestoreViewportAfterGameMode()
QString(
tr("When leaving \" Game Mode \" the engine will automatically restore your camera position to the default position before you "
"had entered Game mode.If you dislike this setting you can always change this anytime in the global "
- "preferences. "))
- .arg(EditorPreferencesGeneralRestoreViewportCameraSettingName);
+ "preferences. "));
QString restoreOnExitGameModePopupDisabledRegKey("Editor/AutoHide/ViewportCameraRestoreOnExitGameMode");
// Read the popup disabled registry value
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
index 2ed2a30f08..66c57361be 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
@@ -1452,7 +1452,7 @@ void SandboxIntegrationManager::ContextMenu_NewEntity()
if (view)
{
const QPoint viewPoint(m_contextMenuViewPoint.GetX(), m_contextMenuViewPoint.GetY());
- worldPosition = LYVec3ToAZVec3(view->SnapToGrid(view->ViewToWorld(viewPoint)));
+ worldPosition = view->GetHitLocation(viewPoint);
}
CreateNewEntityAtPosition(worldPosition);
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.cpp b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.cpp
index 017f59cdc3..158e45d6e2 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.cpp
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.cpp
@@ -20,7 +20,7 @@
#include
OutlinerTreeView::OutlinerTreeView(QWidget* pParent)
- : QTreeView(pParent)
+ : AzQtComponents::StyledTreeView(pParent)
, m_queuedMouseEvent(nullptr)
, m_draggingUnselectedItem(false)
{
@@ -135,16 +135,12 @@ void OutlinerTreeView::startDrag(Qt::DropActions supportedActions)
if (!selectionModel()->isSelected(index))
{
- startCustomDrag({ index }, supportedActions);
+ StartCustomDrag({ index }, supportedActions);
return;
}
}
- if (!selectionModel()->selectedIndexes().empty())
- {
- startCustomDrag(selectionModel()->selectedIndexes(), supportedActions);
- return;
- }
+ StyledTreeView::startDrag(supportedActions);
}
void OutlinerTreeView::dragMoveEvent(QDragMoveEvent* event)
@@ -336,14 +332,14 @@ void OutlinerTreeView::processQueuedMousePressedEvent(QMouseEvent* event)
QTreeView::mousePressEvent(&mousePressedEvent);
}
-void OutlinerTreeView::startCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions)
+void OutlinerTreeView::StartCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions)
{
m_draggingUnselectedItem = true;
//sort by container entity depth and order in hierarchy for proper drag image and drop order
QModelIndexList indexListSorted = indexList;
AZStd::unordered_map> locations;
- for (auto index : indexListSorted)
+ for (const auto& index : indexListSorted)
{
AZ::EntityId entityId(index.data(OutlinerListModel::EntityIdRole).value());
AzToolsFramework::GetEntityLocationInHierarchy(entityId, locations[entityId]);
@@ -356,74 +352,7 @@ void OutlinerTreeView::startCustomDrag(const QModelIndexList& indexList, Qt::Dro
return AZStd::lexicographical_compare(locationsE1.begin(), locationsE1.end(), locationsE2.begin(), locationsE2.end());
});
- //get the data for the unselected item(s)
- QMimeData* mimeData = model()->mimeData(indexListSorted);
- if (mimeData)
- {
- //initiate drag/drop for the item
- QDrag* drag = new QDrag(this);
- drag->setPixmap(QPixmap::fromImage(createDragImage(indexListSorted)));
- drag->setMimeData(mimeData);
- Qt::DropAction defDropAction = Qt::IgnoreAction;
- if (defaultDropAction() != Qt::IgnoreAction && (supportedActions & defaultDropAction()))
- {
- defDropAction = defaultDropAction();
- }
- else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
- {
- defDropAction = Qt::CopyAction;
- }
- drag->exec(supportedActions, defDropAction);
- }
-}
-
-QImage OutlinerTreeView::createDragImage(const QModelIndexList& indexList)
-{
- //generate a drag image of the item icon and text, normally done internally, and inaccessible
- QRect rect(0, 0, 0, 0);
- for (auto index : indexList)
- {
- if (index.column() != 0)
- {
- continue;
- }
- QRect itemRect = visualRect(index);
- rect.setHeight(rect.height() + itemRect.height());
- rect.setWidth(AZStd::GetMax(rect.width(), itemRect.width()));
- }
-
- QImage dragImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
-
- QPainter dragPainter(&dragImage);
- dragPainter.setCompositionMode(QPainter::CompositionMode_Source);
- dragPainter.fillRect(dragImage.rect(), Qt::transparent);
- dragPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
- dragPainter.setOpacity(0.35f);
- dragPainter.fillRect(rect, QColor("#222222"));
- dragPainter.setOpacity(1.0f);
-
- int imageY = 0;
- for (auto index : indexList)
- {
- if (index.column() != 0)
- {
- continue;
- }
-
- QRect itemRect = visualRect(index);
- dragPainter.drawPixmap(QPoint(0, imageY),
- model()->data(index, Qt::DecorationRole).value().pixmap(QSize(16, 16)));
- dragPainter.setPen(
- model()->data(index, Qt::ForegroundRole).value().color());
- dragPainter.setFont(
- font());
- dragPainter.drawText(QRect(20, imageY, rect.width() - 20, rect.height()),
- model()->data(index, Qt::DisplayRole).value());
- imageY += itemRect.height();
- }
-
- dragPainter.end();
- return dragImage;
+ StyledTreeView::StartCustomDrag(indexListSorted, supportedActions);
}
#include
diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.hxx b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.hxx
index fe7a494be4..b597b70092 100644
--- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.hxx
+++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/OutlinerTreeView.hxx
@@ -15,7 +15,8 @@
#include
#include
-#include
+
+#include
#endif
#pragma once
@@ -31,7 +32,7 @@ class OutlinerTreeViewModel;
//! allow for dragging and dropping of entities from the outliner into the property editor
//! of other entities. If the selection updates instantly, this would never be possible.
class OutlinerTreeView
- : public QTreeView
+ : public AzQtComponents::StyledTreeView
{
Q_OBJECT;
public:
@@ -66,9 +67,7 @@ private:
void processQueuedMousePressedEvent(QMouseEvent* event);
- void startCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions);
-
- QImage createDragImage(const QModelIndexList& indexList);
+ void StartCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions) override;
void DrawLayerUI(QPainter* painter, const QRect& rect, const QModelIndex& index) const;
diff --git a/Code/Editor/Viewport.cpp b/Code/Editor/Viewport.cpp
index 2bc1b21216..873f555c80 100644
--- a/Code/Editor/Viewport.cpp
+++ b/Code/Editor/Viewport.cpp
@@ -46,24 +46,7 @@ void QtViewport::BuildDragDropContext(AzQtComponents::ViewportDragContext& conte
PreWidgetRendering(); // required so that the current render cam is set.
- Vec3 pos = Vec3(ZERO);
- HitContext hit;
- if (HitTest(pt, hit))
- {
- pos = hit.raySrc + hit.rayDir * hit.dist;
- pos = SnapToGrid(pos);
- }
- else
- {
- bool hitTerrain;
- pos = ViewToWorld(pt, &hitTerrain);
- if (hitTerrain)
- {
- pos.z = GetIEditor()->GetTerrainElevation(pos.x, pos.y);
- }
- pos = SnapToGrid(pos);
- }
- context.m_hitLocation = AZ::Vector3(pos.x, pos.y, pos.z);
+ context.m_hitLocation = GetHitLocation(pt);
PostWidgetRendering();
}
@@ -1154,6 +1137,29 @@ bool QtViewport::HitTest(const QPoint& point, HitContext& hitInfo)
return false;
}
+AZ::Vector3 QtViewport::GetHitLocation(const QPoint& point)
+{
+ Vec3 pos = Vec3(ZERO);
+ HitContext hit;
+ if (HitTest(point, hit))
+ {
+ pos = hit.raySrc + hit.rayDir * hit.dist;
+ pos = SnapToGrid(pos);
+ }
+ else
+ {
+ bool hitTerrain;
+ pos = ViewToWorld(point, &hitTerrain);
+ if (hitTerrain)
+ {
+ pos.z = GetIEditor()->GetTerrainElevation(pos.x, pos.y);
+ }
+ pos = SnapToGrid(pos);
+ }
+
+ return AZ::Vector3(pos.x, pos.y, pos.z);
+}
+
//////////////////////////////////////////////////////////////////////////
void QtViewport::SetZoomFactor(float fZoomFactor)
{
diff --git a/Code/Editor/Viewport.h b/Code/Editor/Viewport.h
index 823b8c77b1..6b5bfb5c34 100644
--- a/Code/Editor/Viewport.h
+++ b/Code/Editor/Viewport.h
@@ -201,6 +201,7 @@ public:
//! Performs hit testing of 2d point in view to find which object hit.
virtual bool HitTest(const QPoint& point, HitContext& hitInfo) = 0;
+ virtual AZ::Vector3 GetHitLocation(const QPoint& point) = 0;
virtual void MakeConstructionPlane(int axis) = 0;
@@ -436,6 +437,7 @@ public:
//! Performs hit testing of 2d point in view to find which object hit.
bool HitTest(const QPoint& point, HitContext& hitInfo) override;
+ AZ::Vector3 GetHitLocation(const QPoint& point) override;
//! Do 2D hit testing of line in world space.
// pToCameraDistance is an optional output parameter in which distance from the camera to the line is returned.
diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp
index df1549cc31..c89d12a8ae 100644
--- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp
+++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.cpp
@@ -10,6 +10,17 @@
#include
+void OnVsyncIntervalChanged(uint32_t const& interval)
+{
+ AzFramework::WindowNotificationBus::Broadcast(
+ &AzFramework::WindowNotificationBus::Events::OnVsyncIntervalChanged, AZ::GetClamp(interval, 0u, 4u));
+}
+
+// NOTE: On change, broadcasts the new requested vsync interval to all windows.
+// The value of the vsync interval is constrained between 0 and 4
+// Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion)
+AZ_CVAR(uint32_t, vsync_interval, 1, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval");
+
namespace AzFramework
{
//////////////////////////////////////////////////////////////////////////
@@ -122,6 +133,16 @@ namespace AzFramework
return m_pimpl->GetDpiScaleFactor();
}
+ uint32_t NativeWindow::GetDisplayRefreshRate() const
+ {
+ return m_pimpl->GetDisplayRefreshRate();
+ }
+
+ uint32_t NativeWindow::GetSyncInterval() const
+ {
+ return vsync_interval;
+ }
+
/*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow()
{
NativeWindowHandle defaultWindowHandle = nullptr;
@@ -240,4 +261,10 @@ namespace AzFramework
return 1.0f;
}
+ uint32_t NativeWindow::Implementation::GetDisplayRefreshRate() const
+ {
+ // Default to 60
+ return 60;
+ }
+
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h
index 52157d920f..7479b0d1e1 100644
--- a/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h
+++ b/Code/Framework/AzFramework/AzFramework/Windowing/NativeWindow.h
@@ -130,6 +130,8 @@ namespace AzFramework
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
+ uint32_t GetSyncInterval() const override;
+ uint32_t GetDisplayRefreshRate() const override;
//! Get the full screen state of the default window.
//! \return True if the default window is currently in full screen, false otherwise.
@@ -172,6 +174,7 @@ namespace AzFramework
virtual void SetFullScreenState(bool fullScreenState);
virtual bool CanToggleFullScreenState() const;
virtual float GetDpiScaleFactor() const;
+ virtual uint32_t GetDisplayRefreshRate() const;
protected:
uint32_t m_width = 0;
diff --git a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h
index 776cd43787..d3bd0ce82c 100644
--- a/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h
+++ b/Code/Framework/AzFramework/AzFramework/Windowing/WindowBus.h
@@ -74,6 +74,12 @@ namespace AzFramework
//! to a "standard" value of 96, the default for Windows in a DPI unaware setting. This can
//! be used to scale user interface elements to ensure legibility on high density displays.
virtual float GetDpiScaleFactor() const = 0;
+
+ //! Returns the sync interval which tells the drivers the number of v-blanks to synchronize with
+ virtual uint32_t GetSyncInterval() const = 0;
+
+ //! Returns the refresh rate of the main display
+ virtual uint32_t GetDisplayRefreshRate() const = 0;
};
using WindowRequestBus = AZ::EBus;
@@ -101,6 +107,9 @@ namespace AzFramework
//! This is called when vsync interval is changed.
virtual void OnVsyncIntervalChanged(uint32_t interval) { AZ_UNUSED(interval); };
+
+ //! This is called if the main display's refresh rate changes
+ virtual void OnRefreshRateChanged([[maybe_unused]] uint32_t refreshRate) {}
};
using WindowNotificationBus = AZ::EBus;
diff --git a/Code/Framework/AzFramework/Platform/Android/AzFramework/Windowing/NativeWindow_Android.cpp b/Code/Framework/AzFramework/Platform/Android/AzFramework/Windowing/NativeWindow_Android.cpp
index 8da63e9a5e..e655435011 100644
--- a/Code/Framework/AzFramework/Platform/Android/AzFramework/Windowing/NativeWindow_Android.cpp
+++ b/Code/Framework/AzFramework/Platform/Android/AzFramework/Windowing/NativeWindow_Android.cpp
@@ -25,7 +25,7 @@ namespace AzFramework
const WindowGeometry& geometry,
const WindowStyleMasks& styleMasks) override;
NativeWindowHandle GetWindowHandle() const override;
-
+ uint32_t GetDisplayRefreshRate() const override;
private:
ANativeWindow* m_nativeWindow = nullptr;
};
@@ -55,4 +55,9 @@ namespace AzFramework
return reinterpret_cast(m_nativeWindow);
}
+ uint32_t NativeWindowImpl_Android::GetDisplayRefreshRate() const
+ {
+ // Using 60 for now until proper support is added
+ return 60;
+ }
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp
index 5d738f8bdd..0ab1281eda 100644
--- a/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp
+++ b/Code/Framework/AzFramework/Platform/Linux/AzFramework/Windowing/NativeWindow_Linux.cpp
@@ -23,6 +23,7 @@ namespace AzFramework
const WindowGeometry& geometry,
const WindowStyleMasks& styleMasks) override;
NativeWindowHandle GetWindowHandle() const override;
+ uint32_t GetDisplayRefreshRate() const override;
};
NativeWindow::Implementation* NativeWindow::Implementation::Create()
@@ -44,4 +45,9 @@ namespace AzFramework
return nullptr;
}
+ uint32_t NativeWindowImpl_Linux::GetDisplayRefreshRate() const
+ {
+ //Using 60 for now until proper support is added
+ return 60;
+ }
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm
index 6e6b801e79..f9eef9170a 100644
--- a/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm
+++ b/Code/Framework/AzFramework/Platform/Mac/AzFramework/Windowing/NativeWindow_Mac.mm
@@ -34,12 +34,14 @@ namespace AzFramework
bool GetFullScreenState() const override;
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; }
+ uint32_t GetMainDisplayRefreshRate() const;
private:
static NSWindowStyleMask ConvertToNSWindowStyleMask(const WindowStyleMasks& styleMasks);
NSWindow* m_nativeWindow;
NSString* m_windowTitle;
+ uint32_t m_mainDisplayRefreshRate = 0;
};
NativeWindow::Implementation* NativeWindow::Implementation::Create()
@@ -76,6 +78,17 @@ namespace AzFramework
// Make the window active
[m_nativeWindow makeKeyAndOrderFront:nil];
m_nativeWindow.title = m_windowTitle;
+
+ CGDirectDisplayID display = CGMainDisplayID();
+ CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
+ m_mainDisplayRefreshRate = CGDisplayModeGetRefreshRate(currentMode);
+
+ // Assume 60hz if 0 is returned.
+ // This can happen on OSX. In future we can hopefully use maximumFramesPerSecond which wont have this issue
+ if (m_mainDisplayRefreshRate == 0)
+ {
+ m_mainDisplayRefreshRate = 60;
+ }
}
NativeWindowHandle NativeWindowImpl_Darwin::GetWindowHandle() const
@@ -128,4 +141,9 @@ namespace AzFramework
const NSWindowStyleMask defaultMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
return nativeMask ? nativeMask : defaultMask;
}
+
+ uint32_t NativeWindowImpl_Darwin::GetMainDisplayRefreshRate() const
+ {
+ return m_mainDisplayRefreshRate;
+ }
} // namespace AzFramework
diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp
index f3112ab89c..650dd14a1c 100644
--- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp
+++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard_Windows.cpp
@@ -117,9 +117,11 @@ namespace AzFramework
, m_hasFocus(false)
, m_hasTextEntryStarted(false)
{
+ static const char* s_keyboardCountEnvironmentVarName = "InputDeviceKeyboardInstanceCount";
+ s_instanceCount = AZ::Environment::FindVariable(s_keyboardCountEnvironmentVarName);
if (!s_instanceCount)
{
- s_instanceCount = AZ::Environment::CreateVariable("InputDeviceKeyboardInstanceCount", 1);
+ s_instanceCount = AZ::Environment::CreateVariable(s_keyboardCountEnvironmentVarName, 1);
// Register for raw keyboard input
RAWINPUTDEVICE rawInputDevice;
diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Mouse/InputDeviceMouse_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Mouse/InputDeviceMouse_Windows.cpp
index 464f49d620..d5d313eaab 100644
--- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Mouse/InputDeviceMouse_Windows.cpp
+++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Input/Devices/Mouse/InputDeviceMouse_Windows.cpp
@@ -138,9 +138,11 @@ namespace AzFramework
{
memset(&m_lastClientRect, 0, sizeof(m_lastClientRect));
+ static const char* s_mouseCountEnvironmentVarName = "InputDeviceMouseInstanceCount";
+ s_instanceCount = AZ::Environment::FindVariable(s_mouseCountEnvironmentVarName);
if (!s_instanceCount)
{
- s_instanceCount = AZ::Environment::CreateVariable("InputDeviceMouseInstanceCount", 1);
+ s_instanceCount = AZ::Environment::CreateVariable(s_mouseCountEnvironmentVarName, 1);
// Register for raw mouse input
RAWINPUTDEVICE rawInputDevice;
diff --git a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp
index 22a293891c..2c1d97dcf6 100644
--- a/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp
+++ b/Code/Framework/AzFramework/Platform/Windows/AzFramework/Windowing/NativeWindow_Windows.cpp
@@ -37,6 +37,7 @@ namespace AzFramework
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; }
float GetDpiScaleFactor() const override;
+ uint32_t GetDisplayRefreshRate() const override;
private:
static DWORD ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks);
@@ -56,6 +57,7 @@ namespace AzFramework
using GetDpiForWindowType = UINT(HWND hwnd);
GetDpiForWindowType* m_getDpiFunction = nullptr;
+ uint32_t m_mainDisplayRefreshRate = 0;
};
const wchar_t* NativeWindowImpl_Win32::s_defaultClassName = L"O3DEWin32Class";
@@ -144,6 +146,10 @@ namespace AzFramework
{
SetWindowLongPtr(m_win32Handle, GWLP_USERDATA, reinterpret_cast(this));
}
+
+ DEVMODE DisplayConfig;
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig);
+ m_mainDisplayRefreshRate = DisplayConfig.dmDisplayFrequency;
}
void NativeWindowImpl_Win32::Activate()
@@ -263,6 +269,15 @@ namespace AzFramework
WindowNotificationBus::Event(nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnDpiScaleFactorChanged, newScaleFactor);
break;
}
+ case WM_WINDOWPOSCHANGED:
+ {
+ DEVMODE DisplayConfig;
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig);
+ uint32_t refreshRate = DisplayConfig.dmDisplayFrequency;
+ WindowNotificationBus::Event(
+ nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnRefreshRateChanged, refreshRate);
+ break;
+ }
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
@@ -367,6 +382,11 @@ namespace AzFramework
return aznumeric_cast(dotsPerInch) / aznumeric_cast(defaultDotsPerInch);
}
+ uint32_t NativeWindowImpl_Win32::GetDisplayRefreshRate() const
+ {
+ return m_mainDisplayRefreshRate;
+ }
+
void NativeWindowImpl_Win32::EnterBorderlessWindowFullScreen()
{
if (m_isInBorderlessWindowFullScreenState)
diff --git a/Code/Framework/AzFramework/Platform/iOS/AzFramework/Windowing/NativeWindow_ios.mm b/Code/Framework/AzFramework/Platform/iOS/AzFramework/Windowing/NativeWindow_ios.mm
index b14db37d23..83e176b9ef 100644
--- a/Code/Framework/AzFramework/Platform/iOS/AzFramework/Windowing/NativeWindow_ios.mm
+++ b/Code/Framework/AzFramework/Platform/iOS/AzFramework/Windowing/NativeWindow_ios.mm
@@ -27,9 +27,11 @@ namespace AzFramework
const WindowGeometry& geometry,
const WindowStyleMasks& styleMasks) override;
NativeWindowHandle GetWindowHandle() const override;
-
+ uint32_t GetMainDisplayRefreshRate() const;
+
private:
UIWindow* m_nativeWindow;
+ uint32_t m_mainDisplayRefreshRate = 0;
};
NativeWindow::Implementation* NativeWindow::Implementation::Create()
@@ -56,6 +58,7 @@ namespace AzFramework
m_width = geometry.m_width;
m_height = geometry.m_height;
+ m_mainDisplayRefreshRate = [[UIScreen mainScreen] maximumFramesPerSecond];
}
NativeWindowHandle NativeWindowImpl_Ios::GetWindowHandle() const
@@ -63,5 +66,9 @@ namespace AzFramework
return m_nativeWindow;
}
+ uint32_t NativeWindowImpl_Ios::GetMainDisplayRefreshRate() const
+ {
+ return m_mainDisplayRefreshRate;
+ }
} // namespace AzFramework
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.cpp b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.cpp
index 3d0b78ece7..e4d10a321d 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.cpp
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.cpp
@@ -8,10 +8,13 @@
#include
+#include
#include
#include
#include
+#include
+
#include
#include
#include
@@ -252,5 +255,109 @@ namespace AzQtComponents
return qobject_cast(widget) && !qobject_cast(widget);
}
+ StyledTreeView::StyledTreeView(QWidget* parent)
+ : QTreeView(parent)
+ {
+ }
+
+ void StyledTreeView::startDrag(Qt::DropActions supportedActions)
+ {
+ if (!selectionModel()->selectedIndexes().empty())
+ {
+ StartCustomDrag(selectionModel()->selectedIndexes(), supportedActions);
+ }
+ }
+
+ void StyledTreeView::StartCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions)
+ {
+ StartCustomDragInternal(this, indexList, supportedActions);
+ }
+
+ void StyledTreeView::StartCustomDragInternal(QAbstractItemView* itemView, const QModelIndexList& indexList, Qt::DropActions supportedActions)
+ {
+ QMimeData* mimeData = itemView->model()->mimeData(indexList);
+ if (mimeData)
+ {
+ QDrag* drag = new QDrag(itemView);
+ drag->setPixmap(QPixmap::fromImage(CreateDragImage(itemView, indexList)));
+ drag->setMimeData(mimeData);
+
+ Qt::DropAction defDropAction = Qt::IgnoreAction;
+ if (itemView->defaultDropAction() != Qt::IgnoreAction && (supportedActions & itemView->defaultDropAction()))
+ {
+ defDropAction = itemView->defaultDropAction();
+ }
+ else if (supportedActions & Qt::CopyAction && itemView->dragDropMode() != QAbstractItemView::InternalMove)
+ {
+ defDropAction = Qt::CopyAction;
+ }
+
+ drag->exec(supportedActions, defDropAction);
+ }
+ }
+
+ QImage StyledTreeView::CreateDragImage(QAbstractItemView* itemView, const QModelIndexList& indexList)
+ {
+ // Generate a drag image of the item icon and text, normally done internally, and inaccessible
+ QRect rect(0, 0, 0, 0);
+ for (const auto& index : indexList)
+ {
+ if (index.column() != 0)
+ {
+ continue;
+ }
+
+ QRect itemRect = itemView->visualRect(index);
+ rect.setHeight(rect.height() + itemRect.height());
+ rect.setWidth(AZStd::GetMax(rect.width(), itemRect.width()));
+ }
+
+ QImage dragImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
+
+ QPainter dragPainter(&dragImage);
+ dragPainter.setCompositionMode(QPainter::CompositionMode_Source);
+ dragPainter.fillRect(dragImage.rect(), Qt::transparent);
+ dragPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
+ dragPainter.setOpacity(0.35f);
+ dragPainter.fillRect(rect, QColor("#222222"));
+ dragPainter.setOpacity(1.0f);
+
+ int imageY = 0;
+ for (const auto& index : indexList)
+ {
+ if (index.column() != 0)
+ {
+ continue;
+ }
+
+ QRect itemRect = itemView->visualRect(index);
+ dragPainter.drawPixmap(QPoint(0, imageY),
+ itemView->model()->data(index, Qt::DecorationRole).value().pixmap(QSize(16, 16)));
+ dragPainter.setPen(
+ itemView->model()->data(index, Qt::ForegroundRole).value().color());
+ dragPainter.setFont(
+ itemView->font());
+ dragPainter.drawText(QRect(20, imageY, rect.width() - 20, rect.height()),
+ itemView->model()->data(index, Qt::DisplayRole).value());
+ imageY += itemRect.height();
+ }
+
+ dragPainter.end();
+ return dragImage;
+ }
+
+ StyledTreeWidget::StyledTreeWidget(QWidget* parent)
+ : QTreeWidget(parent)
+ {
+ }
+
+ void StyledTreeWidget::startDrag(Qt::DropActions supportedActions)
+ {
+ if (!selectionModel()->selectedIndexes().empty())
+ {
+ StyledTreeView::StartCustomDragInternal(this, selectionModel()->selectedIndexes(), supportedActions);
+ }
+ }
+
} // namespace AzQtComponents
#include
diff --git a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.h b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.h
index 8fdcc24a8b..7510819e23 100644
--- a/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.h
+++ b/Code/Framework/AzQtComponents/AzQtComponents/Components/Widgets/TreeView.h
@@ -9,8 +9,11 @@
#pragma once
#if !defined(Q_MOC_RUN)
+#include
#include
#include
+
+#include
#endif
namespace AzQtComponents
@@ -68,4 +71,46 @@ namespace AzQtComponents
void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
};
+ //! For most of the custom QTreeView styling, we override in AzQtComponents::Style class,
+ //! but there are some cases (e.g. drag/drop) that can only be overriden by an actual
+ //! subclass of the QTreeView
+ class AZ_QT_COMPONENTS_API StyledTreeView
+ : public QTreeView
+ {
+ Q_OBJECT
+
+ public:
+ AZ_CLASS_ALLOCATOR(StyledTreeView, AZ::SystemAllocator, 0);
+
+ explicit StyledTreeView(QWidget* parent = nullptr);
+
+ //! NOTE: QTreeWidget derives from QTreeView, but because we need a custom dervied class
+ //! of QTreeView, then we can't inherit our custom drag methods in our custom derived
+ //! class of QTreeWidget, so these functions are made static so they can be shared
+ static void StartCustomDragInternal(QAbstractItemView* itemView, const QModelIndexList& indexList, Qt::DropActions supportedActions);
+ static QImage CreateDragImage(QAbstractItemView* itemView, const QModelIndexList& indexList);
+
+ protected:
+ void startDrag(Qt::DropActions supportedActions) override;
+
+ virtual void StartCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions);
+ };
+
+ //! For most of the custom QTreeWidget styling, we override in AzQtComponents::Style class,
+ //! but there are some cases (e.g. drag/drop) that can only be overriden by an actual
+ //! subclass of the QTreeWidget.
+ class AZ_QT_COMPONENTS_API StyledTreeWidget
+ : public QTreeWidget
+ {
+ Q_OBJECT
+
+ public:
+ AZ_CLASS_ALLOCATOR(StyledTreeWidget, AZ::SystemAllocator, 0);
+
+ explicit StyledTreeWidget(QWidget* parent = nullptr);
+
+ protected:
+ void startDrag(Qt::DropActions supportedActions) override;
+ };
+
} // namespace AzQtComponents
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.cpp
index eaee196c09..0549c600d3 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.cpp
@@ -27,7 +27,7 @@
namespace AzToolsFramework
{
EntityOutlinerTreeView::EntityOutlinerTreeView(QWidget* pParent)
- : QTreeView(pParent)
+ : AzQtComponents::StyledTreeView(pParent)
, m_queuedMouseEvent(nullptr)
, m_draggingUnselectedItem(false)
{
@@ -144,16 +144,12 @@ namespace AzToolsFramework
if (!selectionModel()->isSelected(index))
{
- startCustomDrag({ index }, supportedActions);
+ StartCustomDrag({ index }, supportedActions);
return;
}
}
- if (!selectionModel()->selectedIndexes().empty())
- {
- startCustomDrag(selectionModel()->selectedIndexes(), supportedActions);
- return;
- }
+ StyledTreeView::startDrag(supportedActions);
}
void EntityOutlinerTreeView::dragMoveEvent(QDragMoveEvent* event)
@@ -243,14 +239,14 @@ namespace AzToolsFramework
QTreeView::mousePressEvent(&mousePressedEvent);
}
- void EntityOutlinerTreeView::startCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions)
+ void EntityOutlinerTreeView::StartCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions)
{
m_draggingUnselectedItem = true;
//sort by container entity depth and order in hierarchy for proper drag image and drop order
QModelIndexList indexListSorted = indexList;
AZStd::unordered_map> locations;
- for (auto index : indexListSorted)
+ for (const auto& index : indexListSorted)
{
AZ::EntityId entityId(index.data(EntityOutlinerListModel::EntityIdRole).value());
AzToolsFramework::GetEntityLocationInHierarchy(entityId, locations[entityId]);
@@ -263,76 +259,8 @@ namespace AzToolsFramework
return AZStd::lexicographical_compare(locationsE1.begin(), locationsE1.end(), locationsE2.begin(), locationsE2.end());
});
- //get the data for the unselected item(s)
- QMimeData* mimeData = model()->mimeData(indexListSorted);
- if (mimeData)
- {
- //initiate drag/drop for the item
- QDrag* drag = new QDrag(this);
- drag->setPixmap(QPixmap::fromImage(createDragImage(indexListSorted)));
- drag->setMimeData(mimeData);
- Qt::DropAction defDropAction = Qt::IgnoreAction;
- if (defaultDropAction() != Qt::IgnoreAction && (supportedActions & defaultDropAction()))
- {
- defDropAction = defaultDropAction();
- }
- else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
- {
- defDropAction = Qt::CopyAction;
- }
- drag->exec(supportedActions, defDropAction);
- }
+ StyledTreeView::StartCustomDrag(indexListSorted, supportedActions);
}
-
- QImage EntityOutlinerTreeView::createDragImage(const QModelIndexList& indexList)
- {
- //generate a drag image of the item icon and text, normally done internally, and inaccessible
- QRect rect(0, 0, 0, 0);
- for (auto index : indexList)
- {
- if (index.column() != 0)
- {
- continue;
- }
- QRect itemRect = visualRect(index);
- rect.setHeight(rect.height() + itemRect.height());
- rect.setWidth(AZStd::GetMax(rect.width(), itemRect.width()));
- }
-
- QImage dragImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
-
- QPainter dragPainter(&dragImage);
- dragPainter.setCompositionMode(QPainter::CompositionMode_Source);
- dragPainter.fillRect(dragImage.rect(), Qt::transparent);
- dragPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
- dragPainter.setOpacity(0.35f);
- dragPainter.fillRect(rect, QColor("#222222"));
- dragPainter.setOpacity(1.0f);
-
- int imageY = 0;
- for (auto index : indexList)
- {
- if (index.column() != 0)
- {
- continue;
- }
-
- QRect itemRect = visualRect(index);
- dragPainter.drawPixmap(QPoint(0, imageY),
- model()->data(index, Qt::DecorationRole).value().pixmap(QSize(16, 16)));
- dragPainter.setPen(
- model()->data(index, Qt::ForegroundRole).value().color());
- dragPainter.setFont(
- font());
- dragPainter.drawText(QRect(20, imageY, rect.width() - 20, rect.height()),
- model()->data(index, Qt::DisplayRole).value());
- imageY += itemRect.height();
- }
-
- dragPainter.end();
- return dragImage;
- }
-
}
#include
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.hxx b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.hxx
index 89471de228..66cd082407 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.hxx
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutlinerTreeView.hxx
@@ -14,7 +14,8 @@
#include
#include
-#include
+
+#include
#endif
#pragma once
@@ -33,7 +34,7 @@ namespace AzToolsFramework
//! allow for dragging and dropping of entities from the outliner into the property editor
//! of other entities. If the selection updates instantly, this would never be possible.
class EntityOutlinerTreeView
- : public QTreeView
+ : public AzQtComponents::StyledTreeView
{
Q_OBJECT;
public:
@@ -68,9 +69,7 @@ namespace AzToolsFramework
void processQueuedMousePressedEvent(QMouseEvent* event);
- void startCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions);
-
- QImage createDragImage(const QModelIndexList& indexList);
+ void StartCustomDrag(const QModelIndexList& indexList, Qt::DropActions supportedActions) override;
void PaintBranchBackground(QPainter* painter, const QRect& rect, const QModelIndex& index) const;
diff --git a/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp b/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp
index 05fb56dfc1..3fa2a369a6 100644
--- a/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp
+++ b/Code/Framework/GridMate/Platform/Android/GridMate/Session/LANSession_Android.cpp
@@ -7,6 +7,7 @@
*/
#include
+#include
namespace GridMate
{
diff --git a/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp b/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp
index 05fb56dfc1..3fa2a369a6 100644
--- a/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp
+++ b/Code/Framework/GridMate/Platform/iOS/GridMate/Session/LANSession_iOS.cpp
@@ -7,6 +7,7 @@
*/
#include
+#include
namespace GridMate
{
diff --git a/Code/LauncherUnified/Platform/Mac/Launcher_Mac.mm b/Code/LauncherUnified/Platform/Mac/Launcher_Mac.mm
index cfba0d8aac..cbd5a043e1 100644
--- a/Code/LauncherUnified/Platform/Mac/Launcher_Mac.mm
+++ b/Code/LauncherUnified/Platform/Mac/Launcher_Mac.mm
@@ -10,6 +10,7 @@
#include
#include <../Common/Apple/Launcher_Apple.h>
#include <../Common/UnixLike/Launcher_UnixLike.h>
+#include
#if AZ_TESTS_ENABLED
diff --git a/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp b/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp
index 5cc3070cdb..44426f6d01 100644
--- a/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp
+++ b/Code/LauncherUnified/Platform/Windows/Launcher_Windows.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
int APIENTRY WinMain([[maybe_unused]] HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance, [[maybe_unused]] LPSTR lpCmdLine, [[maybe_unused]] int nCmdShow)
{
diff --git a/Code/Legacy/CryCommon/AppleSpecific.h b/Code/Legacy/CryCommon/AppleSpecific.h
index c572250b26..cd3146403a 100644
--- a/Code/Legacy/CryCommon/AppleSpecific.h
+++ b/Code/Legacy/CryCommon/AppleSpecific.h
@@ -226,6 +226,21 @@ typedef uint64 __uint64;
#define _PTRDIFF_T_DEFINED 1
+typedef union _LARGE_INTEGER
+{
+ struct
+ {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct
+ {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ long long QuadPart;
+} LARGE_INTEGER;
+
#define _A_RDONLY (0x01) /* Read only file */
#define _A_HIDDEN (0x02) /* Hidden file */
#define _A_SUBDIR (0x10) /* Subdirectory */
diff --git a/Code/Legacy/CryCommon/CryLibrary.h b/Code/Legacy/CryCommon/CryLibrary.h
index 787085af00..a034a2a04b 100644
--- a/Code/Legacy/CryCommon/CryLibrary.h
+++ b/Code/Legacy/CryCommon/CryLibrary.h
@@ -49,7 +49,7 @@
*/
#include
-#include
+#include
#include
#define INJECT_ENVIRONMENT_FUNCTION "InjectEnvironment"
diff --git a/Code/Legacy/CryCommon/MacSpecific.h b/Code/Legacy/CryCommon/MacSpecific.h
index 0533a1b556..1bc8c8a34b 100644
--- a/Code/Legacy/CryCommon/MacSpecific.h
+++ b/Code/Legacy/CryCommon/MacSpecific.h
@@ -26,4 +26,6 @@
typedef uint64_t threadID;
+#define VK_CONTROL 0
+
#endif // CRYINCLUDE_CRYCOMMON_MACSPECIFIC_H
diff --git a/Code/Tools/AzTestRunner/src/main.cpp b/Code/Tools/AzTestRunner/src/main.cpp
index 48ba527a45..0874efeff2 100644
--- a/Code/Tools/AzTestRunner/src/main.cpp
+++ b/Code/Tools/AzTestRunner/src/main.cpp
@@ -121,12 +121,6 @@ namespace AzTestRunner
{
const char* cwd = AzTestRunner::get_current_working_directory();
std::cout << "cwd = " << cwd << std::endl;
-
- for (int i = 0; i < argc; i++)
- {
- std::cout << "arg[" << i << "] " << argv[i] << std::endl;
- }
-
std::cout << "LIB: " << lib << std::endl;
}
@@ -227,6 +221,12 @@ namespace AzTestRunner
testMainFunction.reset();
}
+ // Construct a retry command if the test fails
+ if (result != 0)
+ {
+ std::cout << "Retry command: " << std::endl << argv[0] << " " << lib << " " << symbol << std::endl;
+ }
+
// unload and reset the module here, because it needs to release resources that were used / activated in
// system allocator / etc.
module.reset();
diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
index a9086a0c2b..4febb65782 100644
--- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
+++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.cpp
@@ -39,7 +39,7 @@ namespace O3DE::ProjectManager
NewProjectSettingsScreen::NewProjectSettingsScreen(QWidget* parent)
: ProjectSettingsScreen(parent)
{
- const QString defaultName{ "NewProject" };
+ const QString defaultName = GetDefaultProjectName();
const QString defaultPath = QDir::toNativeSeparators(GetDefaultProjectPath() + "/" + defaultName);
m_projectName->lineEdit()->setText(defaultName);
@@ -162,6 +162,17 @@ namespace O3DE::ProjectManager
return defaultPath;
}
+ QString NewProjectSettingsScreen::GetDefaultProjectName()
+ {
+ return "NewProject";
+ }
+
+ QString NewProjectSettingsScreen::GetProjectAutoPath()
+ {
+ const QString projectName = m_projectName->lineEdit()->text();
+ return QDir::toNativeSeparators(GetDefaultProjectPath() + "/" + projectName);
+ }
+
ProjectManagerScreen NewProjectSettingsScreen::GetScreenEnum()
{
return ProjectManagerScreen::NewProjectSettings;
@@ -260,4 +271,22 @@ namespace O3DE::ProjectManager
m_projectTemplateButtonGroup->blockSignals(false);
}
}
+ void NewProjectSettingsScreen::OnProjectNameUpdated()
+ {
+ if (ValidateProjectName() && !m_userChangedProjectPath)
+ {
+ m_projectPath->setText(GetProjectAutoPath());
+ }
+ }
+
+ void NewProjectSettingsScreen::OnProjectPathUpdated()
+ {
+ const QString defaultPath = QDir::toNativeSeparators(GetDefaultProjectPath() + "/" + GetDefaultProjectName());
+ const QString autoPath = GetProjectAutoPath();
+ const QString path = m_projectPath->lineEdit()->text();
+ m_userChangedProjectPath = path != defaultPath && path != autoPath;
+
+ ValidateProjectPath();
+ }
+
} // namespace O3DE::ProjectManager
diff --git a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
index ebe40de05c..42c47cb1ff 100644
--- a/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
+++ b/Code/Tools/ProjectManager/Source/NewProjectSettingsScreen.h
@@ -40,8 +40,14 @@ namespace O3DE::ProjectManager
signals:
void OnTemplateSelectionChanged(int oldIndex, int newIndex);
+ protected:
+ void OnProjectNameUpdated() override;
+ void OnProjectPathUpdated() override;
+
private:
+ QString GetDefaultProjectName();
QString GetDefaultProjectPath();
+ QString GetProjectAutoPath();
QFrame* CreateTemplateDetails(int margin);
void UpdateTemplateDetails(const ProjectTemplateInfo& templateInfo);
@@ -51,6 +57,7 @@ namespace O3DE::ProjectManager
TagContainerWidget* m_templateIncludedGems;
QVector m_templates;
int m_selectedTemplateIndex = -1;
+ bool m_userChangedProjectPath = false;
inline constexpr static int s_spacerSize = 20;
inline constexpr static int s_templateDetailsContentMargin = 20;
diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp
index 4c79117d96..88ae3d6319 100644
--- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp
+++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.cpp
@@ -40,12 +40,11 @@ namespace O3DE::ProjectManager
m_verticalLayout->setAlignment(Qt::AlignTop);
m_projectName = new FormLineEditWidget(tr("Project name"), "", this);
- connect(m_projectName->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::ValidateProjectName);
+ connect(m_projectName->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::OnProjectNameUpdated);
m_verticalLayout->addWidget(m_projectName);
m_projectPath = new FormFolderBrowseEditWidget(tr("Project Location"), "", this);
- m_projectPath->lineEdit()->setReadOnly(true);
- connect(m_projectPath->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::Validate);
+ connect(m_projectPath->lineEdit(), &QLineEdit::textChanged, this, &ProjectSettingsScreen::OnProjectPathUpdated);
m_verticalLayout->addWidget(m_projectPath);
projectSettingsFrame->setLayout(m_verticalLayout);
@@ -110,28 +109,36 @@ namespace O3DE::ProjectManager
m_projectName->setErrorLabelVisible(!projectNameIsValid);
return projectNameIsValid;
}
+
bool ProjectSettingsScreen::ValidateProjectPath()
{
bool projectPathIsValid = true;
- if (m_projectPath->lineEdit()->text().isEmpty())
+ QDir path(m_projectPath->lineEdit()->text());
+ if (!path.isAbsolute())
{
projectPathIsValid = false;
- m_projectPath->setErrorLabelText(tr("Please provide a valid location."));
+ m_projectPath->setErrorLabelText(tr("Please provide an absolute path for the project location."));
}
- else
+ else if (path.exists() && !path.isEmpty())
{
- QDir path(m_projectPath->lineEdit()->text());
- if (path.exists() && !path.isEmpty())
- {
- projectPathIsValid = false;
- m_projectPath->setErrorLabelText(tr("This folder exists and isn't empty. Please choose a different location."));
- }
+ projectPathIsValid = false;
+ m_projectPath->setErrorLabelText(tr("This folder exists and isn't empty. Please choose a different location."));
}
m_projectPath->setErrorLabelVisible(!projectPathIsValid);
return projectPathIsValid;
}
+ void ProjectSettingsScreen::OnProjectNameUpdated()
+ {
+ ValidateProjectName();
+ }
+
+ void ProjectSettingsScreen::OnProjectPathUpdated()
+ {
+ Validate();
+ }
+
bool ProjectSettingsScreen::Validate()
{
return ValidateProjectName() && ValidateProjectPath();
diff --git a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h
index b2544660e8..752e286ce1 100644
--- a/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h
+++ b/Code/Tools/ProjectManager/Source/ProjectSettingsScreen.h
@@ -33,10 +33,13 @@ namespace O3DE::ProjectManager
virtual bool Validate();
protected slots:
- virtual bool ValidateProjectName();
- virtual bool ValidateProjectPath();
+ virtual void OnProjectNameUpdated();
+ virtual void OnProjectPathUpdated();
protected:
+ bool ValidateProjectName();
+ virtual bool ValidateProjectPath();
+
QString GetDefaultProjectPath();
QHBoxLayout* m_horizontalLayout;
diff --git a/Code/Tools/ProjectManager/Source/UpdateProjectSettingsScreen.cpp b/Code/Tools/ProjectManager/Source/UpdateProjectSettingsScreen.cpp
index 8e9337bcae..6f7f7e1bed 100644
--- a/Code/Tools/ProjectManager/Source/UpdateProjectSettingsScreen.cpp
+++ b/Code/Tools/ProjectManager/Source/UpdateProjectSettingsScreen.cpp
@@ -108,10 +108,11 @@ namespace O3DE::ProjectManager
bool UpdateProjectSettingsScreen::ValidateProjectPath()
{
bool projectPathIsValid = true;
- if (m_projectPath->lineEdit()->text().isEmpty())
+ QDir path(m_projectPath->lineEdit()->text());
+ if (!path.isAbsolute())
{
projectPathIsValid = false;
- m_projectPath->setErrorLabelText(tr("Please provide a valid location."));
+ m_projectPath->setErrorLabelText(tr("Please provide an absolute path for the project location."));
}
m_projectPath->setErrorLabelVisible(!projectPathIsValid);
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/Scheduler/TestImpactProcessScheduler.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/Scheduler/TestImpactProcessScheduler.cpp
index a7e20a76f7..94df662a1d 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/Scheduler/TestImpactProcessScheduler.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/Process/Scheduler/TestImpactProcessScheduler.cpp
@@ -230,7 +230,7 @@ namespace TestImpact
processInFlight.m_process = LaunchProcess(AZStd::move(processInfo));
processInFlight.m_startTime = createTime;
}
- catch (ProcessException& e)
+ catch ([[maybe_unused]] ProcessException& e)
{
AZ_Warning("ProcessScheduler", false, e.what());
createResult = LaunchResult::Failure;
diff --git a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp
index e564b93f6c..756b1c75d6 100644
--- a/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp
+++ b/Code/Tools/TestImpactFramework/Runtime/Code/Source/TestEngine/Enumeration/TestImpactTestEnumerator.cpp
@@ -169,7 +169,7 @@ namespace TestImpact
WriteFileContents(SerializeTestEnumeration(enumeration.value()), jobInfo->GetCache()->m_file);
}
}
- catch (const Exception& e)
+ catch ([[maybe_unused]] const Exception& e)
{
AZ_Warning("Enumerate", false, e.what());
enumerations[jobId] = AZStd::nullopt;
diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/controller/view_edit_controller.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/controller/view_edit_controller.py
index 7e058e6a4e..54d0a29fea 100755
--- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/controller/view_edit_controller.py
+++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/controller/view_edit_controller.py
@@ -105,6 +105,8 @@ class ViewEditController(QObject):
def _create_new_config_file(self) -> None:
configuration: Configuration = self._configuration_manager.configuration
+ self._set_default_region(configuration)
+
try:
new_config_file_path: str = file_utils.join_path(
configuration.config_directory, constants.RESOURCE_MAPPING_DEFAULT_CONFIG_FILE_NAME)
@@ -117,6 +119,15 @@ class ViewEditController(QObject):
self._rescan_config_directory()
+ def _set_default_region(self, configuration: Configuration):
+ default_region = configuration.region
+ if not default_region or default_region == 'aws-global':
+ self.set_notification_frame_text_sender.emit(
+ notification_label_text.VIEW_EDIT_PAGE_CREATE_NEW_CONFIG_FILE_NO_DEFAULT_REGION_MESSAGE)
+ logger.warning(notification_label_text.VIEW_EDIT_PAGE_CREATE_NEW_CONFIG_FILE_NO_DEFAULT_REGION_MESSAGE)
+
+ configuration.region = constants.RESOURCE_MAPPING_DEFAULT_CONFIG_FILE_REGION
+
def _delete_table_row(self) -> None:
indices: List[QModelIndex] = self._table_view.selectedIndexes()
self._proxy_model.remove_resources(indices)
diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/constants.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/constants.py
index 857925499b..94846fc6b5 100755
--- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/constants.py
+++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/constants.py
@@ -24,6 +24,7 @@ AWS_RESOURCE_REGIONS: List[str] = ["us-east-2", "us-east-1", "us-west-1", "us-we
# Default client&server config file name
RESOURCE_MAPPING_CONFIG_FILE_NAME_SUFFIX: str = "_aws_resource_mappings.json"
RESOURCE_MAPPING_DEFAULT_CONFIG_FILE_NAME: str = "default" + RESOURCE_MAPPING_CONFIG_FILE_NAME_SUFFIX
+RESOURCE_MAPPING_DEFAULT_CONFIG_FILE_REGION: str = "us-east-1"
# View related constants
SEARCH_TYPED_RESOURCES_VERSION: str = "Import AWS Resources"
diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/notification_label_text.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/notification_label_text.py
index 4fbff42aba..ecd6d8282c 100755
--- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/notification_label_text.py
+++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/model/notification_label_text.py
@@ -5,6 +5,8 @@ For complete copyright and license terms please see the LICENSE at the root of t
SPDX-License-Identifier: Apache-2.0 OR MIT
"""
+from model import constants
+
NOTIFICATION_LOADING_MESSAGE: str = "Loading..."
ERROR_PAGE_OK_TEXT: str = "OK"
@@ -21,6 +23,12 @@ VIEW_EDIT_PAGE_RESCAN_TEXT: str = "Rescan"
VIEW_EDIT_PAGE_CONFIG_FILES_PLACEHOLDER_TEXT: str = "Found {} config files"
VIEW_EDIT_PAGE_SEARCH_PLACEHOLDER_TEXT: str = "Search by Key Name, Type, Name/ID, Account ID or Region"
VIEW_EDIT_PAGE_IMPORT_RESOURCES_PLACEHOLDER_TEXT: str = "Import Additional Resources"
+VIEW_EDIT_PAGE_CREATE_NEW_CONFIG_FILE_NO_DEFAULT_REGION_MESSAGE: str = \
+ f"Resource mapping file {constants.RESOURCE_MAPPING_DEFAULT_CONFIG_FILE_NAME} is created"\
+ f" with {constants.RESOURCE_MAPPING_DEFAULT_CONFIG_FILE_REGION} as the default region. "\
+ f"See "\
+ f"documentation "\
+ f"for configuring the AWS credentials and default region."
VIEW_EDIT_PAGE_SELECT_CONFIG_FILE_MESSAGE: str = "Please select the Config file you would like to view and modify..."
VIEW_EDIT_PAGE_NO_CONFIG_FILE_FOUND_MESSAGE: str = \
diff --git a/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/controller/test_view_edit_controller.py b/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/controller/test_view_edit_controller.py
index d76ae12940..f854d2cd68 100755
--- a/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/controller/test_view_edit_controller.py
+++ b/Gems/AWSCore/Code/Tools/ResourceMappingTool/tests/unit/controller/test_view_edit_controller.py
@@ -482,6 +482,7 @@ class TestViewEditController(TestCase):
mock_json_utils.create_empty_resource_mapping_file.assert_called_once()
mock_file_utils.find_files_with_suffix_under_directory.assert_called_once()
self._mocked_view_edit_page.set_config_files.assert_called_with(expected_config_files)
+ self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
@patch("controller.view_edit_controller.file_utils")
@patch("controller.view_edit_controller.json_utils")
@@ -496,7 +497,7 @@ class TestViewEditController(TestCase):
mock_file_utils.join_path.assert_called_once()
mock_json_utils.create_empty_resource_mapping_file.assert_called_once()
mock_file_utils.find_files_with_suffix_under_directory.assert_not_called()
- self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
+ assert len(self._test_view_edit_controller.set_notification_frame_text_sender.emit.mock_calls) == 2
@patch("controller.view_edit_controller.file_utils")
def test_page_rescan_button_post_notification_when_find_files_throw_exception(
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/AWSGameLiftClientModule.cpp b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/AWSGameLiftClientModule.cpp
index 4155aaca80..8a9ea5003a 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/AWSGameLiftClientModule.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftClient/Source/AWSGameLiftClientModule.cpp
@@ -42,4 +42,4 @@ namespace AWSGameLift
};
}// namespace AWSGameLift
-AZ_DECLARE_MODULE_CLASS(Gem_AWSGameLift_Client, AWSGameLift::AWSGameLiftClientModule)
+AZ_DECLARE_MODULE_CLASS(Gem_AWSGameLift_Clients, AWSGameLift::AWSGameLiftClientModule)
diff --git a/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerModule.cpp b/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerModule.cpp
index dfdf541049..9feacafec5 100644
--- a/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerModule.cpp
+++ b/Gems/AWSGameLift/Code/AWSGameLiftServer/Source/AWSGameLiftServerModule.cpp
@@ -42,4 +42,4 @@ namespace AWSGameLift
};
}// namespace AWSGameLift
-AZ_DECLARE_MODULE_CLASS(Gem_AWSGameLift_Server, AWSGameLift::AWSGameLiftServerModule)
+AZ_DECLARE_MODULE_CLASS(Gem_AWSGameLift_Servers, AWSGameLift::AWSGameLiftServerModule)
diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h
index 4232658980..e7ad98c074 100644
--- a/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h
+++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/Device.h
@@ -125,7 +125,6 @@ namespace AZ
Format GetNearestSupportedFormat(Format requestedFormat, FormatCapabilities requestedCapabilities) const;
//! Small API to support getting supported/working swapchain formats for a window.
- //! [GFX TODO]ATOM-1125] [RHI] Device::GetValidSwapChainImageFormats()
//! Returns the set of supported formats for swapchain images.
virtual AZStd::vector GetValidSwapChainImageFormats(const WindowHandle& windowHandle) const;
diff --git a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/NsightAftermath_Windows.cpp b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/NsightAftermath_Windows.cpp
index 4ee35b7675..199efbb139 100644
--- a/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/NsightAftermath_Windows.cpp
+++ b/Gems/Atom/RHI/DX12/Code/Source/Platform/Windows/RHI/NsightAftermath_Windows.cpp
@@ -85,7 +85,7 @@ namespace Aftermath
#if defined(USE_NSIGHT_AFTERMATH)
AZStd::vector cntxtHandles = static_cast(crashTracker)->GetContextHandles();
GFSDK_Aftermath_ContextData* outContextData = new GFSDK_Aftermath_ContextData[cntxtHandles.size()];
- GFSDK_Aftermath_Result result = GFSDK_Aftermath_GetData(cntxtHandles.size(), cntxtHandles.data(), outContextData);
+ GFSDK_Aftermath_Result result = GFSDK_Aftermath_GetData(static_cast(cntxtHandles.size()), cntxtHandles.data(), outContextData);
AssertOnError(result);
for (int i = 0; i < cntxtHandles.size(); i++)
{
diff --git a/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Conversions_Mac.h b/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Conversions_Mac.h
index cb1f48cfea..a4dc13a6f1 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Conversions_Mac.h
+++ b/Gems/Atom/RHI/Metal/Code/Source/Platform/Mac/RHI/Conversions_Mac.h
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
+#pragma once
+
namespace AZ
{
namespace Metal
diff --git a/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Conversions_iOS.h b/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Conversions_iOS.h
index cb1f48cfea..a4dc13a6f1 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Conversions_iOS.h
+++ b/Gems/Atom/RHI/Metal/Code/Source/Platform/iOS/RHI/Conversions_iOS.h
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
+#pragma once
+
namespace AZ
{
namespace Metal
diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp
index dbd2204e93..5591bcc843 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp
+++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/Device.cpp
@@ -77,7 +77,6 @@ namespace AZ
m_samplerCache = [[NSCache alloc]init];
[m_samplerCache setName:@"SamplerCache"];
-
return RHI::ResultCode::Success;
}
diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp
index 638f9bd184..0065ea724e 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp
+++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.cpp
@@ -8,6 +8,7 @@
#include
#include
+#include
#include
#include
#include
@@ -74,21 +75,16 @@ namespace AZ
AddSubView();
}
- m_refreshRate = Platform::GetRefreshRate();
-
- //Assume 60hz if 0 is returned.
- //Internal OSX displays have 'flexible' refresh rates, with a max of 60Hz - but report 0hz
- if (m_refreshRate < 0.1f)
- {
- m_refreshRate = 60.0f;
- }
-
m_drawables.resize(descriptor.m_dimensions.m_imageCount);
if (nativeDimensions)
{
*nativeDimensions = descriptor.m_dimensions;
}
+
+ AzFramework::WindowRequestBus::EventResult(
+ m_refreshRate, m_nativeWindow, &AzFramework::WindowRequestBus::Events::GetDisplayRefreshRate);
+
return RHI::ResultCode::Success;
}
@@ -160,7 +156,10 @@ namespace AZ
const uint32_t currentImageIndex = GetCurrentImageIndex();
//Preset the drawable
- Platform::PresentInternal(m_mtlCommandBuffer, m_drawables[currentImageIndex], GetDescriptor().m_verticalSyncInterval, m_refreshRate);
+ Platform::PresentInternal(
+ m_mtlCommandBuffer,
+ m_drawables[currentImageIndex], GetDescriptor().m_verticalSyncInterval,
+ m_refreshRate);
[m_drawables[currentImageIndex] release];
m_drawables[currentImageIndex] = nil;
diff --git a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h
index 571f12faf8..51dfe9258b 100644
--- a/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h
+++ b/Gems/Atom/RHI/Metal/Code/Source/RHI/SwapChain.h
@@ -53,7 +53,7 @@ namespace AZ
id m_mtlDevice = nil;
NativeWindowType* m_nativeWindow = nullptr;
AZStd::vector> m_drawables;
- float m_refreshRate = 0.0f;
+ uint32_t m_refreshRate = 0;
};
}
}
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.cpp b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.cpp
index 1b3a533f34..316144f323 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.cpp
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.cpp
@@ -117,6 +117,35 @@ namespace AZ
m_imageNullDescriptor.m_images[static_cast(ImageTypes::MultiSampleReadOnly2D)].m_sampleCountFlag = VK_SAMPLE_COUNT_4_BIT;
m_imageNullDescriptor.m_images[static_cast(ImageTypes::MultiSampleReadOnly2D)].m_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)] = {};
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_name = "NULL_DESCRIPTOR_GENERAL_ARRAY_2D";
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_sampleCountFlag = VK_SAMPLE_COUNT_1_BIT;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_format = VK_FORMAT_R8G8B8A8_SRGB;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_usageFlagBits =VkImageUsageFlagBits(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_arrayLayers = 1;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_imageCreateFlagBits = VkImageCreateFlagBits(0);
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_layout = VK_IMAGE_LAYOUT_GENERAL;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralArray2D)].m_dimension = imageDimension;
+
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)] = m_imageNullDescriptor.m_images[static_cast(NullDescriptorManager::ImageTypes::GeneralArray2D)];
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_name = "NULL_DESCRIPTOR_READONLY_ARRAY_2D";
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_sampleCountFlag = VK_SAMPLE_COUNT_1_BIT;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_format = VK_FORMAT_R8G8B8A8_SRGB;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_usageFlagBits = VkImageUsageFlagBits(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_arrayLayers = 1;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_imageCreateFlagBits = VkImageCreateFlagBits(0);
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::ReadOnlyArray2D)].m_dimension = imageDimension;
+
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)] = m_imageNullDescriptor.m_images[static_cast(NullDescriptorManager::ImageTypes::General2D)];
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_name = "NULL_DESCRIPTOR_STORAGE_ARRAY_2D";
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_sampleCountFlag = VK_SAMPLE_COUNT_1_BIT;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_format = VK_FORMAT_R32G32B32A32_UINT;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_usageFlagBits = VkImageUsageFlagBits(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT);
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_arrayLayers = 1;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_layout = VK_IMAGE_LAYOUT_GENERAL;
+ m_imageNullDescriptor.m_images[static_cast(ImageTypes::StorageArray2D)].m_dimension = 256;
+
m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralCube)] = m_imageNullDescriptor.m_images[static_cast(NullDescriptorManager::ImageTypes::General2D)];
m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralCube)].m_name = "NULL_DESCRIPTOR_GENERAL_CUBE";
m_imageNullDescriptor.m_images[static_cast(ImageTypes::GeneralCube)].m_arrayLayers = 6;
@@ -243,6 +272,10 @@ namespace AZ
{
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_3D;
}
+ else if (imageIndex >= static_cast(ImageTypes::GeneralArray2D) && imageIndex <= static_cast(ImageTypes::StorageArray2D))
+ {
+ imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
+ }
result = vkCreateImageView(device.GetNativeDevice(), &imageViewCreateInfo, nullptr, &m_imageNullDescriptor.m_images[imageIndex].m_view);
RETURN_RESULT_IF_UNSUCCESSFUL(ConvertResult(result));
@@ -366,7 +399,7 @@ namespace AZ
VkDescriptorImageInfo NullDescriptorManager::GetDescriptorImageInfo(RHI::ShaderInputImageType imageType, bool storageImage)
{
- if (imageType == RHI::ShaderInputImageType::Image2D || imageType == RHI::ShaderInputImageType::Image2DArray)
+ if (imageType == RHI::ShaderInputImageType::Image2D)
{
if (storageImage)
{
@@ -377,6 +410,17 @@ namespace AZ
return GetImage(ImageTypes::ReadOnly2D);
}
}
+ else if (imageType == RHI::ShaderInputImageType::Image2DArray)
+ {
+ if (storageImage)
+ {
+ return GetImage(ImageTypes::StorageArray2D);
+ }
+ else
+ {
+ return GetImage(ImageTypes::ReadOnlyArray2D);
+ }
+ }
else if (imageType == RHI::ShaderInputImageType::Image2DMultisample)
{
if (storageImage)
diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.h
index 52d12b97c4..e5c4dab22e 100644
--- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.h
+++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/NullDescriptorManager.h
@@ -30,6 +30,11 @@ namespace AZ
MultiSampleGeneral2D,
MultiSampleReadOnly2D,
+ // 2d image arrays
+ GeneralArray2D,
+ ReadOnlyArray2D,
+ StorageArray2D,
+
// cube images
GeneralCube,
ReadOnlyCube,
diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp
index 7c269b86d4..9720a88176 100644
--- a/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp
+++ b/Gems/Atom/RPI/Code/Source/RPI.Public/WindowContext.cpp
@@ -17,19 +17,6 @@
#include
#include
-
-void OnVsyncIntervalChanged(uint32_t const& interval)
-{
- AzFramework::WindowNotificationBus::Broadcast(
- &AzFramework::WindowNotificationBus::Events::OnVsyncIntervalChanged,
- AZ::GetClamp(interval, 0u, 4u));
-}
-
-// NOTE: On change, broadcasts the new requested vsync interval to all windows.
-// The value of the vsync interval is constrained between 0 and 4
-// Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion)
-AZ_CVAR(uint32_t, rpi_vsync_interval, 1, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval");
-
namespace AZ
{
namespace RPI
@@ -158,9 +145,13 @@ namespace AZ
const RHI::WindowHandle windowHandle = RHI::WindowHandle(reinterpret_cast(m_windowHandle));
+ uint32_t syncInterval = 1;
+ AzFramework::WindowRequestBus::EventResult(
+ syncInterval, m_windowHandle, &AzFramework::WindowRequestBus::Events::GetSyncInterval);
+
RHI::SwapChainDescriptor descriptor;
descriptor.m_window = windowHandle;
- descriptor.m_verticalSyncInterval = rpi_vsync_interval;
+ descriptor.m_verticalSyncInterval = syncInterval;
descriptor.m_dimensions.m_imageWidth = width;
descriptor.m_dimensions.m_imageHeight = height;
descriptor.m_dimensions.m_imageCount = 3;
diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
index cd670f3048..bb26e116af 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
+++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
@@ -121,6 +121,8 @@ namespace AtomToolsFramework
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
+ uint32_t GetSyncInterval() const override;
+ uint32_t GetDisplayRefreshRate() const;
protected:
// AzFramework::InputChannelEventListener ...
diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
index 5167e3d3f6..bf356d2b99 100644
--- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
+++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Viewport/RenderViewportWidget.cpp
@@ -465,4 +465,14 @@ namespace AtomToolsFramework
{
return aznumeric_cast(devicePixelRatioF());
}
+
+ uint32_t RenderViewportWidget::GetDisplayRefreshRate() const
+ {
+ return 60;
+ }
+
+ uint32_t RenderViewportWidget::GetSyncInterval() const
+ {
+ return 1;
+ }
} //namespace AtomToolsFramework
diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/NotificationWindow.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/NotificationWindow.cpp
index 0b277c6195..a186d94c49 100644
--- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/NotificationWindow.cpp
+++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/NotificationWindow.cpp
@@ -28,7 +28,7 @@ namespace EMStudio
setWindowTitle("Notification");
// window, no border, no focus, stays on top
- setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
+ setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint);
// enable the translucent background
setAttribute(Qt::WA_TranslucentBackground);
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp
index 221e1fdcea..d39ca83000 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp
+++ b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp
@@ -90,6 +90,11 @@ namespace EditorPythonBindings
PythonSymbolEventBus::Handler::BusConnect();
EditorPythonBindingsNotificationBus::Handler::BusConnect();
AZ::Interface::Register(this);
+
+ if (PythonSymbolEventBus::GetTotalNumOfEventHandlers() > 1)
+ {
+ OnPostInitialize();
+ }
}
void PythonLogSymbolsComponent::Deactivate()
@@ -111,6 +116,7 @@ namespace EditorPythonBindings
m_basePath = pythonSymbolsPath;
}
EditorPythonBindingsNotificationBus::Handler::BusDisconnect();
+ PythonSymbolEventBus::ExecuteQueuedEvents();
}
void PythonLogSymbolsComponent::WriteMethod(AZ::IO::HandleType handle, AZStd::string_view methodName, const AZ::BehaviorMethod& behaviorMethod, const AZ::BehaviorClass* behaviorClass)
@@ -206,12 +212,12 @@ namespace EditorPythonBindings
AZ::IO::FileIOBase::GetInstance()->Write(handle, buffer.c_str(), buffer.size());
}
- void PythonLogSymbolsComponent::LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass)
+ void PythonLogSymbolsComponent::LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass)
{
LogClassWithName(moduleName, behaviorClass, behaviorClass->m_name.c_str());
}
- void PythonLogSymbolsComponent::LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className)
+ void PythonLogSymbolsComponent::LogClassWithName(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass, const AZStd::string className)
{
Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
if (fileHandle.IsValid())
@@ -255,7 +261,11 @@ namespace EditorPythonBindings
}
}
- void PythonLogSymbolsComponent::LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod)
+ void PythonLogSymbolsComponent::LogClassMethod(
+ const AZStd::string moduleName,
+ const AZStd::string globalMethodName,
+ const AZ::BehaviorClass* behaviorClass,
+ const AZ::BehaviorMethod* behaviorMethod)
{
AZ_UNUSED(behaviorClass);
Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
@@ -265,7 +275,7 @@ namespace EditorPythonBindings
}
}
- void PythonLogSymbolsComponent::LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus)
+ void PythonLogSymbolsComponent::LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus)
{
if (behaviorEBus->m_events.empty())
{
@@ -404,7 +414,7 @@ namespace EditorPythonBindings
}
}
- void PythonLogSymbolsComponent::LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod)
+ void PythonLogSymbolsComponent::LogGlobalMethod(const AZStd::string moduleName, const AZStd::string methodName, const AZ::BehaviorMethod* behaviorMethod)
{
Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
if (fileHandle.IsValid())
@@ -428,7 +438,10 @@ namespace EditorPythonBindings
}
}
- void PythonLogSymbolsComponent::LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty)
+ void PythonLogSymbolsComponent::LogGlobalProperty(
+ const AZStd::string moduleName,
+ const AZStd::string propertyName,
+ const AZ::BehaviorProperty* behaviorProperty)
{
if (!behaviorProperty->m_getter || !behaviorProperty->m_getter->GetResult())
{
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h
index 54285198cf..5fbd1c3f37 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h
+++ b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h
@@ -51,12 +51,19 @@ namespace EditorPythonBindings
////////////////////////////////////////////////////////////////////////
// PythonSymbolEventBus::Handler
- void LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) override;
- void LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) override;
- void LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) override;
- void LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) override;
- void LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) override;
- void LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) override;
+ void LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass) override;
+ void LogClassWithName(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass, const AZStd::string className) override;
+ void LogClassMethod(
+ const AZStd::string moduleName,
+ const AZStd::string globalMethodName,
+ const AZ::BehaviorClass* behaviorClass,
+ const AZ::BehaviorMethod* behaviorMethod) override;
+ void LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus) override;
+ void LogGlobalMethod(const AZStd::string moduleName, const AZStd::string methodName, const AZ::BehaviorMethod* behaviorMethod) override;
+ void LogGlobalProperty(
+ const AZStd::string moduleName,
+ const AZStd::string propertyName,
+ const AZ::BehaviorProperty* behaviorProperty) override;
void Finalize() override;
AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) override;
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp b/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp
index 89f8248202..e640778bbe 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp
+++ b/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp
@@ -394,7 +394,7 @@ namespace EditorPythonBindings
// log the bus symbol
AZStd::string subModuleName = pybind11::cast(thisBusModule.attr("__name__"));
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus);
}
}
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp b/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp
index de8009830b..706ca48156 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp
+++ b/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp
@@ -756,7 +756,7 @@ namespace EditorPythonBindings
}
AZStd::string subModuleName = pybind11::cast(subModule.attr("__name__"));
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClassMethod, subModuleName, globalMethodName, behaviorClass, behaviorMethod);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClassMethod, subModuleName, globalMethodName, behaviorClass, behaviorMethod);
}
else
{
@@ -782,7 +782,7 @@ namespace EditorPythonBindings
pybind11::setattr(subModule, constantPropertyName.c_str(), constantValue);
AZStd::string subModuleName = pybind11::cast(subModule.attr("__name__"));
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, constantPropertyName, behaviorProperty);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, constantPropertyName, behaviorProperty);
}
}
@@ -809,11 +809,11 @@ namespace EditorPythonBindings
{
return ConstructPythonProxyObjectByTypename(behaviorClassName, pythonArgs);
});
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClassWithName, subModuleName, behaviorClass, properSyntax);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClassWithName, subModuleName, behaviorClass, properSyntax);
}
else
{
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClass, subModuleName, behaviorClass);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClass, subModuleName, behaviorClass);
}
}
}
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp
index 0404e81380..38e00e73ed 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp
+++ b/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp
@@ -153,7 +153,7 @@ namespace EditorPythonBindings
StaticPropertyHolderMapEntry& entry = iter->second;
entry.second->AddProperty(propertyName, behaviorProperty);
}
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, scopeName, propertyName, behaviorProperty);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, scopeName, propertyName, behaviorProperty);
}
pybind11::module DetermineScope(pybind11::module scope, const AZStd::string& fullName)
@@ -302,7 +302,7 @@ namespace EditorPythonBindings
// log global method symbol
AZStd::string subModuleName = pybind11::cast(targetModule.attr("__name__"));
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalMethod, subModuleName, methodName, behaviorMethod);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalMethod, subModuleName, methodName, behaviorMethod);
}
}
@@ -325,7 +325,7 @@ namespace EditorPythonBindings
// log global property symbol
AZStd::string subModuleName = pybind11::cast(globalsModule.attr("__name__"));
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, propertyName, behaviorProperty);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, propertyName, behaviorProperty);
if (behaviorProperty->m_getter && behaviorProperty->m_setter)
{
@@ -377,7 +377,7 @@ namespace EditorPythonBindings
PythonProxyBusManagement::CreateSubmodule(parentModule);
Internal::RegisterPaths(parentModule);
- PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::Finalize);
+ PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::Finalize);
}
}
}
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h b/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h
index 242225e87a..9c6d3bab37 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h
+++ b/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h
@@ -9,6 +9,14 @@
#include
+namespace AZ
+{
+ class BehaviorClass;
+ class BehaviorMethod;
+ class BehaviorEBus;
+ class BehaviorProperty;
+}
+
namespace EditorPythonBindings
{
//! An interface to track exported Python symbols
@@ -16,23 +24,39 @@ namespace EditorPythonBindings
: public AZ::EBusTraits
{
public:
+ // the symbols will be written out in the future
+ static const bool EnableEventQueue = true;
+
//! logs a behavior class type
- virtual void LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) = 0;
+ virtual void LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass) = 0;
//! logs a behavior class type with an override to its name
- virtual void LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) = 0;
+ virtual void LogClassWithName(
+ const AZStd::string moduleName,
+ const AZ::BehaviorClass* behaviorClass,
+ const AZStd::string className) = 0;
//! logs a static class method with a specified global method name
- virtual void LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) = 0;
+ virtual void LogClassMethod(
+ const AZStd::string moduleName,
+ const AZStd::string globalMethodName,
+ const AZ::BehaviorClass* behaviorClass,
+ const AZ::BehaviorMethod* behaviorMethod) = 0;
//! logs a behavior bus with a specified bus name
- virtual void LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) = 0;
+ virtual void LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus) = 0;
//! logs a global method from the behavior context registry with a specified method name
- virtual void LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) = 0;
+ virtual void LogGlobalMethod(
+ const AZStd::string moduleName,
+ const AZStd::string methodName,
+ const AZ::BehaviorMethod* behaviorMethod) = 0;
//! logs a global property, enum, or constant from the behavior context registry with a specified property name
- virtual void LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) = 0;
+ virtual void LogGlobalProperty(
+ const AZStd::string moduleName,
+ const AZStd::string propertyName,
+ const AZ::BehaviorProperty* behaviorProperty) = 0;
//! signals the end of the logging of symbols
virtual void Finalize() = 0;
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp
index 32411e9417..8df196e7cb 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp
+++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp
@@ -10,6 +10,7 @@
#include
#include
+#include
#include
#include
#include
@@ -25,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
@@ -39,7 +41,7 @@
namespace Platform
{
- // Implemented in each different platform's implentation files, as it differs per platform.
+ // Implemented in each different platform's implementation files, as it differs per platform.
bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set& paths, const char* pythonPackage, const char* engineRoot);
AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot);
}
@@ -225,6 +227,37 @@ namespace RedirectOutput
namespace EditorPythonBindings
{
+ // A stand in bus to capture the log symbol queue events
+ // so that when/if the PythonLogSymbolsComponent becomes
+ // active it can write out the python symbols to disk
+ class PythonSystemComponent::SymbolLogHelper final
+ : public PythonSymbolEventBus::Handler
+ {
+ public:
+ SymbolLogHelper()
+ {
+ PythonSymbolEventBus::Handler::BusConnect();
+ }
+
+ ~SymbolLogHelper()
+ {
+ PythonSymbolEventBus::ExecuteQueuedEvents();
+ PythonSymbolEventBus::Handler::BusDisconnect();
+ }
+
+ void LogClass(const AZStd::string, const AZ::BehaviorClass*) override {}
+ void LogClassWithName(const AZStd::string, const AZ::BehaviorClass*, const AZStd::string) override {}
+ void LogClassMethod(
+ const AZStd::string,
+ const AZStd::string,
+ const AZ::BehaviorClass*,
+ const AZ::BehaviorMethod*) override {}
+ void LogBus(const AZStd::string, const AZStd::string, const AZ::BehaviorEBus*) override {}
+ void LogGlobalMethod(const AZStd::string, const AZStd::string, const AZ::BehaviorMethod*) override {}
+ void LogGlobalProperty(const AZStd::string, const AZStd::string, const AZ::BehaviorProperty*) override {}
+ void Finalize() override {}
+ };
+
void PythonSystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast(context))
@@ -471,8 +504,6 @@ namespace EditorPythonBindings
}
}
-
-
bool PythonSystemComponent::StartPythonInterpreter(const PythonPathStack& pythonPathStack)
{
AZStd::unordered_set pyPackageSites(pythonPathStack.begin(), pythonPathStack.end());
@@ -520,6 +551,11 @@ namespace EditorPythonBindings
AZStd::lock_guard lock(m_lock);
pybind11::gil_scoped_acquire acquire;
+ if (EditorPythonBindings::PythonSymbolEventBus::GetTotalNumOfEventHandlers() == 0)
+ {
+ m_symbolLogHelper = AZStd::make_shared();
+ }
+
// print Python version using AZ logging
const int verRet = PyRun_SimpleStringFlags("import sys \nprint (sys.version) \n", nullptr);
AZ_Error("python", verRet == 0, "Error trying to fetch the version number in Python!");
diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h
index 679da3ccab..48ac27a036 100644
--- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h
+++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h
@@ -59,10 +59,13 @@ namespace EditorPythonBindings
////////////////////////////////////////////////////////////////////////
private:
+ class SymbolLogHelper;
+
// handle multiple Python initializers and threads
AZStd::atomic_int m_initalizeWaiterCount {0};
AZStd::semaphore m_initalizeWaiter;
AZStd::recursive_mutex m_lock;
+ AZStd::shared_ptr m_symbolLogHelper;
enum class Result
{
diff --git a/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp b/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp
index 697820d75c..3646e5a413 100644
--- a/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp
+++ b/Gems/LyShine/Code/Editor/Animation/UiAnimViewAnimNode.cpp
@@ -1482,7 +1482,7 @@ bool CUiAnimViewAnimNode::PasteNodesFromClipboard(QWidget* context)
const bool bLightAnimationSetActive = GetSequence()->GetFlags() & IUiAnimSequence::eSeqFlags_LightAnimationSet;
const unsigned int numNodes = animNodesRoot->getChildCount();
- for (int i = 0; i < numNodes; ++i)
+ for (unsigned int i = 0; i < numNodes; ++i)
{
XmlNodeRef xmlNode = animNodesRoot->getChild(i);
diff --git a/Gems/LyShine/Code/Editor/HierarchyWidget.cpp b/Gems/LyShine/Code/Editor/HierarchyWidget.cpp
index 0b56382237..30cb7e51dc 100644
--- a/Gems/LyShine/Code/Editor/HierarchyWidget.cpp
+++ b/Gems/LyShine/Code/Editor/HierarchyWidget.cpp
@@ -21,7 +21,7 @@
#include
HierarchyWidget::HierarchyWidget(EditorWindow* editorWindow)
- : QTreeWidget()
+ : AzQtComponents::StyledTreeWidget()
, m_isDeleting(false)
, m_editorWindow(editorWindow)
, m_entityItemMap()
@@ -391,7 +391,7 @@ void HierarchyWidget::startDrag(Qt::DropActions supportedActions)
// Remember the current selection so that we can revert back to it when the items are dragged back into the hierarchy
m_dragSelection = selectedItems();
- QTreeView::startDrag(supportedActions);
+ AzQtComponents::StyledTreeWidget::startDrag(supportedActions);
}
void HierarchyWidget::dragEnterEvent(QDragEnterEvent* event)
diff --git a/Gems/LyShine/Code/Editor/HierarchyWidget.h b/Gems/LyShine/Code/Editor/HierarchyWidget.h
index 525aaa8a3a..324eda207b 100644
--- a/Gems/LyShine/Code/Editor/HierarchyWidget.h
+++ b/Gems/LyShine/Code/Editor/HierarchyWidget.h
@@ -10,6 +10,8 @@
#if !defined(Q_MOC_RUN)
#include "EditorCommon.h"
+#include
+
#include
#include
@@ -19,7 +21,7 @@
class QMimeData;
class HierarchyWidget
- : public QTreeWidget
+ : public AzQtComponents::StyledTreeWidget
, private AzToolsFramework::EditorPickModeNotificationBus::Handler
, private AzToolsFramework::EntityHighlightMessages::Bus::Handler
{
diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugModule.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugModule.cpp
index b320959dd7..bb80ffad29 100644
--- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugModule.cpp
+++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugModule.cpp
@@ -28,4 +28,4 @@ namespace Multiplayer
}
}
-AZ_DECLARE_MODULE_CLASS(Gem_Multiplayer_Imgui, Multiplayer::MultiplayerDebugModule);
+AZ_DECLARE_MODULE_CLASS(Gem_Multiplayer_Debug, Multiplayer::MultiplayerDebugModule);
diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp
index dbc525e8e1..2708f95f92 100644
--- a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp
@@ -322,11 +322,9 @@ namespace ScriptCanvasEditor
return;
}
- auto& variableOverrides = parseOutcome.GetValue();
-
if (!m_variableOverrides.IsEmpty())
{
- variableOverrides.CopyPreviousOverriddenValues(m_variableOverrides);
+ parseOutcome.GetValue().CopyPreviousOverriddenValues(m_variableOverrides);
}
m_variableOverrides = parseOutcome.TakeValue();
@@ -351,8 +349,7 @@ namespace ScriptCanvasEditor
}
auto runtimeComponent = gameEntity->CreateComponent();
- auto runtimeOverrides = ConvertToRuntime(m_variableOverrides);
- runtimeComponent->SetRuntimeDataOverrides(runtimeOverrides);
+ runtimeComponent->TakeRuntimeDataOverrides(ConvertToRuntime(m_variableOverrides));
}
void EditorScriptCanvasComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId)
@@ -518,8 +515,8 @@ namespace ScriptCanvasEditor
[[maybe_unused]] AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity();
AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity");
BuildGameEntityData();
- AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
UpdateName();
+ AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent);
}
}
diff --git a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl
index 4b22864b6e..05541196f7 100644
--- a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl
+++ b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl
@@ -283,7 +283,7 @@ namespace ScriptCanvasEditor
loadResult.m_runtimeAsset.Get()->GetData().m_debugMap = luaAssetResult.m_debugMap;
loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent();
CopyAssetEntityIdsToOverrides(runtimeDataOverrides);
- loadResult.m_runtimeComponent->SetRuntimeDataOverrides(runtimeDataOverrides);
+ loadResult.m_runtimeComponent->TakeRuntimeDataOverrides(AZStd::move(runtimeDataOverrides));
Execution::Context::InitializeActivationData(loadResult.m_runtimeAsset->GetData());
Execution::InitializeInterpretedStatics(loadResult.m_runtimeAsset->GetData());
}
diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp
index 5ec2637231..b80bba75c2 100644
--- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.cpp
@@ -311,7 +311,7 @@ namespace ScriptCanvasEditor
{
if (AZStd::wildcard_match("*.scriptcanvas", fullSourceFileName))
{
- return AzToolsFramework::AssetBrowser::SourceFileDetails("Icons/AssetBrowser/ScriptCanvas_16.png");
+ return AzToolsFramework::AssetBrowser::SourceFileDetails("Editor/Icons/AssetBrowser/ScriptCanvas_16.png");
}
// not one of our types.
diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp
index 8341cc1e24..96b0ac353f 100644
--- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ScriptCanvasNodePaletteDockWidget.cpp
@@ -80,12 +80,11 @@ namespace ScriptCanvasEditor
GraphCanvas::NodePaletteTreeItem* variablesRoot = root->CreateChildNode("Variables");
root->RegisterCategoryNode(variablesRoot, "Variables");
- // We always want to keep these around as place holders
GraphCanvas::NodePaletteTreeItem* customEventRoot = root->GetCategoryNode("Script Events");
- customEventRoot->SetAllowPruneOnEmpty(false);
+ customEventRoot->SetAllowPruneOnEmpty(true);
GraphCanvas::NodePaletteTreeItem* globalFunctionRoot = root->GetCategoryNode("User Functions");
- globalFunctionRoot->SetAllowPruneOnEmpty(false);
+ globalFunctionRoot->SetAllowPruneOnEmpty(true);
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h
index 83db8fc242..4cbc25b500 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h
@@ -20,6 +20,7 @@
namespace AZ
{
class ReflectContext;
+ class DatumSerializer;
}
namespace ScriptCanvas
@@ -33,6 +34,8 @@ namespace ScriptCanvas
/// in the editor, regardless of their actual ScriptCanvas or BehaviorContext type.
class Datum final
{
+ friend class AZ::DatumSerializer;
+
public:
AZ_TYPE_INFO(Datum, "{8B836FC0-98A8-4A81-8651-35C7CA125451}");
AZ_CLASS_ALLOCATOR(Datum, AZ::SystemAllocator, 0);
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp
index 81d6445556..9d1626fb73 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp
@@ -509,7 +509,8 @@ namespace ScriptCanvas
bool SubgraphInterface::HasAnyFunctionality() const
{
- return IsActiveDefaultObject() || HasPublicFunctionality();
+ // \todo restore default object addition when ndoes can define an variable, as well
+ return /*IsActiveDefaultObject() || */ HasPublicFunctionality();
}
bool SubgraphInterface::HasBranches() const
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp
index 2d3fd355e2..ac19028fd5 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp
@@ -93,9 +93,9 @@ namespace ScriptCanvas
return m_runtimeOverrides;
}
- void RuntimeComponent::SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData)
+ void RuntimeComponent::TakeRuntimeDataOverrides(RuntimeDataOverrides&& overrideData)
{
- m_runtimeOverrides = overrideData;
+ m_runtimeOverrides = AZStd::move(overrideData);
m_runtimeOverrides.EnforcePreloadBehavior();
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h
index 38ff219d4c..8650433b0a 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h
@@ -54,7 +54,7 @@ namespace ScriptCanvas
const RuntimeDataOverrides& GetRuntimeDataOverrides() const;
- void SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData);
+ void TakeRuntimeDataOverrides(RuntimeDataOverrides&& overrideData);
protected:
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml
index 14634ff959..951a30ceb1 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/RepeaterNodeable.ScriptCanvasNodeable.xml
@@ -10,17 +10,17 @@
Category="Nodeables"
GeneratePropertyFriend="True"
Namespace="ScriptCanvas"
- Description="Repeats the output signal the given number of times using the specified delay to space the signals out">
+ Description="Repeats the output signal the given number of times using the specified delay to space the signals out.">
-
+
-
+
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp
new file mode 100644
index 0000000000..44ca1730a8
--- /dev/null
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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
+#include
+#include
+
+using namespace ScriptCanvas;
+
+namespace AZ
+{
+ AZ_CLASS_ALLOCATOR_IMPL(DatumSerializer, SystemAllocator, 0);
+
+ JsonSerializationResult::Result DatumSerializer::Load
+ ( void* outputValue
+ , [[maybe_unused]] const Uuid& outputValueTypeId
+ , const rapidjson::Value& inputValue
+ , JsonDeserializerContext& context)
+ {
+ namespace JSR = JsonSerializationResult;
+
+ AZ_Assert(outputValueTypeId == azrtti_typeid(), "DatumSerializer Load against output typeID that was not Datum");
+ AZ_Assert(outputValue, "DatumSerializer Load against null output");
+
+ JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField);
+ auto outputDatum = reinterpret_cast(outputValue);
+
+ bool isOverloadedStorage = false;
+ AZ_Assert(azrtti_typeidm_isOverloadedStorage)>() == azrtti_typeid()
+ , "overloaded storage type changed and won't load properly");
+ result.Combine(ContinueLoadingFromJsonObjectField
+ ( &isOverloadedStorage
+ , azrtti_typeidm_isOverloadedStorage)>()
+ , inputValue
+ , "isOverloadedStorage"
+ , context));
+
+ ScriptCanvas::Data::Type scType;
+ AZ_Assert(azrtti_typeidm_type)>() == azrtti_typeid()
+ , "ScriptCanvas::Data::Type type changed and won't load properly");
+ result.Combine(ContinueLoadingFromJsonObjectField
+ ( &scType
+ , azrtti_typeidm_type)>()
+ , inputValue
+ , "scriptCanvasType"
+ , context));
+
+ AZStd::any storage;
+ { // datum storage begin
+ AZ::Uuid typeId = AZ::Uuid::CreateNull();
+
+ auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier);
+ if (typeIdMember == inputValue.MemberEnd())
+ {
+ return context.Report
+ ( JSR::Tasks::ReadField
+ , JSR::Outcomes::Missing
+ , AZStd::string::format("DatumSerializer::Load failed to load the %s member"
+ , JsonSerialization::TypeIdFieldIdentifier));
+ }
+
+ result.Combine(LoadTypeId(typeId, typeIdMember->value, context));
+ if (typeId.IsNull())
+ {
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic
+ , "DatumSerializer::Load failed to load the AZ TypeId of the value");
+ }
+
+ storage = context.GetSerializeContext()->CreateAny(typeId);
+ if (storage.empty() || storage.type() != typeId)
+ {
+ return context.Report(result, "DatumSerializer::Load failed to load a value matched the reported AZ TypeId. "
+ "The C++ declaration may have been deleted or changed.");
+ }
+
+ result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "value", context));
+ } // datum storage end
+
+ AZStd::string label;
+ AZ_Assert(azrtti_typeidm_datumLabel)>() == azrtti_typeid()
+ , "m_datumLabel type changed and won't load properly");
+ result.Combine(ContinueLoadingFromJsonObjectField
+ ( &label
+ , azrtti_typeidm_datumLabel)>()
+ , inputValue
+ , "label"
+ , context));
+
+ Datum copy(scType, Datum::eOriginality::Original, AZStd::any_cast(&storage), scType.GetAZType());
+ copy.SetLabel(label);
+ *outputDatum = copy;
+
+ return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
+ ? "DatumSerializer Load finished loading Datum"
+ : "DatumSerializer Load failed to load Datum");
+ }
+
+ JsonSerializationResult::Result DatumSerializer::Store
+ ( rapidjson::Value& outputValue
+ , const void* inputValue
+ , const void* defaultValue
+ , [[maybe_unused]] const Uuid& valueTypeId
+ , JsonSerializerContext& context)
+ {
+ namespace JSR = JsonSerializationResult;
+
+ AZ_Assert(valueTypeId == azrtti_typeid(), "DatumSerializer Store against value typeID that was not Datum");
+ AZ_Assert(inputValue, "DatumSerializer Store against null inputValue pointer ");
+
+ auto inputScriptDataPtr = reinterpret_cast(inputValue);
+ auto defaultScriptDataPtr = reinterpret_cast(defaultValue);
+
+ if (defaultScriptDataPtr)
+ {
+ if (*inputScriptDataPtr == *defaultScriptDataPtr)
+ {
+ return context.Report
+ ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "DatumSerializer Store used defaults for Datum");
+ }
+ }
+
+ JSR::ResultCode result(JSR::Tasks::WriteValue);
+ outputValue.SetObject();
+
+ result.Combine(ContinueStoringToJsonObjectField
+ ( outputValue
+ , "isOverloadedStorage"
+ , &inputScriptDataPtr->m_isOverloadedStorage
+ , defaultScriptDataPtr ? &defaultScriptDataPtr->m_isOverloadedStorage : nullptr
+ , azrtti_typeidm_isOverloadedStorage)>()
+ , context));
+
+ result.Combine(ContinueStoringToJsonObjectField
+ ( outputValue
+ , "scriptCanvasType"
+ , &inputScriptDataPtr->GetType()
+ , defaultScriptDataPtr ? &defaultScriptDataPtr->GetType() : nullptr
+ , azrtti_typeidGetType())>()
+ , context));
+
+ { // datum storage begin
+ {
+ rapidjson::Value typeValue;
+ result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->GetType().GetAZType(), context));
+ outputValue.AddMember
+ ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier)
+ , AZStd::move(typeValue)
+ , context.GetJsonAllocator());
+ }
+
+ result.Combine(ContinueStoringToJsonObjectField
+ ( outputValue
+ , "value"
+ , inputScriptDataPtr->GetAsDanger()
+ , defaultScriptDataPtr ? defaultScriptDataPtr->GetAsDanger() : nullptr
+ , inputScriptDataPtr->GetType().GetAZType()
+ , context));
+ } // datum storage end
+
+ result.Combine(ContinueStoringToJsonObjectField
+ ( outputValue
+ , "label"
+ , &inputScriptDataPtr->m_datumLabel
+ , defaultScriptDataPtr ? &defaultScriptDataPtr->m_datumLabel : nullptr
+ , azrtti_typeidm_datumLabel)>()
+ , context));
+
+ return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
+ ? "DatumSerializer Store finished saving Datum"
+ : "DatumSerializer Store failed to save Datum");
+ }
+
+}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.h
similarity index 87%
rename from Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h
rename to Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.h
index 720f9481f3..003c5c0383 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.h
@@ -14,11 +14,11 @@
namespace AZ
{
- class ScriptUserDataSerializer
+ class DatumSerializer
: public BaseJsonSerializer
{
public:
- AZ_RTTI(ScriptUserDataSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer);
+ AZ_RTTI(DatumSerializer, "{FBEBF833-465F-49F4-AFB1-CC9D3B25C16C}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
private:
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp
similarity index 74%
rename from Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp
rename to Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp
index 64cf665305..763206df38 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp
@@ -8,15 +8,15 @@
#include
#include
-#include
+#include
using namespace ScriptCanvas;
namespace AZ
{
- AZ_CLASS_ALLOCATOR_IMPL(ScriptUserDataSerializer, SystemAllocator, 0);
+ AZ_CLASS_ALLOCATOR_IMPL(RuntimeVariableSerializer, SystemAllocator, 0);
- JsonSerializationResult::Result ScriptUserDataSerializer::Load
+ JsonSerializationResult::Result RuntimeVariableSerializer::Load
( void* outputValue
, [[maybe_unused]] const Uuid& outputValueTypeId
, const rapidjson::Value& inputValue
@@ -24,8 +24,8 @@ namespace AZ
{
namespace JSR = JsonSerializationResult;
- AZ_Assert(outputValueTypeId == azrtti_typeid(), "ScriptUserDataSerializer Load against output typeID that was not RuntimeVariable");
- AZ_Assert(outputValue, "ScriptUserDataSerializer Load against null output");
+ AZ_Assert(outputValueTypeId == azrtti_typeid(), "RuntimeVariableSerializer Load against output typeID that was not RuntimeVariable");
+ AZ_Assert(outputValue, "RuntimeVariableSerializer Load against null output");
auto outputVariable = reinterpret_cast(outputValue);
JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField);
@@ -34,28 +34,28 @@ namespace AZ
auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier);
if (typeIdMember == inputValue.MemberEnd())
{
- return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier));
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, AZStd::string::format("RuntimeVariableSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier));
}
result.Combine(LoadTypeId(typeId, typeIdMember->value, context));
if (typeId.IsNull())
{
- return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load the AZ TypeId of the value");
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "RuntimeVariableSerializer::Load failed to load the AZ TypeId of the value");
}
outputVariable->value = context.GetSerializeContext()->CreateAny(typeId);
if (outputVariable->value.empty() || outputVariable->value.type() != typeId)
{
- return context.Report(result, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed.");
+ return context.Report(result, "RuntimeVariableSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed.");
}
result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&outputVariable->value), typeId, inputValue, "value", context));
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
- ? "ScriptUserDataSerializer Load finished loading RuntimeVariable"
- : "ScriptUserDataSerializer Load failed to load RuntimeVariable");
+ ? "RuntimeVariableSerializer Load finished loading RuntimeVariable"
+ : "RuntimeVariableSerializer Load failed to load RuntimeVariable");
}
- JsonSerializationResult::Result ScriptUserDataSerializer::Store
+ JsonSerializationResult::Result RuntimeVariableSerializer::Store
( rapidjson::Value& outputValue
, const void* inputValue
, const void* defaultValue
@@ -79,7 +79,7 @@ namespace AZ
if (inputDatum == defaultDatum)
{
- return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ScriptUserDataSerializer Store used defaults for RuntimeVariable");
+ return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "RuntimeVariableSerializer Store used defaults for RuntimeVariable");
}
}
@@ -95,8 +95,8 @@ namespace AZ
result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast(inputAnyPtr), AZStd::any_cast(defaultAnyPtr), inputAnyPtr->type(), context));
return context.Report(result, result.GetProcessing() != JSR::Processing::Halted
- ? "ScriptUserDataSerializer Store finished saving RuntimeVariable"
- : "ScriptUserDataSerializer Store failed to save RuntimeVariable");
+ ? "RuntimeVariableSerializer Store finished saving RuntimeVariable"
+ : "RuntimeVariableSerializer Store failed to save RuntimeVariable");
}
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h
new file mode 100644
index 0000000000..a55770c79f
--- /dev/null
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h
@@ -0,0 +1,37 @@
+/*
+ * 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
+#include
+#include
+
+namespace AZ
+{
+ class RuntimeVariableSerializer
+ : public BaseJsonSerializer
+ {
+ public:
+ AZ_RTTI(RuntimeVariableSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer);
+ AZ_CLASS_ALLOCATOR_DECL;
+
+ private:
+ JsonSerializationResult::Result Load
+ ( void* outputValue
+ , const Uuid& outputValueTypeId
+ , const rapidjson::Value& inputValue
+ , JsonDeserializerContext& context) override;
+
+ JsonSerializationResult::Result Store
+ ( rapidjson::Value& outputValue
+ , const void* inputValue
+ , const void* defaultValue
+ , const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ };
+}
diff --git a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp
index 9efbb13639..0a82b8cf2a 100644
--- a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp
+++ b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp
@@ -23,7 +23,8 @@
#include
#include
#include
-#include
+#include
+#include
#include
#include
@@ -87,8 +88,13 @@ namespace ScriptCanvas
if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(context))
{
- jsonContext->Serializer()
- ->HandlesType();
+ jsonContext->Serializer()
+ ->HandlesType()
+ ;
+
+ jsonContext->Serializer()
+ ->HandlesType()
+ ;
}
#if defined(SC_EXECUTION_TRACE_ENABLED)
diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake
index 84ba39cc72..f1215dd580 100644
--- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake
+++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake
@@ -539,8 +539,10 @@ set(FILES
Include/ScriptCanvas/Profiler/Aggregator.cpp
Include/ScriptCanvas/Profiler/DrillerEvents.h
Include/ScriptCanvas/Profiler/DrillerEvents.cpp
- Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h
- Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp
+ Include/ScriptCanvas/Serialization/DatumSerializer.h
+ Include/ScriptCanvas/Serialization/DatumSerializer.cpp
+ Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h
+ Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp
Include/ScriptCanvas/Data/DataTrait.cpp
Include/ScriptCanvas/Data/DataTrait.h
Include/ScriptCanvas/Data/PropertyTraits.cpp
diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json
index 4c275a49cf..0268412aea 100644
--- a/scripts/build/Platform/Windows/build_config.json
+++ b/scripts/build/Platform/Windows/build_config.json
@@ -89,7 +89,7 @@
"CONFIGURATION": "profile",
"SCRIPT_PATH": "scripts/build/TestImpactAnalysis/tiaf_driver.py",
"SCRIPT_PARAMETERS":
- "--config=\"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=!BRANCH_NAME! --dst-branch=!CHANGE_TARGET! --commit=!CHANGE_ID! --s3-bucket=!TEST_IMPACT_S3_BUCKET! --mars-index-prefix=jonawals --suite=main --test-failure-policy=continue"
+ "--config=\"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=!BRANCH_NAME! --dst-branch=!CHANGE_TARGET! --commit=!CHANGE_ID! --s3-bucket=!TEST_IMPACT_S3_BUCKET! --mars-index-prefix=jonawals --s3-top-level-dir=!REPOSITORY_NAME! --build-number=!BUILD_NUMBER! --suite=main --test-failure-policy=continue"
}
},
"debug_vs2019": {
diff --git a/scripts/build/TestImpactAnalysis/git_utils.py b/scripts/build/TestImpactAnalysis/git_utils.py
index ddc17ca146..61380ecb74 100644
--- a/scripts/build/TestImpactAnalysis/git_utils.py
+++ b/scripts/build/TestImpactAnalysis/git_utils.py
@@ -14,6 +14,7 @@ import pathlib
class Repo:
def __init__(self, repo_path: str):
self._repo = git.Repo(repo_path)
+ self._remote_url = self._repo.remotes[0].config_reader.get("url")
# Returns the current branch
@property
@@ -21,6 +22,11 @@ class Repo:
branch = self._repo.active_branch
return branch.name
+ # Returns the remote URL
+ @property
+ def remote_url(self):
+ return self._remote_url
+
def create_diff_file(self, src_commit_hash: str, dst_commit_hash: str, output_path: pathlib.Path, multi_branch: bool):
"""
Attempts to create a diff from the src and dst commits and write to the specified output file.
diff --git a/scripts/build/TestImpactAnalysis/mars_utils.py b/scripts/build/TestImpactAnalysis/mars_utils.py
index e2394ed6e1..8fa1f123c7 100644
--- a/scripts/build/TestImpactAnalysis/mars_utils.py
+++ b/scripts/build/TestImpactAnalysis/mars_utils.py
@@ -14,6 +14,7 @@ from tiaf_logger import get_logger
logger = get_logger(__file__)
MARS_JOB_KEY = "job"
+BUILD_NUMBER_KEY = "build_number"
SRC_COMMIT_KEY = "src_commit"
DST_COMMIT_KEY = "dst_commit"
COMMIT_DISTANCE_KEY = "commit_distance"
@@ -175,12 +176,14 @@ def get_duration_in_seconds(duration_in_milliseconds: int):
return duration_in_milliseconds * 0.001
-def generate_mars_job(tiaf_result, driver_args):
+def generate_mars_job(tiaf_result, driver_args, build_number: int):
"""
Generates a MARS job document using the job meta-data used to drive the TIAF sequence.
- @param tiaf_result: The result object generated by the TIAF script.
- @param driver_args: The arguments specified to the driver script.
+ @param tiaf_result: The result object generated by the TIAF script.
+ @param driver_args: The arguments specified to the driver script.
+ @param driver_args: The arguments specified to the driver script.
+ @param build_number: The build number this job corresponds to.
@return: The MARS job document with the job meta-data.
"""
@@ -203,6 +206,7 @@ def generate_mars_job(tiaf_result, driver_args):
]}
mars_job[DRIVER_ARGS_KEY] = driver_args
+ mars_job[BUILD_NUMBER_KEY] = build_number
return mars_job
def generate_test_run_list(test_runs):
@@ -418,7 +422,7 @@ def generate_mars_test_targets(sequence_report: dict, mars_job: dict, t0_timesta
return mars_test_targets
-def transmit_report_to_mars(mars_index_prefix: str, tiaf_result: dict, driver_args: list):
+def transmit_report_to_mars(mars_index_prefix: str, tiaf_result: dict, driver_args: list, build_number: int):
"""
Transforms the TIAF result into the appropriate MARS documents and transmits them to MARS.
@@ -434,7 +438,7 @@ def transmit_report_to_mars(mars_index_prefix: str, tiaf_result: dict, driver_ar
t0_timestamp = datetime.datetime.now().timestamp()
# Generate and transmit the MARS job document
- mars_job = generate_mars_job(tiaf_result, driver_args)
+ mars_job = generate_mars_job(tiaf_result, driver_args, build_number)
filebeat.send_event(mars_job, f"{mars_index_prefix}.tiaf.job")
if tiaf_result[REPORT_KEY]:
diff --git a/scripts/build/TestImpactAnalysis/tiaf.py b/scripts/build/TestImpactAnalysis/tiaf.py
index 11ca24f830..6a43ad3c70 100644
--- a/scripts/build/TestImpactAnalysis/tiaf.py
+++ b/scripts/build/TestImpactAnalysis/tiaf.py
@@ -161,7 +161,7 @@ class TestImpact:
result["change_list"] = self._change_list
return result
- def run(self, commit: str, src_branch: str, dst_branch: str, s3_bucket: str, suite: str, test_failure_policy: str, safe_mode: bool, test_timeout: int, global_timeout: int):
+ def run(self, commit: str, src_branch: str, dst_branch: str, s3_bucket: str, s3_top_level_dir: str, suite: str, test_failure_policy: str, safe_mode: bool, test_timeout: int, global_timeout: int):
"""
Determins the type of sequence to run based on the commit, source branch and test branch before running the
sequence with the specified values.
@@ -170,6 +170,7 @@ class TestImpact:
@param src_branch: If not equal to dst_branch, the branch that is being built.
@param dst_branch: If not equal to src_branch, the destination branch for the PR being built.
@param s3_bucket: Location of S3 bucket to use for persistent storage, otherwise local disk storage will be used.
+ @param s3_top_level_dir: Top level directory to use in the S3 bucket.
@param suite: Test suite to run.
@param test_failure_policy: Test failure policy for regular and test impact sequences (ignored when seeding).
@param safe_mode: Flag to run impact analysis tests in safe mode (ignored when seeding).
@@ -218,7 +219,7 @@ class TestImpact:
try:
# Persistent storage location
if s3_bucket:
- persistent_storage = PersistentStorageS3(self._config, suite, s3_bucket, self._source_of_truth_branch)
+ persistent_storage = PersistentStorageS3(self._config, suite, s3_bucket, s3_top_level_dir, self._source_of_truth_branch)
else:
persistent_storage = PersistentStorageLocal(self._config, suite)
except SystemError as e:
@@ -226,14 +227,20 @@ class TestImpact:
persistent_storage = None
if persistent_storage:
+ # Flag to signify whether or not this is a re-run (multiple runs of the same commit)
+ # Right now, we don't fully support re-runs but in the future we will have an extra subfolder for each commit hash with the
+ # last run hash that was used for the first run for the commit so we can retreive the same reference point for building the
+ # change list to ensure each subsequent run is using the same data but for the time being, just perform a regular run
+ is_rerun = False
if persistent_storage.has_historic_data:
logger.info("Historic data found.")
self._src_commit = persistent_storage.last_commit_hash
- # Perform some basic sanity checks on the commit hashes to ensure confidence in the integrity of of the environment
+ # Perform some basic sanity checks on the commit hashes to ensure confidence in the integrity of the environment
if self._src_commit == self._dst_commit:
- logger.error(f"Source commit '{self._src_commit}' and destination commit '{self._dst_commit}', implying the integrity of the historic data is compromised.")
+ logger.info(f"Source commit '{self._src_commit}' and destination commit '{self._dst_commit}', implying this is a re-run. A regular sequence will instead be performed.")
persistent_storage = None
+ is_rerun = True
else:
self._attempt_to_generate_change_list()
else:
@@ -261,7 +268,7 @@ class TestImpact:
args.append(f"--changelist={self._change_list_path}")
logger.info(f"Change list is set to '{self._change_list_path}'.")
else:
- if self._is_source_of_truth_branch:
+ if self._is_source_of_truth_branch and not is_rerun:
# Use seed sequence (instrumented all tests) for coverage updating branches so we can generate the coverage bed for future sequences
sequence_type = "seed"
# We always continue after test failures when seeding to ensure we capture the coverage for all test targets
diff --git a/scripts/build/TestImpactAnalysis/tiaf_driver.py b/scripts/build/TestImpactAnalysis/tiaf_driver.py
index 5ad16abaa0..ad49d98102 100644
--- a/scripts/build/TestImpactAnalysis/tiaf_driver.py
+++ b/scripts/build/TestImpactAnalysis/tiaf_driver.py
@@ -11,6 +11,7 @@ import mars_utils
import sys
import pathlib
import traceback
+import re
from tiaf import TestImpact
from tiaf_logger import get_logger
@@ -66,13 +67,20 @@ def parse_args():
required=True
)
- # S3 bucket
+ # S3 bucket name
parser.add_argument(
'--s3-bucket',
help="Location of S3 bucket to use for persistent storage, otherwise local disk storage will be used",
required=False
)
+ # S3 bucket top level directory
+ parser.add_argument(
+ '--s3-top-level-dir',
+ help="The top level directory to use in the S3 bucket",
+ required=False
+ )
+
# MARS index prefix
parser.add_argument(
'--mars-index-prefix',
@@ -80,6 +88,13 @@ def parse_args():
required=False
)
+ # Build number
+ parser.add_argument(
+ '--build-number',
+ help="The build number this run of TIAF corresponds to",
+ required=True
+ )
+
# Test suite
parser.add_argument(
'--suite',
@@ -127,12 +142,19 @@ if __name__ == "__main__":
try:
args = parse_args()
+
+ s3_top_level_dir = None
+ if args.s3_top_level_dir:
+ s3_top_level_dir = args.s3_top_level_dir
+ else:
+ s3_top_level_dir = "tiaf"
+
tiaf = TestImpact(args.config)
- tiaf_result = tiaf.run(args.commit, args.src_branch, args.dst_branch, args.s3_bucket, args.suite, args.test_failure_policy, args.safe_mode, args.test_timeout, args.global_timeout)
+ tiaf_result = tiaf.run(args.commit, args.src_branch, args.dst_branch, args.s3_bucket, s3_top_level_dir, args.suite, args.test_failure_policy, args.safe_mode, args.test_timeout, args.global_timeout)
if args.mars_index_prefix:
logger.info("Transmitting report to MARS...")
- mars_utils.transmit_report_to_mars(args.mars_index_prefix, tiaf_result, sys.argv)
+ mars_utils.transmit_report_to_mars(args.mars_index_prefix, tiaf_result, sys.argv, args.build_number)
logger.info("Complete!")
# Non-gating will be removed from this script and handled at the job level in SPEC-7413
diff --git a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py
index ec646ee484..1ee3ac7e8c 100644
--- a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py
+++ b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage.py
@@ -106,7 +106,7 @@ class PersistentStorage(ABC):
historic_data_json = self._pack_historic_data(last_commit_hash)
if historic_data_json:
- logger.info(f"Attempting to store historic data with new last commit hash '{self._last_commit_hash}'...")
+ logger.info(f"Attempting to store historic data with new last commit hash '{last_commit_hash}'...")
self._store_historic_data(historic_data_json)
logger.info("The historic data was successfully stored.")
diff --git a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py
index 24101c7cba..1a279855ea 100644
--- a/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py
+++ b/scripts/build/TestImpactAnalysis/tiaf_persistent_storage_s3.py
@@ -18,7 +18,7 @@ logger = get_logger(__file__)
# Implementation of s3 bucket persistent storage
class PersistentStorageS3(PersistentStorage):
- def __init__(self, config: dict, suite: str, s3_bucket: str, branch: str):
+ def __init__(self, config: dict, suite: str, s3_bucket: str, root_dir: str, branch: str):
"""
Initializes the persistent storage with the specified s3 bucket.
@@ -36,8 +36,8 @@ class PersistentStorageS3(PersistentStorage):
# historic_data.json.zip is the file containing the coverage and meta-data of the last TIAF sequence run
historic_data_file = f"historic_data.{object_extension}"
- # The location of the data is in the form / so the build config of each branch gets its own historic data
- self._dir = f'{branch}/{config["meta"]["build_config"]}'
+ # The location of the data is in the form // so the build config of each branch gets its own historic data
+ self._dir = f'{root_dir}/{branch}/{config["meta"]["build_config"]}'
self._historic_data_key = f'{self._dir}/{historic_data_file}'
logger.info(f"Attempting to retrieve historic data for branch '{branch}' at location '{self._historic_data_key}' on bucket '{s3_bucket}'...")