Merge branch 'main' into Atom/guthadam/ATOM-15223
This commit is contained in:
@@ -123,6 +123,21 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
)
|
||||
endif()
|
||||
|
||||
## Prefab ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
NAME AutomatedTesting::PrefabTests
|
||||
TEST_SUITE main
|
||||
TEST_SERIAL
|
||||
PATH ${CMAKE_CURRENT_LIST_DIR}/prefab/TestSuite_Main.py
|
||||
TIMEOUT 1500
|
||||
RUNTIME_DEPENDENCIES
|
||||
Legacy::Editor
|
||||
AZ::AssetProcessor
|
||||
AutomatedTesting.Assets
|
||||
)
|
||||
endif()
|
||||
|
||||
## Editor Python Bindings ##
|
||||
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
|
||||
ly_add_pytest(
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
|
||||
# fmt:off
|
||||
class Tests():
|
||||
find_empty_entity = ("Entity: 'EmptyEntity' found", "Entity: 'EmptyEntity' *not* found in level")
|
||||
empty_entity_pos = ("'EmptyEntity' position is at the expected position", "'EmptyEntity' position is *not* at the expected position")
|
||||
find_pxentity = ("Entity: 'EntityWithPxCollider' found", "Entity: 'EntityWithPxCollider' *not* found in level")
|
||||
pxentity_component = ("Entity: 'EntityWithPxCollider' has a Physx Collider", "Entity: 'EntityWithPxCollider' does *not* have a Physx Collider")
|
||||
|
||||
# fmt:on
|
||||
|
||||
def PrefabLevel_OpensLevelWithEntities():
|
||||
"""
|
||||
Opens the level that contains 2 entities, "EmptyEntity" and "EntityWithPxCollider".
|
||||
This test makes sure that both entities exist after opening the level and that:
|
||||
- EmptyEntity is at Position: (10, 20, 30)
|
||||
- EntityWithPxCollider has a PhysXCollider component
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
|
||||
import editor_python_test_tools.hydra_editor_utils as hydra
|
||||
|
||||
import azlmbr.entity as entity
|
||||
import azlmbr.bus as bus
|
||||
from azlmbr.math import Vector3
|
||||
|
||||
EXPECTED_EMPTY_ENTITY_POS = Vector3(10.00, 20.0, 30.0)
|
||||
|
||||
helper.init_idle()
|
||||
helper.open_level("prefab", "PrefabLevel_OpensLevelWithEntities")
|
||||
|
||||
def find_entity(entity_name):
|
||||
searchFilter = entity.SearchFilter()
|
||||
searchFilter.names = [entity_name]
|
||||
entityIds = entity.SearchBus(bus.Broadcast, 'SearchEntities', searchFilter)
|
||||
if entityIds[0].IsValid():
|
||||
return entityIds[0]
|
||||
return None
|
||||
#Checks for an entity called "EmptyEntity"
|
||||
helper.wait_for_condition(lambda: find_entity("EmptyEntity").IsValid(), 5.0)
|
||||
empty_entity_id = find_entity("EmptyEntity")
|
||||
Report.result(Tests.find_empty_entity, empty_entity_id.IsValid())
|
||||
|
||||
# Checks if the EmptyEntity is in the correct position and if it fails, it will provide the expected postion and the actual postion of the entity in the Editor log
|
||||
empty_entity_pos = azlmbr.components.TransformBus(azlmbr.bus.Event, "GetWorldTranslation", empty_entity_id)
|
||||
is_at_position = empty_entity_pos.IsClose(EXPECTED_EMPTY_ENTITY_POS)
|
||||
Report.result(Tests.empty_entity_pos, is_at_position)
|
||||
if not is_at_position:
|
||||
Report.info(f'Expected position: {EXPECTED_EMPTY_ENTITY_POS.ToString()}, actual position: {empty_entity_pos.ToString()}')
|
||||
|
||||
#Checks for an entity called "EntityWithPxCollider" and if it has the PhysX Collider component
|
||||
pxentity = find_entity("EntityWithPxCollider")
|
||||
Report.result(Tests.find_pxentity, pxentity.IsValid())
|
||||
|
||||
pxcollider_id = hydra.get_component_type_id("PhysX Collider")
|
||||
hasComponent = azlmbr.editor.EditorComponentAPIBus(azlmbr.bus.Broadcast, 'HasComponentOfType', pxentity, pxcollider_id)
|
||||
Report.result(Tests.pxentity_component, hasComponent)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
Report.start_test (PrefabLevel_OpensLevelWithEntities)
|
||||
@@ -0,0 +1,35 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
"""
|
||||
|
||||
# This suite consists of all test cases that are passing and have been verified.
|
||||
|
||||
import pytest
|
||||
import os
|
||||
import sys
|
||||
|
||||
from ly_test_tools import LAUNCHERS
|
||||
|
||||
sys.path.append (os.path.dirname (os.path.abspath (__file__)) + '/../automatedtesting_shared')
|
||||
|
||||
from base import TestAutomationBase
|
||||
|
||||
@pytest.mark.SUITE_main
|
||||
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
|
||||
@pytest.mark.parametrize("project", ["AutomatedTesting"])
|
||||
class TestAutomation(TestAutomationBase):
|
||||
|
||||
def _run_prefab_test(self, request, workspace, editor, test_module):
|
||||
self._run_test(request, workspace, editor, test_module, ["--regset=/Amazon/Preferences/EnablePrefabSystem=true"])
|
||||
|
||||
def test_PrefabLevel_OpensLevelWithEntities(self, request, workspace, editor, launcher_platform):
|
||||
from . import PrefabLevel_OpensLevelWithEntities as test_module
|
||||
self._run_prefab_test(request, workspace, editor, test_module)
|
||||
@@ -0,0 +1,10 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
@@ -0,0 +1,117 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
|
||||
|
||||
# fmt: off
|
||||
class Tests():
|
||||
node_duplicated = ("Successfully duplicated node", "Failed to duplicate the node")
|
||||
# fmt: on
|
||||
|
||||
|
||||
def Node_HappyPath_DuplicateNode():
|
||||
"""
|
||||
Summary:
|
||||
Duplicating node in graph
|
||||
|
||||
Expected Behavior:
|
||||
Upon selecting a node and pressing Ctrl+D, the node will be duplicated
|
||||
|
||||
Test Steps:
|
||||
1) Open Script Canvas window (Tools > Script Canvas)
|
||||
2) Open a new graph
|
||||
3) Add node to graph
|
||||
4) Duplicate node
|
||||
5) Verify the node was duplicated6) Verify the node was duplicated
|
||||
|
||||
Note:
|
||||
- This test file must be called from the Open 3D Engine Editor command terminal
|
||||
- Any passed and failed tests are written to the Editor.log file.
|
||||
Parsing the file or running a log_monitor are required to observe the test results.
|
||||
|
||||
:return: None
|
||||
"""
|
||||
from PySide2 import QtWidgets, QtTest
|
||||
from PySide2.QtCore import Qt
|
||||
|
||||
from editor_python_test_tools.utils import Report
|
||||
from editor_python_test_tools.utils import TestHelper as helper
|
||||
import editor_python_test_tools.pyside_utils as pyside_utils
|
||||
|
||||
import azlmbr.legacy.general as general
|
||||
|
||||
WAIT_FRAMES = 200
|
||||
|
||||
NODE_NAME = "Print"
|
||||
NODE_CATEGORY = "Debug"
|
||||
EXPECTED_STRING = f"{NODE_NAME} - {NODE_CATEGORY} (2 Selected)"
|
||||
|
||||
def command_line_input(command_str):
|
||||
cmd_action = pyside_utils.find_child_by_pattern(
|
||||
sc_main, {"objectName": "action_ViewCommandLine", "type": QtWidgets.QAction}
|
||||
)
|
||||
cmd_action.trigger()
|
||||
textbox = sc.findChild(QtWidgets.QLineEdit, "commandText")
|
||||
QtTest.QTest.keyClicks(textbox, command_str)
|
||||
QtTest.QTest.keyClick(textbox, Qt.Key_Enter, Qt.NoModifier)
|
||||
|
||||
def grab_title_text():
|
||||
scroll_area = node_inspector.findChild(QtWidgets.QScrollArea, "")
|
||||
QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES)
|
||||
background = scroll_area.findChild(QtWidgets.QFrame, "Background")
|
||||
title = background.findChild(QtWidgets.QLabel, "Title")
|
||||
text = title.findChild(QtWidgets.QLabel, "Title")
|
||||
return text.text()
|
||||
|
||||
# 1) Open Script Canvas window (Tools > Script Canvas)
|
||||
general.idle_enable(True)
|
||||
general.open_pane("Script Canvas")
|
||||
helper.wait_for_condition(lambda: general.is_pane_visible("Script Canvas"), 5.0)
|
||||
|
||||
# 2) Open a new graph
|
||||
editor_window = pyside_utils.get_editor_main_window()
|
||||
sc = editor_window.findChild(QtWidgets.QDockWidget, "Script Canvas")
|
||||
sc_main = sc.findChild(QtWidgets.QMainWindow)
|
||||
create_new_graph = pyside_utils.find_child_by_pattern(
|
||||
sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction}
|
||||
)
|
||||
if sc.findChild(QtWidgets.QDockWidget, "NodeInspector") is None:
|
||||
action = pyside_utils.find_child_by_pattern(sc, {"text": "Node Inspector", "type": QtWidgets.QAction})
|
||||
action.trigger()
|
||||
node_inspector = sc.findChild(QtWidgets.QDockWidget, "NodeInspector")
|
||||
create_new_graph.trigger()
|
||||
|
||||
# 3) Add node
|
||||
command_line_input("add_node Print")
|
||||
|
||||
# 4) Duplicate node
|
||||
graph_view = sc.findChild(QtWidgets.QFrame, "graphicsViewFrame")
|
||||
graph = graph_view.findChild(QtWidgets.QWidget, "")
|
||||
# There are currently no utilities available to directly duplicate the node,
|
||||
# therefore the node is selected using CTRL+A on the graph to select
|
||||
# it and then CTRL+D to duplicate
|
||||
sc_main.activateWindow()
|
||||
QtTest.QTest.keyClick(graph, "a", Qt.ControlModifier, WAIT_FRAMES)
|
||||
QtTest.QTest.keyClick(graph, "d", Qt.ControlModifier, WAIT_FRAMES)
|
||||
|
||||
# 5) Verify the node was duplicated
|
||||
# As direct interaction with node is not available the text on the label
|
||||
# inside the Node Inspector is validated showing two nodes exist
|
||||
after_dup = grab_title_text()
|
||||
Report.result(Tests.node_duplicated, after_dup == EXPECTED_STRING)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import ImportPathHelper as imports
|
||||
|
||||
imports.init()
|
||||
from editor_python_test_tools.utils import Report
|
||||
|
||||
Report.start_test(Node_HappyPath_DuplicateNode)
|
||||
@@ -84,7 +84,7 @@ class TestAutomation(TestAutomationBase):
|
||||
file_system.delete([os.path.join(workspace.paths.project(), "Levels", level)], True, True)
|
||||
from . import OnEntityActivatedDeactivated_PrintMessage as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
|
||||
@pytest.mark.test_case_id("T92562993")
|
||||
def test_NodePalette_ClearSelection(self, request, workspace, editor, launcher_platform, project):
|
||||
from . import NodePalette_ClearSelection as test_module
|
||||
@@ -122,7 +122,7 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_NodeInspector_RenameVariable(self, request, workspace, editor, launcher_platform, project):
|
||||
from . import NodeInspector_RenameVariable as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
|
||||
@pytest.mark.test_case_id("T92569137")
|
||||
def test_Debugging_TargetMultipleGraphs(self, request, workspace, editor, launcher_platform, project):
|
||||
from . import Debugging_TargetMultipleGraphs as test_module
|
||||
@@ -195,7 +195,7 @@ class TestAutomation(TestAutomationBase):
|
||||
def test_NodeCategory_ExpandOnClick(self, request, workspace, editor, launcher_platform):
|
||||
from . import NodeCategory_ExpandOnClick as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
|
||||
def test_NodePalette_SearchText_Deletion(self, request, workspace, editor, launcher_platform):
|
||||
from . import NodePalette_SearchText_Deletion as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
@@ -204,6 +204,10 @@ class TestAutomation(TestAutomationBase):
|
||||
from . import VariableManager_UnpinVariableType_Works as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
def test_Node_HappyPath_DuplicateNode(self, request, workspace, editor, launcher_platform):
|
||||
from . import Node_HappyPath_DuplicateNode as test_module
|
||||
self._run_test(request, workspace, editor, test_module)
|
||||
|
||||
# NOTE: We had to use hydra_test_utils.py, as TestAutomationBase run_test method
|
||||
# fails because of pyside_utils import
|
||||
@pytest.mark.SUITE_periodic
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
{
|
||||
"Source": "Levels/PrefabLevel_OpensLevelWithEntities/PrefabLevel_OpensLevelWithEntities.prefab",
|
||||
"ContainerEntity": {
|
||||
"Id": "Entity_[403811863694]",
|
||||
"Name": "Level",
|
||||
"Components": {
|
||||
"Component_[10582285743525614098]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 10582285743525614098
|
||||
},
|
||||
"Component_[12253783095375428046]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 12253783095375428046
|
||||
},
|
||||
"Component_[13764860261821571747]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 13764860261821571747,
|
||||
"Parent Entity": ""
|
||||
},
|
||||
"Component_[15844324401733835865]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 15844324401733835865
|
||||
},
|
||||
"Component_[1605854641405361768]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 1605854641405361768
|
||||
},
|
||||
"Component_[17698173984524983803]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 17698173984524983803
|
||||
},
|
||||
"Component_[3444251662966224826]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 3444251662966224826
|
||||
},
|
||||
"Component_[4231768881195179982]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 4231768881195179982
|
||||
},
|
||||
"Component_[4722360315410084479]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 4722360315410084479
|
||||
},
|
||||
"Component_[7614719100624882952]": {
|
||||
"$type": "EditorPrefabComponent",
|
||||
"Id": 7614719100624882952
|
||||
},
|
||||
"Component_[9585901769691795481]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 9585901769691795481
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entities": {
|
||||
"Entity_[438171602062]": {
|
||||
"Id": "Entity_[438171602062]",
|
||||
"Name": "EntityWithPxCollider",
|
||||
"Components": {
|
||||
"Component_[11161653124805884473]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 11161653124805884473
|
||||
},
|
||||
"Component_[13116773315299882093]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 13116773315299882093
|
||||
},
|
||||
"Component_[15820915681461536711]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 15820915681461536711
|
||||
},
|
||||
"Component_[2222061938345834243]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 2222061938345834243
|
||||
},
|
||||
"Component_[3861913165076405600]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 3861913165076405600
|
||||
},
|
||||
"Component_[7118587015611303204]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 7118587015611303204
|
||||
},
|
||||
"Component_[7751174327125555504]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 7751174327125555504
|
||||
},
|
||||
"Component_[8304730147756374057]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 8304730147756374057,
|
||||
"Parent Entity": "Entity_[403811863694]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
0.0,
|
||||
20.0,
|
||||
34.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[8866353210615920259]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 8866353210615920259
|
||||
},
|
||||
"Component_[8988181228601932779]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 8988181228601932779
|
||||
},
|
||||
"Component_[7103333782129541775]": {
|
||||
"$type": "EditorColliderComponent",
|
||||
"Id": 7103333782129541775
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
},
|
||||
"Entity_[532660882574]": {
|
||||
"Id": "Entity_[532660882574]",
|
||||
"Name": "EmptyEntity",
|
||||
"Components": {
|
||||
"Component_[16437814751543997955]": {
|
||||
"$type": "EditorEntitySortComponent",
|
||||
"Id": 16437814751543997955
|
||||
},
|
||||
"Component_[16751517102089557119]": {
|
||||
"$type": "EditorPendingCompositionComponent",
|
||||
"Id": 16751517102089557119
|
||||
},
|
||||
"Component_[16773275259304187949]": {
|
||||
"$type": "EditorInspectorComponent",
|
||||
"Id": 16773275259304187949
|
||||
},
|
||||
"Component_[17283539636910567200]": {
|
||||
"$type": "SelectionComponent",
|
||||
"Id": 17283539636910567200
|
||||
},
|
||||
"Component_[250004123617033400]": {
|
||||
"$type": "EditorLockComponent",
|
||||
"Id": 250004123617033400
|
||||
},
|
||||
"Component_[2791138963683667073]": {
|
||||
"$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
|
||||
"Id": 2791138963683667073,
|
||||
"Parent Entity": "Entity_[403811863694]",
|
||||
"Transform Data": {
|
||||
"Translate": [
|
||||
10.0,
|
||||
20.0,
|
||||
30.0
|
||||
]
|
||||
}
|
||||
},
|
||||
"Component_[3296942400051129145]": {
|
||||
"$type": "EditorEntityIconComponent",
|
||||
"Id": 3296942400051129145
|
||||
},
|
||||
"Component_[3422076964671342434]": {
|
||||
"$type": "EditorOnlyEntityComponent",
|
||||
"Id": 3422076964671342434
|
||||
},
|
||||
"Component_[3431895414183121731]": {
|
||||
"$type": "EditorVisibilityComponent",
|
||||
"Id": 3431895414183121731
|
||||
},
|
||||
"Component_[7072085777705148766]": {
|
||||
"$type": "EditorDisabledCompositionComponent",
|
||||
"Id": 7072085777705148766
|
||||
}
|
||||
},
|
||||
"IsDependencyReady": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1304,7 +1304,7 @@ namespace AZ
|
||||
// Add all auto loadable non-asset gems to the list of gem modules to load
|
||||
if (!moduleLoadData.m_autoLoad)
|
||||
{
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
for (AZ::OSString& dynamicLibraryPath : moduleLoadData.m_dynamicLibraryPaths)
|
||||
{
|
||||
|
||||
-8
@@ -282,14 +282,6 @@ namespace AzToolsFramework
|
||||
containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
|
||||
HandleEntitiesAdded({containerEntity});
|
||||
HandleEntitiesAdded(entities);
|
||||
|
||||
// Update the template of the instance since we modified the entities of the instance by calling HandleEntitiesAdded.
|
||||
Prefab::PrefabDom serializedInstance;
|
||||
if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(addedInstance, serializedInstance))
|
||||
{
|
||||
m_prefabSystemComponent->UpdatePrefabTemplate(addedInstance.GetTemplateId(), serializedInstance);
|
||||
}
|
||||
|
||||
return addedInstance;
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -270,7 +270,7 @@ namespace AzToolsFramework
|
||||
return parentInstance;
|
||||
}
|
||||
|
||||
void InstanceToTemplatePropagator::AddPatchesToLink(PrefabDom& patches, Link& link)
|
||||
void InstanceToTemplatePropagator::AddPatchesToLink(const PrefabDom& patches, Link& link)
|
||||
{
|
||||
PrefabDom& linkDom = link.GetLinkDom();
|
||||
PrefabDomValueReference linkPatchesReference =
|
||||
@@ -279,7 +279,14 @@ namespace AzToolsFramework
|
||||
// This logic only covers addition of patches. If patches already exists, the given list of patches must be appended to them.
|
||||
if (!linkPatchesReference.has_value())
|
||||
{
|
||||
linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patches, linkDom.GetAllocator());
|
||||
/*
|
||||
If the original allocator the patches were created with gets destroyed, then the patches would become garbage in the
|
||||
linkDom. Since we cannot guarantee the lifecycle of the patch allocators, we are doing a copy of the patches here to
|
||||
associate them with the linkDom's allocator.
|
||||
*/
|
||||
PrefabDom patchesCopy;
|
||||
patchesCopy.CopyFrom(patches, linkDom.GetAllocator());
|
||||
linkDom.AddMember(rapidjson::StringRef(PrefabDomUtils::PatchesName), patchesCopy, linkDom.GetAllocator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ namespace AzToolsFramework
|
||||
|
||||
void ApplyPatchesToInstance(const AZ::EntityId& entityId, PrefabDom& patches, const Instance& instanceToAddPatches) override;
|
||||
|
||||
void AddPatchesToLink(PrefabDom& patches, Link& link);
|
||||
void AddPatchesToLink(const PrefabDom& patches, Link& link);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace AzToolsFramework
|
||||
using PrefabDomList = AZStd::vector<PrefabDom>;
|
||||
|
||||
using PrefabDomReference = AZStd::optional<AZStd::reference_wrapper<PrefabDom>>;
|
||||
using PrefabDomConstReference = AZStd::optional<AZStd::reference_wrapper<const PrefabDom>>;
|
||||
using PrefabDomValueReference = AZStd::optional<AZStd::reference_wrapper<PrefabDomValue>>;
|
||||
using PrefabDomValueConstReference = AZStd::optional<AZStd::reference_wrapper<const PrefabDomValue>>;
|
||||
|
||||
|
||||
@@ -122,30 +122,49 @@ namespace AzToolsFramework
|
||||
|
||||
AZ::EntityId containerEntityId = instanceToCreate->get().GetContainerEntityId();
|
||||
|
||||
// Parent the entities to the container entity. Parenting the container entities of the instances passed to createPrefab
|
||||
// will be done during the creation of links below.
|
||||
for (AZ::Entity* topLevelEntity : entities)
|
||||
{
|
||||
AZ::TransformBus::Event(topLevelEntity->GetId(), &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
}
|
||||
|
||||
// Update the template of the instance since the entities are modified since the template creation.
|
||||
Prefab::PrefabDom serializedInstance;
|
||||
if (Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(instanceToCreate->get(), serializedInstance))
|
||||
{
|
||||
m_prefabSystemComponentInterface->UpdatePrefabTemplate(instanceToCreate->get().GetTemplateId(), serializedInstance);
|
||||
}
|
||||
|
||||
instanceToCreate->get().GetNestedInstances([&](AZStd::unique_ptr<Instance>& nestedInstance) {
|
||||
AZ_Assert(nestedInstance, "Invalid nested instance found in the new prefab created.");
|
||||
EntityOptionalReference nestedInstanceContainerEntity = nestedInstance->GetContainerEntity();
|
||||
AZ_Assert(
|
||||
nestedInstanceContainerEntity, "Invalid container entity found for the nested instance used in prefab creation.");
|
||||
|
||||
// These link creations shouldn't be undone because that would put the template in a non-usable state if a user
|
||||
// chooses to instantiate the template after undoing the creation.
|
||||
CreateLink(
|
||||
{&nestedInstanceContainerEntity->get()}, *nestedInstance, instanceToCreate->get().GetTemplateId(),
|
||||
undoBatch.GetUndoBatch(), containerEntityId);
|
||||
undoBatch.GetUndoBatch(), containerEntityId, false);
|
||||
});
|
||||
|
||||
// Create a link between the templates of the newly created instance and the instance it's being parented under.
|
||||
CreateLink(
|
||||
topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(), undoBatch.GetUndoBatch(),
|
||||
commonRootEntityId);
|
||||
topLevelEntities, instanceToCreate->get(), commonRootEntityOwningInstance->get().GetTemplateId(),
|
||||
undoBatch.GetUndoBatch(), commonRootEntityId);
|
||||
|
||||
// Change top level entities to be parented to the container entity
|
||||
// Mark them as dirty so this change is correctly applied to the template
|
||||
for (AZ::Entity* topLevelEntity : topLevelEntities)
|
||||
{
|
||||
AZ::EntityId topLevelEntityId = topLevelEntity->GetId();
|
||||
if (topLevelEntityId.IsValid())
|
||||
{
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntityId);
|
||||
undoBatch.MarkEntityDirty(topLevelEntityId);
|
||||
AZ::TransformBus::Event(topLevelEntityId, &AZ::TransformBus::Events::SetParent, containerEntityId);
|
||||
m_prefabUndoCache.UpdateCache(topLevelEntity->GetId());
|
||||
|
||||
// Parenting entities would mark entities as dirty. But we want to unmark the top level entities as dirty because
|
||||
// if we don't, the template created would be updated and cause issues with undo operation followed by instantiation.
|
||||
ToolsApplicationRequests::Bus::Broadcast(
|
||||
&ToolsApplicationRequests::Bus::Events::RemoveDirtyEntity, topLevelEntity->GetId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +315,7 @@ namespace AzToolsFramework
|
||||
|
||||
void PrefabPublicHandler::CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId)
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool isUndoRedoSupportNeeded)
|
||||
{
|
||||
AZ::EntityId containerEntityId = sourceInstance.GetContainerEntityId();
|
||||
AZ::Entity* containerEntity = GetEntityById(containerEntityId);
|
||||
@@ -322,9 +341,19 @@ namespace AzToolsFramework
|
||||
m_instanceToTemplateInterface->GeneratePatch(patch, containerEntityDomBefore, containerEntityDomAfter);
|
||||
m_instanceToTemplateInterface->AppendEntityAliasToPatchPaths(patch, containerEntityId);
|
||||
|
||||
LinkId linkId = PrefabUndoHelpers::CreateLink(
|
||||
sourceInstance.GetTemplateId(), targetTemplateId, patch, sourceInstance.GetInstanceAlias(),
|
||||
undoBatch);
|
||||
LinkId linkId;
|
||||
if (isUndoRedoSupportNeeded)
|
||||
{
|
||||
linkId = PrefabUndoHelpers::CreateLink(
|
||||
sourceInstance.GetTemplateId(), targetTemplateId, AZStd::move(patch), sourceInstance.GetInstanceAlias(), undoBatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
linkId = m_prefabSystemComponentInterface->CreateLink(
|
||||
targetTemplateId, sourceInstance.GetTemplateId(), sourceInstance.GetInstanceAlias(), patch,
|
||||
InvalidLinkId);
|
||||
m_prefabSystemComponentInterface->PropagateTemplateChanges(targetTemplateId);
|
||||
}
|
||||
|
||||
sourceInstance.SetLinkId(linkId);
|
||||
|
||||
@@ -357,7 +386,7 @@ namespace AzToolsFramework
|
||||
patchesCopyForUndoSupport.CopyFrom(nestedInstanceLinkPatches->get(), patchesCopyForUndoSupport.GetAllocator());
|
||||
PrefabUndoHelpers::RemoveLink(
|
||||
sourceInstance->GetTemplateId(), targetTemplateId, sourceInstance->GetInstanceAlias(), sourceInstance->GetLinkId(),
|
||||
patchesCopyForUndoSupport, undoBatch);
|
||||
AZStd::move(patchesCopyForUndoSupport), undoBatch);
|
||||
}
|
||||
|
||||
PrefabOperationResult PrefabPublicHandler::SavePrefab(AZ::IO::Path filePath)
|
||||
|
||||
@@ -77,10 +77,11 @@ namespace AzToolsFramework
|
||||
* \param targetInstance The id of the target template.
|
||||
* \param undoBatch The undo batch to set as parent for this create link action.
|
||||
* \param commonRootEntityId The id of the entity that the source instance should be parented under.
|
||||
* \param isUndoRedoSupportNeeded The flag indicating whether the link should be created with undo/redo support or not.
|
||||
*/
|
||||
void CreateLink(
|
||||
const EntityList& topLevelEntities, Instance& sourceInstance, TemplateId targetTemplateId,
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId);
|
||||
UndoSystem::URSequencePoint* undoBatch, AZ::EntityId commonRootEntityId, const bool isUndoRedoSupportNeeded = true);
|
||||
|
||||
/**
|
||||
* Removes the link between template of the sourceInstance and the template corresponding to targetTemplateId.
|
||||
|
||||
@@ -583,7 +583,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& linkTargetId,
|
||||
const TemplateId& linkSourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
const PrefabDomReference linkPatch,
|
||||
const PrefabDomConstReference linkPatches,
|
||||
const LinkId& linkId)
|
||||
{
|
||||
if (linkTargetId == InvalidTemplateId)
|
||||
@@ -667,9 +667,9 @@ namespace AzToolsFramework
|
||||
rapidjson::StringRef(PrefabDomUtils::SourceName), rapidjson::StringRef(sourceTemplate.GetFilePath().c_str()),
|
||||
newLink.GetLinkDom().GetAllocator());
|
||||
|
||||
if (linkPatch && linkPatch->get().IsArray() && !(linkPatch->get().Empty()))
|
||||
if (linkPatches && linkPatches->get().IsArray() && !(linkPatches->get().Empty()))
|
||||
{
|
||||
m_instanceToTemplatePropagator.AddPatchesToLink(linkPatch.value(), newLink);
|
||||
m_instanceToTemplatePropagator.AddPatchesToLink(linkPatches.value(), newLink);
|
||||
}
|
||||
|
||||
//update the target template dom to have the proper values for the source template dom
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& linkTargetId,
|
||||
const TemplateId& linkSourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
const PrefabDomReference linkPatch,
|
||||
const PrefabDomConstReference linkPatches,
|
||||
const LinkId& linkId = InvalidLinkId) override;
|
||||
|
||||
/**
|
||||
|
||||
+3
-3
@@ -43,9 +43,9 @@ namespace AzToolsFramework
|
||||
PrefabDomValue::MemberIterator& instanceIterator, InstanceOptionalReference instance) = 0;
|
||||
|
||||
//creates a new Link
|
||||
virtual LinkId CreateLink(const TemplateId& linkTargetId, const TemplateId& linkSourceId,
|
||||
const InstanceAlias& instanceAlias, const PrefabDomReference linkPatch,
|
||||
const LinkId& linkId = InvalidLinkId) = 0;
|
||||
virtual LinkId CreateLink(
|
||||
const TemplateId& linkTargetId, const TemplateId& linkSourceId, const InstanceAlias& instanceAlias,
|
||||
const PrefabDomConstReference linkPatches, const LinkId& linkId = InvalidLinkId) = 0;
|
||||
|
||||
virtual void RemoveLink(const LinkId& linkId) = 0;
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkPatches,
|
||||
PrefabDom linkPatches,
|
||||
const LinkId linkId)
|
||||
{
|
||||
m_targetId = targetId;
|
||||
@@ -132,10 +132,7 @@ namespace AzToolsFramework
|
||||
m_instanceAlias = instanceAlias;
|
||||
m_linkId = linkId;
|
||||
|
||||
if (linkPatches.has_value())
|
||||
{
|
||||
m_linkPatches = AZStd::move(linkPatches->get());
|
||||
}
|
||||
m_linkPatches = AZStd::move(linkPatches);
|
||||
|
||||
//if linkId is invalid, set as ADD
|
||||
if (m_linkId == InvalidLinkId)
|
||||
@@ -228,7 +225,7 @@ namespace AzToolsFramework
|
||||
|
||||
if (link.has_value())
|
||||
{
|
||||
m_linkDomPrevious = AZStd::move(link->get().GetLinkDom());
|
||||
m_linkDomPrevious.CopyFrom(link->get().GetLinkDom(), m_linkDomPrevious.GetAllocator());
|
||||
}
|
||||
|
||||
//get source templateDom
|
||||
@@ -275,7 +272,7 @@ namespace AzToolsFramework
|
||||
if (patchesIter == m_linkDomNext.MemberEnd())
|
||||
{
|
||||
m_linkDomNext.AddMember(
|
||||
rapidjson::GenericStringRef(PrefabDomUtils::PatchesName), patchLinkCopy, m_linkDomNext.GetAllocator());
|
||||
rapidjson::GenericStringRef(PrefabDomUtils::PatchesName), AZStd::move(patchLinkCopy), m_linkDomNext.GetAllocator());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -303,9 +300,7 @@ namespace AzToolsFramework
|
||||
return;
|
||||
}
|
||||
|
||||
PrefabDom moveLink;
|
||||
moveLink.CopyFrom(linkDom, linkDom.GetAllocator());
|
||||
link->get().GetLinkDom() = AZStd::move(moveLink);
|
||||
link->get().SetLinkDom(linkDom);
|
||||
|
||||
//propagate the link changes
|
||||
link->get().UpdateTarget();
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace AzToolsFramework
|
||||
const TemplateId& targetId,
|
||||
const TemplateId& sourceId,
|
||||
const InstanceAlias& instanceAlias,
|
||||
PrefabDomReference linkPatches = PrefabDomReference(),
|
||||
PrefabDom linkPatches = PrefabDom(),
|
||||
const LinkId linkId = InvalidLinkId);
|
||||
|
||||
void Undo() override;
|
||||
|
||||
@@ -34,11 +34,11 @@ namespace AzToolsFramework
|
||||
}
|
||||
|
||||
LinkId CreateLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDom patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkAddUndo = aznew PrefabUndoInstanceLink("Create Link");
|
||||
linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, patch, InvalidLinkId);
|
||||
linkAddUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, AZStd::move(patch), InvalidLinkId);
|
||||
linkAddUndo->SetParent(undoBatch);
|
||||
linkAddUndo->Redo();
|
||||
|
||||
@@ -47,10 +47,10 @@ namespace AzToolsFramework
|
||||
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch)
|
||||
PrefabDom linkPatches, UndoSystem::URSequencePoint* undoBatch)
|
||||
{
|
||||
auto linkRemoveUndo = aznew PrefabUndoInstanceLink("Remove Link");
|
||||
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, linkPatches, linkId);
|
||||
linkRemoveUndo->Capture(targetTemplateId, sourceTemplateId, instanceAlias, AZStd::move(linkPatches), linkId);
|
||||
linkRemoveUndo->SetParent(undoBatch);
|
||||
linkRemoveUndo->Redo();
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace AzToolsFramework
|
||||
const Instance& instance, AZStd::string_view undoMessage, const PrefabDom& instanceDomBeforeUpdate,
|
||||
UndoSystem::URSequencePoint* undoBatch);
|
||||
LinkId CreateLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDomReference patch,
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, PrefabDom patch,
|
||||
const InstanceAlias& instanceAlias, UndoSystem::URSequencePoint* undoBatch);
|
||||
void RemoveLink(
|
||||
TemplateId sourceTemplateId, TemplateId targetTemplateId, const InstanceAlias& instanceAlias, LinkId linkId,
|
||||
PrefabDomReference linkPatches, UndoSystem::URSequencePoint* undoBatch);
|
||||
PrefabDom linkPatches, UndoSystem::URSequencePoint* undoBatch);
|
||||
}
|
||||
} // namespace Prefab
|
||||
} // namespace AzToolsFramework
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace UnitTest
|
||||
|
||||
//create an undo node to apply the patch and prep for undo
|
||||
PrefabUndoInstanceLink undoInstanceLinkNode("Undo Link Patch");
|
||||
undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], patch, InvalidLinkId);
|
||||
undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], AZStd::move(patch), InvalidLinkId);
|
||||
undoInstanceLinkNode.Redo();
|
||||
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace UnitTest
|
||||
|
||||
//create an undo node to apply the patch and prep for undo
|
||||
PrefabUndoInstanceLink undoInstanceLinkNode("Undo Link Patch");
|
||||
undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], linkPatch, InvalidLinkId);
|
||||
undoInstanceLinkNode.Capture(rootTemplateId, nestedTemplateId, aliases[0], AZStd::move(linkPatch), InvalidLinkId);
|
||||
undoInstanceLinkNode.Redo();
|
||||
m_instanceUpdateExecutorInterface->UpdateTemplateInstancesInQueue();
|
||||
|
||||
|
||||
@@ -16,12 +16,23 @@
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
#include <AzToolsFramework/Thumbnails/ThumbnailerNullComponent.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
// SerializeContextTools is a full ToolsApplication that will load a project's Gem DLLs and initialize the system components.
|
||||
// This level of initialization is required to get all the serialization contexts and asset handlers registered, so that when
|
||||
// data transformations take place, none of the data is dropped due to not being recognized.
|
||||
// However, as a simplification, anything requiring Python or Qt is skipped during initialization:
|
||||
// - The gem_autoload.serializecontexttools.setreg file disables autoload for QtForPython, EditorPythonBindings, and PythonAssetBuilder
|
||||
// - The system component initialization below uses ThumbnailerNullComponent so that other components relying on a ThumbnailService
|
||||
// can still be started up, but the thumbnail service itself won't do anything. The real ThumbnailerComponent uses Qt, which is why
|
||||
// it isn't used.
|
||||
|
||||
namespace SerializeContextTools
|
||||
{
|
||||
Application::Application(int argc, char** argv)
|
||||
: AZ::ComponentApplication(argc, argv)
|
||||
: AzToolsFramework::ToolsApplication(&argc, &argv)
|
||||
{
|
||||
AZ::IO::FixedMaxPath projectPath = AZ::Utils::GetProjectPath();
|
||||
if (projectPath.empty())
|
||||
@@ -51,14 +62,27 @@ namespace AZ
|
||||
else
|
||||
{
|
||||
AZ::SettingsRegistryInterface::Specializations projectSpecializations{ projectName };
|
||||
AZ::IO::PathView configFilenameStem = m_configFilePath.Stem();
|
||||
if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Editor"))
|
||||
|
||||
// If a project specialization has been passed in via the command line, use it.
|
||||
if (size_t specializationCount = m_commandLine.GetNumSwitchValues("specializations"); specializationCount > 0)
|
||||
{
|
||||
projectSpecializations.Append("editor");
|
||||
for (size_t specializationIndex = 0; specializationIndex < specializationCount; ++specializationIndex)
|
||||
{
|
||||
projectSpecializations.Append(m_commandLine.GetSwitchValue("specializations", specializationIndex));
|
||||
}
|
||||
}
|
||||
else if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Game"))
|
||||
// Otherwise, if a config file was passed in, auto-set the specialization based on the config file name.
|
||||
else
|
||||
{
|
||||
projectSpecializations.Append(projectName + "_GameLauncher");
|
||||
AZ::IO::PathView configFilenameStem = m_configFilePath.Stem();
|
||||
if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Editor"))
|
||||
{
|
||||
projectSpecializations.Append("editor");
|
||||
}
|
||||
else if (AZ::StringFunc::Equal(configFilenameStem.Native(), "Game"))
|
||||
{
|
||||
projectSpecializations.Append(projectName + "_GameLauncher");
|
||||
}
|
||||
}
|
||||
|
||||
// Used the project specializations to merge the build dependencies *.setreg files
|
||||
@@ -78,5 +102,14 @@ namespace AZ
|
||||
AZ::ComponentApplication::SetSettingsRegistrySpecializations(specializations);
|
||||
specializations.Append("serializecontexttools");
|
||||
}
|
||||
|
||||
AZ::ComponentTypeList Application::GetRequiredSystemComponents() const
|
||||
{
|
||||
// Use all of the default system components, but also add in the ThumbnailerNullComponent so that components requiring
|
||||
// a ThumbnailService can still be started up.
|
||||
AZ::ComponentTypeList components = AzToolsFramework::ToolsApplication::GetRequiredSystemComponents();
|
||||
components.emplace_back(azrtti_typeid<AzToolsFramework::Thumbnailer::ThumbnailerNullComponent>());
|
||||
return components;
|
||||
}
|
||||
} // namespace SerializeContextTools
|
||||
} // namespace AZ
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzToolsFramework/Application/ToolsApplication.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -20,13 +20,14 @@ namespace AZ
|
||||
namespace SerializeContextTools
|
||||
{
|
||||
class Application final
|
||||
: public AZ::ComponentApplication
|
||||
: public AzToolsFramework::ToolsApplication
|
||||
{
|
||||
public:
|
||||
Application(int argc, char** argv);
|
||||
~Application() override = default;
|
||||
|
||||
const char* GetConfigFilePath() const;
|
||||
AZ::ComponentTypeList GetRequiredSystemComponents() const override;
|
||||
|
||||
protected:
|
||||
void SetSettingsRegistrySpecializations(AZ::SettingsRegistryInterface::Specializations& specializations) override;
|
||||
|
||||
@@ -29,4 +29,6 @@ ly_add_target(
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::AzCore
|
||||
AZ::AzFramework
|
||||
AZ::AzToolsFramework
|
||||
)
|
||||
|
||||
@@ -236,7 +236,6 @@ namespace AZ::SerializeContextTools
|
||||
AZ::IO::MemoryStream stream(data.data(), fileLength);
|
||||
|
||||
ObjectStream::FilterDescriptor filter;
|
||||
filter.m_flags = ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES;
|
||||
// Never load dependencies. That's another file that would need to be processed
|
||||
// separately from this one.
|
||||
filter.m_assetCB = AZ::Data::AssetFilterNoAssetLoading;
|
||||
|
||||
@@ -23,6 +23,8 @@ void PrintHelp()
|
||||
AZ_Printf("Help", "Serialize Context Tool\n");
|
||||
AZ_Printf("Help", " <action> [-config] <action arguments>*\n");
|
||||
AZ_Printf("Help", " [opt] -config=<path>: optional path to application's config file. Default is 'config/editor.xml'.\n");
|
||||
AZ_Printf("Help", " [opt] -specializations=<prefix>: <comma or semicolon>-separated list of optional Registry project\n");
|
||||
AZ_Printf("Help", " specializations, such as 'editor' or 'game' or 'editor;test'. Default is none. \n");
|
||||
AZ_Printf("Help", "\n");
|
||||
AZ_Printf("Help", " 'help': Print this help\n");
|
||||
AZ_Printf("Help", " example: 'help'\n");
|
||||
@@ -81,11 +83,7 @@ int main(int argc, char** argv)
|
||||
bool result = false;
|
||||
Application application(argc, argv);
|
||||
AZ::ComponentApplication::StartupParameters startupParameters;
|
||||
startupParameters.m_loadDynamicModules = false;
|
||||
application.Create({}, startupParameters);
|
||||
// Load the DynamicModules after the Application starts to prevent Gem System Components
|
||||
// from activating
|
||||
application.LoadDynamicModules();
|
||||
application.Start({}, startupParameters);
|
||||
|
||||
const AZ::CommandLine* commandLine = application.GetAzCommandLine();
|
||||
if (commandLine->GetNumMiscValues() < 1)
|
||||
|
||||
@@ -23,7 +23,9 @@ namespace AZ
|
||||
{
|
||||
public:
|
||||
|
||||
void TrackAssetLoad(const FeatureProcessorHandle handle, const AZ::Data::AssetId asset)
|
||||
using MaterialAssetPtr = AZ::Data::Asset<AZ::RPI::MaterialAsset>;
|
||||
|
||||
void TrackAssetLoad(const FeatureProcessorHandle handle, const MaterialAssetPtr asset)
|
||||
{
|
||||
if (IsAssetLoading(handle))
|
||||
{
|
||||
@@ -77,12 +79,12 @@ namespace AZ
|
||||
{
|
||||
const auto asset = EraseFromInFlightHandles(handle);
|
||||
|
||||
AZ_Assert(m_inFlightHandlesByAsset.count(asset) > 0, "AsyncLoadTracker in a bad state");
|
||||
auto& handleList = m_inFlightHandlesByAsset[asset];
|
||||
AZ_Assert(m_inFlightHandlesByAsset.count(asset.GetId()) > 0, "AsyncLoadTracker in a bad state");
|
||||
auto& handleList = m_inFlightHandlesByAsset[asset.GetId()];
|
||||
EraseFromVector(handleList, handle);
|
||||
if (handleList.empty())
|
||||
{
|
||||
m_inFlightHandlesByAsset.erase(asset);
|
||||
m_inFlightHandlesByAsset.erase(asset.GetId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,14 +106,14 @@ namespace AZ
|
||||
vec.pop_back();
|
||||
}
|
||||
|
||||
void Add(const FeatureProcessorHandle handle, const AZ::Data::AssetId asset)
|
||||
void Add(const FeatureProcessorHandle handle, const MaterialAssetPtr asset)
|
||||
{
|
||||
AZ_Assert(m_inFlightHandles.count(handle) == 0, "AsyncLoadTracker::Add() - told to add a handle that was already being tracked.");
|
||||
m_inFlightHandlesByAsset[asset].push_back(handle);
|
||||
m_inFlightHandlesByAsset[asset.GetId()].push_back(handle);
|
||||
m_inFlightHandles[handle] = asset;
|
||||
}
|
||||
|
||||
AZ::Data::AssetId EraseFromInFlightHandles(const FeatureProcessorHandle handle)
|
||||
MaterialAssetPtr EraseFromInFlightHandles(const FeatureProcessorHandle handle)
|
||||
{
|
||||
const auto iter = m_inFlightHandles.find(handle);
|
||||
AZ_Assert(iter != m_inFlightHandles.end(), "Told to remove handle that was not present");
|
||||
@@ -125,7 +127,7 @@ namespace AZ
|
||||
|
||||
// Hash table that tracks the reverse of the m_inFlightHandlesByAsset hash table.
|
||||
// i.e. for each object, it stores what asset that it needs.
|
||||
AZStd::unordered_map<FeatureProcessorHandle, AZ::Data::AssetId> m_inFlightHandles;
|
||||
AZStd::unordered_map<FeatureProcessorHandle, MaterialAssetPtr> m_inFlightHandles;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@ namespace AZ
|
||||
|
||||
m_decalData.Clear();
|
||||
m_decalBufferHandler.Release();
|
||||
m_materialAssets.clear();
|
||||
}
|
||||
|
||||
DecalTextureArrayFeatureProcessor::DecalHandle DecalTextureArrayFeatureProcessor::AcquireDecal()
|
||||
@@ -410,7 +409,7 @@ namespace AZ
|
||||
int iter = m_textureArrayList.begin();
|
||||
while (iter != -1)
|
||||
{
|
||||
const auto packedTexture = m_textureArrayList[iter].second.GetPackedTexture();
|
||||
const auto& packedTexture = m_textureArrayList[iter].second.GetPackedTexture();
|
||||
view->GetShaderResourceGroup()->SetImage(m_decalTextureArrayIndices[iter], packedTexture);
|
||||
iter = m_textureArrayList.next(iter);
|
||||
}
|
||||
@@ -482,22 +481,15 @@ namespace AZ
|
||||
return material;
|
||||
}
|
||||
|
||||
void DecalTextureArrayFeatureProcessor::QueueMaterialLoadForDecal(const AZ::Data::AssetId material, const DecalHandle handle)
|
||||
void DecalTextureArrayFeatureProcessor::QueueMaterialLoadForDecal(const AZ::Data::AssetId materialId, const DecalHandle handle)
|
||||
{
|
||||
// Note that another decal might have already queued this material for loading
|
||||
if (m_materialLoadTracker.IsAssetLoading(material))
|
||||
{
|
||||
m_materialLoadTracker.TrackAssetLoad(handle, material);
|
||||
return;
|
||||
}
|
||||
const auto materialAsset = QueueMaterialAssetLoad(materialId);
|
||||
|
||||
const auto materialAsset = QueueMaterialAssetLoad(material);
|
||||
m_materialAssets.emplace(material, materialAsset);
|
||||
m_materialLoadTracker.TrackAssetLoad(handle, material);
|
||||
m_materialLoadTracker.TrackAssetLoad(handle, materialAsset);
|
||||
|
||||
if (materialAsset.IsLoading())
|
||||
{
|
||||
AZ::Data::AssetBus::MultiHandler::BusConnect(material);
|
||||
AZ::Data::AssetBus::MultiHandler::BusConnect(materialId);
|
||||
}
|
||||
else if (materialAsset.IsReady())
|
||||
{
|
||||
|
||||
@@ -136,11 +136,8 @@ namespace AZ
|
||||
GpuBufferHandler m_decalBufferHandler;
|
||||
|
||||
AsyncLoadTracker<DecalHandle> m_materialLoadTracker;
|
||||
|
||||
AZStd::unordered_map< AZ::Data::AssetId, DecalLocationAndUseCount> m_materialToTextureArrayLookupTable;
|
||||
|
||||
AZStd::unordered_map<AZ::Data::AssetId, AZ::Data::Asset<AZ::RPI::MaterialAsset>> m_materialAssets;
|
||||
|
||||
bool m_deviceBufferNeedsUpdate = false;
|
||||
};
|
||||
} // namespace Render
|
||||
|
||||
+3
@@ -10,6 +10,9 @@
|
||||
#
|
||||
|
||||
set(LY_RUNTIME_DEPENDENCIES
|
||||
Gem::Atom_RHI_Vulkan.Private
|
||||
Gem::Atom_RHI_DX12.Private
|
||||
Gem::Atom_RHI_Metal.Private
|
||||
Gem::Atom_RHI_Vulkan.Builders
|
||||
Gem::Atom_RHI_DX12.Builders
|
||||
Gem::Atom_RHI_Metal.Builders
|
||||
|
||||
+3
@@ -10,6 +10,9 @@
|
||||
#
|
||||
|
||||
set(LY_RUNTIME_DEPENDENCIES
|
||||
Gem::Atom_RHI_Metal.Private
|
||||
Gem::Atom_RHI_Vulkan.Private
|
||||
Gem::Atom_RHI_DX12.Private
|
||||
Gem::Atom_RHI_Metal.Builders
|
||||
Gem::Atom_RHI_Vulkan.Builders
|
||||
Gem::Atom_RHI_DX12.Builders
|
||||
|
||||
+3
@@ -10,6 +10,9 @@
|
||||
#
|
||||
|
||||
set(LY_RUNTIME_DEPENDENCIES
|
||||
Gem::Atom_RHI_Vulkan.Private
|
||||
Gem::Atom_RHI_DX12.Private
|
||||
Gem::Atom_RHI_Metal.Private
|
||||
Gem::Atom_RHI_Vulkan.Builders
|
||||
Gem::Atom_RHI_DX12.Builders
|
||||
Gem::Atom_RHI_Metal.Builders
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"Amazon": {
|
||||
"Gems": {
|
||||
"QtForPython.Editor": {
|
||||
"AutoLoad": false
|
||||
},
|
||||
"EditorPythonBindings.Editor": {
|
||||
"AutoLoad": false
|
||||
},
|
||||
"PythonAssetBuilder.Editor": {
|
||||
"AutoLoad": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ def check_exact_match(line, expected_line):
|
||||
|
||||
# Look for either start of line or whitespace, then the expected_line, then either end of the line or whitespace.
|
||||
# This way we don't partial match inside of a string. So for example, 'foo' matches 'foo bar' but not 'foobar'
|
||||
regex_pattern = re.compile("(^|\\s){}($|\\s)".format(re.escape(expected_line)))
|
||||
regex_pattern = re.compile("(^|\\s){}($|\\s)".format(re.escape(expected_line)), re.UNICODE)
|
||||
if regex_pattern.search(line) is not None:
|
||||
return expected_line
|
||||
|
||||
@@ -125,7 +125,7 @@ class LogMonitor(object):
|
||||
self.py_log = ""
|
||||
try:
|
||||
logger.debug("Monitoring log file in '{}' ".format(self.log_file_path))
|
||||
with open(self.log_file_path, mode='r') as log:
|
||||
with open(self.log_file_path, mode='r', encoding='utf-8') as log:
|
||||
logger.info(
|
||||
"Monitoring log file '{}' for '{}' seconds".format(self.log_file_path, timeout))
|
||||
|
||||
|
||||
@@ -98,6 +98,16 @@ class TestLogMonitor(object):
|
||||
under_test = ly_test_tools.log.log_monitor.check_exact_match(line, expected_line)
|
||||
assert under_test == expected_line
|
||||
|
||||
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
|
||||
def test_Monitor_UTF8StringsPresentAndExpected_Success(self):
|
||||
mock_file = io.StringIO('gr\xc3\xb6\xc3\x9feren pr\xc3\xbcfung \xd1\x82\xd0\xb5\xd1\x81\xd1\x82\xd1\x83\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8f\n\xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99\n\xc3\x85lpha\xc3\x9fravo\xc3\xa7harlie\n')
|
||||
mock_launcher.is_alive.side_effect = [True, True, True, False]
|
||||
|
||||
with mock.patch('ly_test_tools.log.log_monitor.open', return_value=mock_file, create=True):
|
||||
mock_log_monitor().monitor_log_for_lines(['gr\xc3\xb6\xc3\x9feren pr\xc3\xbcfung \xd1\x82\xd0\xb5\xd1\x81\xd1\x82\xd1\x83\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xbd\xd1\x8f',
|
||||
'\xc3\x80\xc3\x88\xc3\x8c\xc3\x92\xc3\x99',
|
||||
'\xc3\x85lpha\xc3\x9fravo\xc3\xa7harlie'])
|
||||
|
||||
@mock.patch('os.path.exists', mock.MagicMock(return_value=True))
|
||||
def test_Monitor_AllLinesFound_Success(self):
|
||||
mock_file = io.StringIO(u'a\nb\nc\n')
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION": "debug",
|
||||
"OUTPUT_DIRECTORY": "build/ios",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "ALL_BUILD",
|
||||
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
|
||||
@@ -44,7 +44,7 @@
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION": "profile",
|
||||
"OUTPUT_DIRECTORY": "build/ios",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "ALL_BUILD",
|
||||
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
|
||||
@@ -60,7 +60,7 @@
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION": "profile",
|
||||
"OUTPUT_DIRECTORY": "build/ios",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=FALSE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "ALL_BUILD",
|
||||
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
|
||||
@@ -94,7 +94,7 @@
|
||||
"PARAMETERS": {
|
||||
"CONFIGURATION": "release",
|
||||
"OUTPUT_DIRECTORY": "build/ios",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"!WORKSPACE!/home\" -DO3DE_REGISTER_ENGINE_PATH=\"!WORKSPACE!/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_OPTIONS": "-G Xcode -DCMAKE_TOOLCHAIN_FILE=cmake/Platform/iOS/Toolchain_ios.cmake -DLY_MONOLITHIC_GAME=TRUE -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=FALSE -DLY_IOS_CODE_SIGNING_IDENTITY=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS=\"\" -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=FALSE -DLY_UNITY_BUILD=TRUE -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
|
||||
"CMAKE_LY_PROJECTS": "AutomatedTesting",
|
||||
"CMAKE_TARGET": "ALL_BUILD",
|
||||
"CMAKE_NATIVE_BUILD_ARGS": "-destination generic/platform=iOS"
|
||||
|
||||
@@ -38,7 +38,7 @@ then
|
||||
./aws/install
|
||||
rm -rf ./aws
|
||||
else
|
||||
AWS_CLI_VERSION=`aws --version | awk '{print $1}' | awk -F/ '{print $2}'`
|
||||
AWS_CLI_VERSION=$(aws --version | awk '{print $1}' | awk -F/ '{print $2}')
|
||||
echo AWS CLI \(version $AWS_CLI_VERSION\) already installed
|
||||
fi
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`"
|
||||
UBUNTU_DISTRO="$(lsb_release -c | awk '{print $2}')"
|
||||
if [ "$UBUNTU_DISTRO" == "bionic" ]
|
||||
then
|
||||
echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)"
|
||||
@@ -53,7 +53,7 @@ fi
|
||||
# will install it from the bionic distro manually into focal. This is needed since Ubuntu 20.04 supports
|
||||
# python 3.8 out of the box, but we are using 3.7
|
||||
#
|
||||
LIBFFI6_COUNT=`apt list --installed 2>/dev/null | grep libffi6 | wc -l`
|
||||
LIBFFI6_COUNT=$(apt list --installed 2>/dev/null | grep libffi6 | wc -l)
|
||||
if [ "$UBUNTU_DISTRO" == "focal" ] && [ $LIBFFI6_COUNT -eq 0 ]
|
||||
then
|
||||
echo "Installing libffi for Ubuntu 20.04"
|
||||
@@ -90,7 +90,7 @@ fi
|
||||
# Add the kitware repository for cmake if necessary
|
||||
#
|
||||
|
||||
KITWARE_REPO_COUNT=`cat /etc/apt/sources.list | grep ^deb | grep https://apt.kitware.com/ubuntu/ | wc -l`
|
||||
KITWARE_REPO_COUNT=$(cat /etc/apt/sources.list | grep ^deb | grep https://apt.kitware.com/ubuntu/ | wc -l)
|
||||
|
||||
if [ $KITWARE_REPO_COUNT -eq 0 ]
|
||||
then
|
||||
@@ -121,33 +121,34 @@ PACKAGE_FILE_LIST=package-list.ubuntu-$UBUNTU_DISTRO.txt
|
||||
echo Reading package list $PACKAGE_FILE_LIST
|
||||
|
||||
# Read each line (strip out comment tags)
|
||||
for LINE in `cat $PACKAGE_FILE_LIST | sed 's/#.*$//g'`
|
||||
for PREPROC_LINE in $(cat $PACKAGE_FILE_LIST | sed 's/#.*$//g')
|
||||
do
|
||||
PACKAGE=`echo $LINE | awk -F / '{print $1}'`
|
||||
LINE=$(echo $PREPROC_LINE | tr -d '\r\n')
|
||||
PACKAGE=$(echo $LINE | awk -F / '{$1=$1;print $1}')
|
||||
if [ "$PACKAGE" != "" ] # Skip blank lines
|
||||
then
|
||||
PACKAGE_VER=`echo $LINE | awk -F / '{print $2}'`
|
||||
PACKAGE_VER=$(echo $LINE | awk -F / '{$2=$2;print $2}')
|
||||
if [ "$PACKAGE_VER" == "" ]
|
||||
then
|
||||
# Process non-versioned packages
|
||||
INSTALLED_COUNT=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l`
|
||||
INSTALLED_COUNT=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l)
|
||||
if [ $INSTALLED_COUNT -eq 0 ]
|
||||
then
|
||||
echo Installing $PACKAGE
|
||||
apt-get install $PACKAGE -y
|
||||
else
|
||||
INSTALLED_VERSION=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}'`
|
||||
INSTALLED_VERSION=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}')
|
||||
echo $PACKAGE already installed \(version $INSTALLED_VERSION\)
|
||||
fi
|
||||
else
|
||||
# Process versioned packages
|
||||
INSTALLED_COUNT=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l`
|
||||
INSTALLED_COUNT=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | wc -l)
|
||||
if [ $INSTALLED_COUNT -eq 0 ]
|
||||
then
|
||||
echo Installing $PACKAGE \( $PACKAGE_VER \)
|
||||
apt-get install $PACKAGE=$PACKAGE_VER -y
|
||||
else
|
||||
INSTALLED_VERSION=`apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}'`
|
||||
INSTALLED_VERSION=$(apt list --installed 2>/dev/null | grep ^$PACKAGE/ | awk '{print $2}')
|
||||
if [ "$INSTALLED_VERSION" != "$PACKAGE_VER" ]
|
||||
then
|
||||
echo $PACKAGE already installed but with the wrong version. Purging the package
|
||||
|
||||
@@ -26,7 +26,7 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
UBUNTU_DISTRO="`lsb_release -c | awk '{print $2}'`"
|
||||
UBUNTU_DISTRO="$(lsb_release -c | awk '{print $2}')"
|
||||
if [ "$UBUNTU_DISTRO" == "bionic" ]
|
||||
then
|
||||
echo "Setup for Ubuntu 18.04 LTS ($UBUNTU_DISTRO)"
|
||||
@@ -49,14 +49,14 @@ then
|
||||
apt-get update
|
||||
apt-get install git -y
|
||||
else
|
||||
GIT_VERSION=`git --version | awk '{print $3}'`
|
||||
GIT_VERSION=$(git --version | awk '{print $3}')
|
||||
echo Git $GIT_VERSION already Installed. Skipping Git installation
|
||||
fi
|
||||
|
||||
#
|
||||
# Setup Git-LFS if needed
|
||||
#
|
||||
GIT_LFS_PACKAGE_COUNT=`apt list --installed 2>/dev/null | grep git-lfs/ | wc -l`
|
||||
GIT_LFS_PACKAGE_COUNT=$(apt list --installed 2>/dev/null | grep git-lfs/ | wc -l)
|
||||
if [ $GIT_LFS_PACKAGE_COUNT -eq 0 ]
|
||||
then
|
||||
echo Setting up Git-LFS
|
||||
@@ -87,7 +87,7 @@ then
|
||||
dpkg -i $GCM_PACKAGE_NAME
|
||||
popd
|
||||
else
|
||||
GCM_VERSION=`git-credential-manager-core --version`
|
||||
GCM_VERSION=$(git-credential-manager-core --version)
|
||||
echo Git Credential Manager \(GCM\) version $GCM_VERSION already installed. Skipping GCM installation
|
||||
fi
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
|
||||
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
# its licensors.
|
||||
#
|
||||
# For complete copyright and license terms please see the LICENSE at the root of this
|
||||
# distribution (the "License"). All use of this software is governed by the License,
|
||||
# or, if provided, by the license below or the license accompanying this file. Do not
|
||||
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
# This script must be run as root
|
||||
if [[ $EUID -ne 0 ]]
|
||||
then
|
||||
echo "This script must be run as root (sudo)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Installing packages and tools for O3DE development
|
||||
|
||||
# Install awscli
|
||||
./install-ubuntu-awscli.sh
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo Error installing AWSCLI
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Install git
|
||||
./install-ubuntu-git.sh
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo Error installing Git
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install the necessary build tools
|
||||
./install-ubuntu-build-tools.sh
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo Error installing ubuntu tools
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
echo Packages and tools for O3DE setup complete
|
||||
exit 0
|
||||
Reference in New Issue
Block a user