diff --git a/Assets/Editor/Prefabs/Default_Level.prefab b/Assets/Editor/Prefabs/Default_Level.prefab
new file mode 100644
index 0000000000..fb82c5ab03
--- /dev/null
+++ b/Assets/Editor/Prefabs/Default_Level.prefab
@@ -0,0 +1,666 @@
+{
+ "Source": "Default_Level.prefab",
+ "ContainerEntity": {
+ "Id": "Entity_[1146574390643]",
+ "Name": "Level",
+ "Components": {
+ "Component_[10641544592923449938]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 10641544592923449938
+ },
+ "Component_[12039882709170782873]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 12039882709170782873
+ },
+ "Component_[12265484671603697631]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 12265484671603697631
+ },
+ "Component_[14126657869720434043]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 14126657869720434043
+ },
+ "Component_[15230859088967841193]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 15230859088967841193,
+ "Parent Entity": "",
+ "Cached World Transform Parent": ""
+ },
+ "Component_[16239496886950819870]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 16239496886950819870
+ },
+ "Component_[5688118765544765547]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 5688118765544765547
+ },
+ "Component_[6545738857812235305]": {
+ "$type": "SelectionComponent",
+ "Id": 6545738857812235305
+ },
+ "Component_[7247035804068349658]": {
+ "$type": "EditorPrefabComponent",
+ "Id": 7247035804068349658
+ },
+ "Component_[9307224322037797205]": {
+ "$type": "EditorLockComponent",
+ "Id": 9307224322037797205
+ },
+ "Component_[9562516168917670048]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9562516168917670048
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entities": {
+ "Entity_[1155164325235]": {
+ "Id": "Entity_[1155164325235]",
+ "Name": "Sun",
+ "Components": {
+ "Component_[10440557478882592717]": {
+ "$type": "SelectionComponent",
+ "Id": 10440557478882592717
+ },
+ "Component_[13620450453324765907]": {
+ "$type": "EditorLockComponent",
+ "Id": 13620450453324765907
+ },
+ "Component_[2134313378593666258]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 2134313378593666258
+ },
+ "Component_[234010807770404186]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 234010807770404186
+ },
+ "Component_[2970359110423865725]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 2970359110423865725
+ },
+ "Component_[3722854130373041803]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3722854130373041803
+ },
+ "Component_[5992533738676323195]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5992533738676323195
+ },
+ "Component_[7378860763541895402]": {
+ "$type": "AZ::Render::EditorDirectionalLightComponent",
+ "Id": 7378860763541895402,
+ "Controller": {
+ "Configuration": {
+ "Intensity": 1.0,
+ "CameraEntityId": "",
+ "ShadowFilterMethod": 1,
+ "ShadowmapSize": "Size1024",
+ "Pcf Method": 1
+ }
+ }
+ },
+ "Component_[7892834440890947578]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 7892834440890947578,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ 0.0,
+ 0.0,
+ 13.487043380737305
+ ],
+ "Rotate": [
+ -76.13099670410156,
+ -0.847000002861023,
+ -15.8100004196167
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 9.442070960998536
+ ],
+ "Rotation": [
+ -0.6098860502243042,
+ -0.09055805951356888,
+ -0.10376212745904924,
+ 0.7804304361343384
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1176639161715]"
+ },
+ "Component_[8599729549570828259]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 8599729549570828259
+ },
+ "Component_[952797371922080273]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 952797371922080273
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1159459292531]": {
+ "Id": "Entity_[1159459292531]",
+ "Name": "Ground",
+ "Components": {
+ "Component_[11701138785793981042]": {
+ "$type": "SelectionComponent",
+ "Id": 11701138785793981042
+ },
+ "Component_[12260880513256986252]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 12260880513256986252
+ },
+ "Component_[13711420870643673468]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 13711420870643673468
+ },
+ "Component_[138002849734991713]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 138002849734991713
+ },
+ "Component_[16578565737331764849]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 16578565737331764849,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1176639161715]"
+ },
+ "Component_[16919232076966545697]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 16919232076966545697
+ },
+ "Component_[5182430712893438093]": {
+ "$type": "EditorMaterialComponent",
+ "Id": 5182430712893438093,
+ "materialSlots": [
+ {
+ "id": {
+ "materialAssetId": {
+ "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
+ "subId": 803645540
+ }
+ }
+ }
+ ],
+ "materialSlotsByLod": [
+ [
+ {
+ "id": {
+ "lodIndex": 0,
+ "materialAssetId": {
+ "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
+ "subId": 803645540
+ }
+ }
+ }
+ ]
+ ]
+ },
+ "Component_[5675108321710651991]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 5675108321710651991,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{935F694A-8639-515B-8133-81CDC7948E5B}",
+ "subId": 277333723
+ },
+ "assetHint": "objects/groudplane/groundplane_521x521m.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[5681893399601237518]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5681893399601237518
+ },
+ "Component_[592692962543397545]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 592692962543397545
+ },
+ "Component_[7090012899106946164]": {
+ "$type": "EditorLockComponent",
+ "Id": 7090012899106946164
+ },
+ "Component_[9410832619875640998]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 9410832619875640998
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1163754259827]": {
+ "Id": "Entity_[1163754259827]",
+ "Name": "Camera",
+ "Components": {
+ "Component_[11895140916889160460]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11895140916889160460
+ },
+ "Component_[16880285896855930892]": {
+ "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+ "Id": 16880285896855930892,
+ "Controller": {
+ "Configuration": {
+ "Field of View": 55.0,
+ "EditorEntityId": 8929576024571800510
+ }
+ }
+ },
+ "Component_[17187464423780271193]": {
+ "$type": "EditorLockComponent",
+ "Id": 17187464423780271193
+ },
+ "Component_[17495696818315413311]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 17495696818315413311
+ },
+ "Component_[18086214374043522055]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 18086214374043522055,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Translate": [
+ -2.300000190734864,
+ -3.9368600845336916,
+ 1.0
+ ],
+ "Rotate": [
+ -2.050307512283325,
+ 1.9552897214889529,
+ -43.62335586547852
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ -11.904647827148438,
+ 13.392678260803223,
+ -3.0449724197387697
+ ],
+ "Rotation": [
+ -0.02294669672846794,
+ 0.00919158011674881,
+ -0.37172695994377139,
+ 0.9280129671096802
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1176639161715]"
+ },
+ "Component_[18387556550380114975]": {
+ "$type": "SelectionComponent",
+ "Id": 18387556550380114975
+ },
+ "Component_[2654521436129313160]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 2654521436129313160
+ },
+ "Component_[5265045084611556958]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5265045084611556958
+ },
+ "Component_[7169798125182238623]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7169798125182238623
+ },
+ "Component_[8866210352157164042]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 8866210352157164042
+ },
+ "Component_[9129253381063760879]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 9129253381063760879
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1168049227123]": {
+ "Id": "Entity_[1168049227123]",
+ "Name": "Grid",
+ "Components": {
+ "Component_[11443347433215807130]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 11443347433215807130
+ },
+ "Component_[11779275529534764488]": {
+ "$type": "SelectionComponent",
+ "Id": 11779275529534764488
+ },
+ "Component_[14249419413039427459]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14249419413039427459
+ },
+ "Component_[15448581635946161318]": {
+ "$type": "AZ::Render::EditorGridComponent",
+ "Id": 15448581635946161318,
+ "Controller": {
+ "Configuration": {
+ "primarySpacing": 4.0,
+ "primaryColor": [
+ 0.501960813999176,
+ 0.501960813999176,
+ 0.501960813999176
+ ],
+ "secondarySpacing": 0.5,
+ "secondaryColor": [
+ 0.250980406999588,
+ 0.250980406999588,
+ 0.250980406999588
+ ]
+ }
+ }
+ },
+ "Component_[1843303322527297409]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 1843303322527297409
+ },
+ "Component_[380249072065273654]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 380249072065273654,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1176639161715]"
+ },
+ "Component_[7476660583684339787]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 7476660583684339787
+ },
+ "Component_[7557626501215118375]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 7557626501215118375
+ },
+ "Component_[7984048488947365511]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 7984048488947365511
+ },
+ "Component_[8118181039276487398]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 8118181039276487398
+ },
+ "Component_[9189909764215270515]": {
+ "$type": "EditorLockComponent",
+ "Id": 9189909764215270515
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1172344194419]": {
+ "Id": "Entity_[1172344194419]",
+ "Name": "Shader Ball",
+ "Components": {
+ "Component_[10789351944715265527]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 10789351944715265527
+ },
+ "Component_[12037033284781049225]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 12037033284781049225
+ },
+ "Component_[13759153306105970079]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 13759153306105970079
+ },
+ "Component_[14135560884830586279]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14135560884830586279
+ },
+ "Component_[16247165675903986673]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 16247165675903986673
+ },
+ "Component_[18082433625958885247]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 18082433625958885247
+ },
+ "Component_[6472623349872972660]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6472623349872972660,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Transform Data": {
+ "Rotate": [
+ 0.0,
+ 0.10000000149011612,
+ 180.0
+ ]
+ },
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.0
+ ],
+ "Rotation": [
+ 0.0008726645028218627,
+ 0.0,
+ 0.9999996423721314,
+ 0.0
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1176639161715]"
+ },
+ "Component_[6495255223970673916]": {
+ "$type": "AZ::Render::EditorMeshComponent",
+ "Id": 6495255223970673916,
+ "Controller": {
+ "Configuration": {
+ "ModelAsset": {
+ "assetId": {
+ "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
+ "subId": 281415304
+ },
+ "assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
+ }
+ }
+ }
+ },
+ "Component_[8056625192494070973]": {
+ "$type": "SelectionComponent",
+ "Id": 8056625192494070973
+ },
+ "Component_[8550141614185782969]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 8550141614185782969
+ },
+ "Component_[9439770997198325425]": {
+ "$type": "EditorLockComponent",
+ "Id": 9439770997198325425
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1176639161715]": {
+ "Id": "Entity_[1176639161715]",
+ "Name": "Atom Default Environment",
+ "Components": {
+ "Component_[10757302973393310045]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 10757302973393310045,
+ "Parent Entity": "Entity_[1146574390643]",
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1146574390643]"
+ },
+ "Component_[14505817420424255464]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 14505817420424255464,
+ "ComponentOrderEntryArray": [
+ {
+ "ComponentId": 10757302973393310045
+ }
+ ]
+ },
+ "Component_[14988041764659020032]": {
+ "$type": "EditorLockComponent",
+ "Id": 14988041764659020032
+ },
+ "Component_[15808690248755038124]": {
+ "$type": "SelectionComponent",
+ "Id": 15808690248755038124
+ },
+ "Component_[15900837685796817138]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 15900837685796817138
+ },
+ "Component_[3298767348226484884]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 3298767348226484884
+ },
+ "Component_[4076975109609220594]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 4076975109609220594
+ },
+ "Component_[5679760548946028854]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 5679760548946028854
+ },
+ "Component_[5855590796136709437]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 5855590796136709437,
+ "ChildEntityOrderEntryArray": [
+ {
+ "EntityId": "Entity_[1155164325235]"
+ },
+ {
+ "EntityId": "Entity_[1180934129011]",
+ "SortIndex": 1
+ },
+ {
+ "EntityId": "Entity_[1172344194419]",
+ "SortIndex": 2
+ },
+ {
+ "EntityId": "Entity_[1168049227123]",
+ "SortIndex": 3
+ },
+ {
+ "EntityId": "Entity_[1163754259827]",
+ "SortIndex": 4
+ },
+ {
+ "EntityId": "Entity_[1159459292531]",
+ "SortIndex": 5
+ }
+ ]
+ },
+ "Component_[9277695270015777859]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 9277695270015777859
+ }
+ },
+ "IsDependencyReady": true
+ },
+ "Entity_[1180934129011]": {
+ "Id": "Entity_[1180934129011]",
+ "Name": "Global Sky",
+ "Components": {
+ "Component_[11231930600558681245]": {
+ "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+ "Id": 11231930600558681245,
+ "Controller": {
+ "Configuration": {
+ "CubemapAsset": {
+ "assetId": {
+ "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+ "subId": 1000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[11980494120202836095]": {
+ "$type": "SelectionComponent",
+ "Id": 11980494120202836095
+ },
+ "Component_[1428633914413949476]": {
+ "$type": "EditorLockComponent",
+ "Id": 1428633914413949476
+ },
+ "Component_[14936200426671614999]": {
+ "$type": "AZ::Render::EditorImageBasedLightComponent",
+ "Id": 14936200426671614999,
+ "Controller": {
+ "Configuration": {
+ "diffuseImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 3000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+ },
+ "specularImageAsset": {
+ "assetId": {
+ "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+ "subId": 2000
+ },
+ "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+ }
+ }
+ }
+ },
+ "Component_[14994774102579326069]": {
+ "$type": "EditorDisabledCompositionComponent",
+ "Id": 14994774102579326069
+ },
+ "Component_[15417479889044493340]": {
+ "$type": "EditorPendingCompositionComponent",
+ "Id": 15417479889044493340
+ },
+ "Component_[15826613364991382688]": {
+ "$type": "EditorEntitySortComponent",
+ "Id": 15826613364991382688
+ },
+ "Component_[1665003113283562343]": {
+ "$type": "EditorOnlyEntityComponent",
+ "Id": 1665003113283562343
+ },
+ "Component_[3704934735944502280]": {
+ "$type": "EditorEntityIconComponent",
+ "Id": 3704934735944502280
+ },
+ "Component_[5698542331457326479]": {
+ "$type": "EditorVisibilityComponent",
+ "Id": 5698542331457326479
+ },
+ "Component_[6644513399057217122]": {
+ "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+ "Id": 6644513399057217122,
+ "Parent Entity": "Entity_[1176639161715]",
+ "Cached World Transform": {
+ "Translation": [
+ 0.0,
+ 0.0,
+ 0.0
+ ]
+ },
+ "Cached World Transform Parent": "Entity_[1176639161715]"
+ },
+ "Component_[931091830724002070]": {
+ "$type": "EditorInspectorComponent",
+ "Id": 931091830724002070
+ }
+ },
+ "IsDependencyReady": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Gem/Code/tool_dependencies.cmake b/AutomatedTesting/Gem/Code/tool_dependencies.cmake
index e2e57d4012..1d70c02b1c 100644
--- a/AutomatedTesting/Gem/Code/tool_dependencies.cmake
+++ b/AutomatedTesting/Gem/Code/tool_dependencies.cmake
@@ -12,7 +12,7 @@
# Extracted from Editor.xml
set(GEM_DEPENDENCIES
Gem::Maestro.Editor
- Gem::TextureAtlas
+ Gem::TextureAtlas.Editor
Gem::LmbrCentral.Editor
Gem::LyShine.Editor
Gem::HttpRequestor
diff --git a/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl b/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl
index 079c70c878..537d3e5c83 100644
--- a/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl
+++ b/Code/Framework/AzCore/AzCore/RTTI/AzStdOnDemandReflection.inl
@@ -1020,29 +1020,60 @@ namespace AZ
}
};
- /// OnDemand reflection for AZStd::set
+
+ template
+ class Iterator_VM>
+ {
+ public:
+ using ContainerType = AZStd::unordered_set;
+ using IteratorType = typename ContainerType::iterator;
+ Iterator_VM(ContainerType& container)
+ : m_iterator(container.begin())
+ , m_end(container.end())
+ {}
+
+ const t_Key& GetKeyUnchecked() const
+ {
+ return *m_iterator;
+ }
+
+ bool IsNotAtEnd() const
+ {
+ return m_iterator != m_end;
+ }
+
+ t_Key& ModValueUnchecked()
+ {
+ return *m_iterator;
+ }
+
+ void Next()
+ {
+ ++m_iterator;
+ }
+
+ private:
+ IteratorType m_iterator;
+ IteratorType m_end;
+ };
+
+ /// OnDemand reflection for AZStd::unordered_set
template
struct OnDemandReflection< AZStd::unordered_set >
{
using ContainerType = AZStd::unordered_set;
using KeyListType = AZStd::vector;
- static AZ::Outcome Erase(ContainerType& thisMap, Key& key)
+ using ValueIteratorType = Iterator_VM;
+
+ static bool EraseCheck_VM(ContainerType& thisSet, Key& key)
{
- const auto result = thisMap.erase(key);
- if (result)
- {
- return AZ::Success();
- }
- else
- {
- return AZ::Failure();
- }
+ return thisSet.erase(key) != 0;
}
- static void Insert(ContainerType& thisSet, Key& key)
+ static ContainerType& ErasePost_VM(ContainerType& thisSet, [[maybe_unused]] Key&)
{
- thisSet.insert(key);
+ return thisSet;
}
static KeyListType GetKeys(ContainerType& thisSet)
@@ -1055,6 +1086,17 @@ namespace AZ
return keys;
}
+ static ContainerType& Insert(ContainerType& thisSet, Key& key)
+ {
+ thisSet.insert(key);
+ return thisSet;
+ }
+
+ static ValueIteratorType Iterate_VM(ContainerType& thisContainer)
+ {
+ return ValueIteratorType(thisContainer);
+ }
+
static void Swap(ContainerType& thisSet, ContainerType& otherSet)
{
thisSet.swap(otherSet);
@@ -1064,33 +1106,68 @@ namespace AZ
{
if (BehaviorContext* behaviorContext = azrtti_cast(context))
{
+ BranchOnResultInfo emptyBranchInfo;
+ emptyBranchInfo.m_returnResultInBranches = true;
+ emptyBranchInfo.m_trueToolTip = "The container is empty";
+ emptyBranchInfo.m_falseToolTip = "The container is not empty";
+
auto ContainsTransparent = [](const ContainerType& containerType, typename ContainerType::key_type& key)->bool
{
return containerType.contains(key);
};
+ ExplicitOverloadInfo explicitOverloadInfo;
behaviorContext->Class()
- ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
+ ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
->Attribute(AZ::ScriptCanvasAttributes::PrettyName, ScriptCanvasOnDemandReflection::OnDemandPrettyName::Get(*behaviorContext))
->Attribute(AZ::Script::Attributes::ToolTip, ScriptCanvasOnDemandReflection::OnDemandToolTip::Get(*behaviorContext))
->Attribute(AZ::Script::Attributes::Category, ScriptCanvasOnDemandReflection::OnDemandCategoryName::Get(*behaviorContext))
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn)
->Method("BucketCount", static_cast(&ContainerType::bucket_count))
- ->Method("Erase", &Erase)
- ->Method("Empty", [](ContainerType& thisSet)->bool { return thisSet.empty(); })
+ ->Method("Empty", static_cast(&ContainerType::empty), { { { "Container", "The container to check if it is empty", nullptr, {} } } })
+ ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Is Empty", "Containers"))
+ ->Attribute(AZ::ScriptCanvasAttributes::BranchOnResult, emptyBranchInfo)
+ ->Method("EraseCheck_VM", &EraseCheck_VM)
+ ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
+ ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
+ ->Method("Erase", &ErasePost_VM)
+ ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
+ ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Erase", "Containers"))
+ ->Attribute(AZ::ScriptCanvasAttributes::CheckedOperation, CheckedOperationInfo("EraseCheck_VM", {}, "Out", "Key Not Found", true))
+ ->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "" }, { "ContainerGroup" }))
->Method("contains", ContainsTransparent)
+ ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Has Key", "Containers"))
->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
->Method("Insert", &Insert)
+ ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
+ ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Insert", "Containers"))
+ ->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup", "", "" }, { "ContainerGroup" }))
->Method(k_sizeName, [](ContainerType* thisPtr) { return aznumeric_cast(thisPtr->size()); })
->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::Length)
->Method("GetKeys", &GetKeys)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::All)
+ ->Method("GetSize", [](ContainerType& thisPtr) { return aznumeric_cast(thisPtr.size()); })
+ ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Get Size", "Containers"))
+ ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
->Method("Reserve", static_cast(&ContainerType::reserve))
->Method("Swap", &Swap)
+ ->Method("Clear", [](ContainerType& thisContainer)->ContainerType& { thisContainer.clear(); return thisContainer; })
+ ->Attribute(AZ::Script::Attributes::TreatAsMemberFunction, AZ::AttributeIsValid::IfPresent)
+ ->Attribute(AZ::ScriptCanvasAttributes::ExplicitOverloadCrc, ExplicitOverloadInfo("Clear All Elements", "Containers"))
+ ->Attribute(AZ::ScriptCanvasAttributes::OverloadArgumentGroup, AZ::OverloadArgumentGroupInfo({ "ContainerGroup" }, { "ContainerGroup" }))
+ ->Method(k_iteratorConstructorName, &Iterate_VM)
+ ;
+
+ behaviorContext->Class()
+ ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::ListOnly)
+ ->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::ScriptOwn)
+ ->Method(k_iteratorGetKeyName, &ValueIteratorType::GetKeyUnchecked)
+ ->Method(k_iteratorModValueName, &ValueIteratorType::ModValueUnchecked)
+ ->Method(k_iteratorIsNotAtEndName, &ValueIteratorType::IsNotAtEnd)
+ ->Method(k_iteratorNextName, &ValueIteratorType::Next)
;
}
}
-
};
template <>
diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp
index 635d160434..31a2cfc09e 100644
--- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp
+++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContext.cpp
@@ -165,7 +165,7 @@ namespace AZ
if (HasResult() != overload->HasResult())
{
- AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all");
+ AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str());
return false;
}
@@ -176,7 +176,7 @@ namespace AZ
if (!(methodResult->m_typeId == overloadResult->m_typeId && methodResult->m_traits == overloadResult->m_traits))
{
- AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all");
+ AZ_Error("Reflection", false, "Overload failure, all methods must have the same result, or none at all: %s", m_name.c_str());
return false;
}
}
@@ -575,7 +575,7 @@ namespace AZ
}
else
{
- AZ_Error("BehaviorContext", false, "safety check declared for method %s but it was not found in the class");
+ AZ_Error("BehaviorContext", false, "Method: %s, declared safety check: %s, but it was not found in class: %s", method.m_name.c_str(), m_name.c_str(), checkedOperationInfo.m_safetyCheckName.c_str());
}
}
}
diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp
index c64b86ae0f..f6aac0fa16 100644
--- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp
+++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.cpp
@@ -34,10 +34,17 @@ namespace BehaviorContextUtilitiesCPP
using argument_type = const BehaviorParameter*;
using result_type = size_t;
result_type operator()(const argument_type& value) const
- {
- result_type result = AZStd::hash()(value->m_typeId);
- AZStd::hash_combine(result, CleanTraits(value->m_traits));
- return result;
+ {
+ if (value)
+ {
+ result_type result = AZStd::hash()(value->m_typeId);
+ AZStd::hash_combine(result, CleanTraits(value->m_traits));
+ return result;
+ }
+ else
+ {
+ return 0;
+ }
}
};
@@ -45,7 +52,11 @@ namespace BehaviorContextUtilitiesCPP
{
bool operator()(const BehaviorParameter* left, const BehaviorParameter* right) const
{
- return left->m_typeId == right->m_typeId && CleanTraits(left->m_traits) == CleanTraits(right->m_traits);
+ return (left == nullptr && right == nullptr)
+ || (left != nullptr
+ && right != nullptr
+ && left->m_typeId == right->m_typeId
+ && CleanTraits(left->m_traits) == CleanTraits(right->m_traits));
}
};
@@ -137,7 +148,7 @@ namespace AZ
for (size_t argIndex = 0, argSentinel = overload.GetNumArguments(); argIndex < argSentinel; ++argIndex)
{
auto overloadedArgIter = variance.m_input.find(argIndex);
- if (overloadedArgIter != variance.m_input.end())
+ if (overloadedArgIter != variance.m_input.end() && overloadedArgIter->second[overloadIndex])
{
// if this doesn't work try the type name
overloadName += ReplaceCppArtifacts(overloadedArgIter->second[overloadIndex]->m_name);
@@ -185,16 +196,24 @@ namespace AZ
{
auto argument = overloads[overloadIndex].first->GetArgument(0);
- const bool isThisPointer
- = (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0
- || AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes);
+ if (argument)
+ {
+ const bool isThisPointer
+ = (argument->m_traits & AZ::BehaviorParameter::Traits::TR_THIS_PTR) != 0
+ || AZ::FindAttribute(AZ::Script::Attributes::TreatAsMemberFunction, overloads[overloadIndex].first->m_attributes);
- oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer;
+ oneArgIsThisPointer = oneArgIsThisPointer || isThisPointer;
+ }
types.insert(argument);
stripedArgs.emplace_back(argument);
}
+ if (types.size() == overloads.size())
+ {
+ variance.m_unambiguousInput.insert(0);
+ }
+
if (types.size() > 1 && (onThis == VariantOnThis::Yes || !oneArgIsThisPointer))
{
variance.m_input.insert(AZStd::make_pair(0, stripedArgs));
@@ -210,11 +229,15 @@ namespace AZ
for (size_t overloadIndex = 0, overloadSentinel = overloads.size(); overloadIndex < overloadSentinel; ++overloadIndex)
{
auto argument = overloads[overloadIndex].first->GetArgument(argIndex);
-
types.insert(argument);
stripedArgs.emplace_back(argument);
}
+ if (types.size() == overloads.size())
+ {
+ variance.m_unambiguousInput.insert(0);
+ }
+
if (types.size() > 1)
{
variance.m_input.insert(AZStd::make_pair(argIndex, stripedArgs));
diff --git a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h
index 4663635cdf..0dc9ecc969 100644
--- a/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h
+++ b/Code/Framework/AzCore/AzCore/RTTI/BehaviorContextUtilities.h
@@ -27,6 +27,8 @@ namespace AZ
struct OverloadVariance
{
AZStd::unordered_map> m_input;
+ // the indices of inputs that make selection of overload unambiguous
+ AZStd::unordered_set m_unambiguousInput;
AZStd::vector m_output;
};
diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
index ac1e61a5aa..9bf6247e97 100644
--- a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
+++ b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp
@@ -2048,10 +2048,6 @@ LUA_API const Node* lua_getDummyNode()
return true;
}
- else
- {
- AZ_Warning("Script", false, "Index %d is not a function!", functionIndex);
- }
return false;
}
@@ -2078,7 +2074,6 @@ LUA_API const Node* lua_getDummyNode()
}
else
{
- AZ_Warning("Script", lua_isnil(m_nativeContext, -1), "Name %s exists but is not a function!", functionName);
lua_pop(m_nativeContext, 1);
}
@@ -5888,7 +5883,6 @@ LUA_API const Node* lua_getDummyNode()
else
{
lua_pop(m_impl->m_lua, 1);
- AZ_Warning("Script", false, "%s is not a function!", functionName);
}
return false;
}
@@ -5906,7 +5900,6 @@ LUA_API const Node* lua_getDummyNode()
else
{
lua_pop(m_impl->m_lua, 1);
- AZ_Warning("Script", false, "CacheIndex %d is not a function!", cachedIndex);
}
return false;
}
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp
index 93d12acba3..9c4641741e 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp
@@ -10,6 +10,7 @@
*
*/
+#include "AzCore/RTTI/TypeInfo.h"
#include
#include
#include
@@ -61,6 +62,13 @@ namespace AZ
if (classData->m_azRtti && classData->m_azRtti->GetGenericTypeId() != typeId)
{
+ if (((classData->m_azRtti->GetTypeTraits() & (AZ::TypeTraits::is_signed | AZ::TypeTraits::is_unsigned)) != AZ::TypeTraits{0}) &&
+ context.GetSerializeContext()->GetUnderlyingTypeId(typeId) == classData->m_typeId)
+ {
+ // This value is from an enum, where a field has been reflected using ClassBuilder::Field, but the enum
+ // type itself has not been reflected using EnumBuilder. Treat it as an enum.
+ return LoadEnum(object, *classData, value, context);
+ }
serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId());
if (serializer)
{
@@ -77,21 +85,18 @@ namespace AZ
{
return LoadEnum(object, *classData, value, context);
}
- else if (classData->m_container)
+ if (classData->m_container)
{
return context.Report(Tasks::ReadField, Outcomes::Unsupported,
"The Json Serializer uses custom serializers to load containers. If this message is encountered "
"then a serializer for the target containers is missing, isn't registered or doesn't exist.");
}
- else if (value.IsObject())
+ if (value.IsObject())
{
return LoadClass(object, *classData, value, context);
}
- else
- {
- return context.Report(Tasks::ReadField, Outcomes::Unsupported,
- AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name));
- }
+ return context.Report(Tasks::ReadField, Outcomes::Unsupported,
+ AZStd::string::format("Reading into targets of type '%s' is not supported.", classData->m_name));
}
JsonSerializationResult::ResultCode JsonDeserializer::LoadToPointer(void* object, const Uuid& typeId,
@@ -233,8 +238,16 @@ namespace AZ
AZ::TypeId underlyingTypeId = AZ::TypeId::CreateNull();
if (!attributeReader.Read(underlyingTypeId))
{
- return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
- "Unable to find underlying type of enum in class data.");
+ // for non-reflected enums, the passed-in classData already represents the enum's underlying type
+ if (context.GetSerializeContext()->GetUnderlyingTypeId(classData.m_typeId) == classData.m_typeId)
+ {
+ underlyingTypeId = classData.m_typeId;
+ }
+ else
+ {
+ return context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
+ "Unable to find underlying type of enum in class data.");
+ }
}
const SerializeContext::ClassData* underlyingClassData = context.GetSerializeContext()->FindClassData(underlyingTypeId);
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h
index b01dbe9b0d..ae313632af 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases.h
@@ -21,7 +21,7 @@ namespace JsonSerializationTests
{
using JsonSerializationTestCases = ::testing::Types<
// Structures
- SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper,
+ SimpleClass, SimpleInheritence, MultipleInheritence, SimpleNested, SimpleEnumWrapper, NonReflectedEnumWrapper,
// Pointers
SimpleNullPointer, SimpleAssignedPointer, ComplexAssignedPointer, ComplexNullInheritedPointer,
ComplexAssignedDifferentInheritedPointer, ComplexAssignedSameInheritedPointer,
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp
index 5be031d70a..6da3120f59 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.cpp
@@ -373,6 +373,57 @@ namespace JsonSerializationTests
return MakeInstanceWithoutDefaults(AZStd::move(instance), json);
}
+ // NonReflectedEnumWrapper
+ bool NonReflectedEnumWrapper::Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const
+ {
+ return !fullReflection || (m_enumClass == rhs.m_enumClass && m_rawEnum== rhs.m_rawEnum);
+ }
+
+ void NonReflectedEnumWrapper::Reflect(AZStd::unique_ptr& context, bool fullReflection)
+ {
+ if (fullReflection)
+ {
+ // Note that the enums are not reflected using context->Enum<>
+
+ context->Class()
+ ->Field("enumClass", &NonReflectedEnumWrapper::m_enumClass)
+ ->Field("rawEnum", &NonReflectedEnumWrapper::m_rawEnum);
+ }
+ }
+
+ InstanceWithSomeDefaults NonReflectedEnumWrapper::GetInstanceWithSomeDefaults()
+ {
+ auto instance = AZStd::make_unique();
+ instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2;
+
+ const char* strippedDefaults = R"(
+ {
+ "enumClass": 2
+ })";
+ const char* keptDefaults = R"(
+ {
+ "enumClass": 2,
+ "rawEnum": 0
+ })";
+
+ return MakeInstanceWithSomeDefaults(AZStd::move(instance),
+ strippedDefaults, keptDefaults);
+ }
+
+ InstanceWithoutDefaults NonReflectedEnumWrapper::GetInstanceWithoutDefaults()
+ {
+ auto instance = AZStd::make_unique();
+ instance->m_enumClass = NonReflectedEnumWrapper::SimpleEnumClass::Option2;
+ instance->m_rawEnum = NonReflectedEnumWrapper::SimpleRawEnum::RawOption1;
+
+ const char* json = R"(
+ {
+ "enumClass": 2,
+ "rawEnum": 1
+ })";
+ return MakeInstanceWithoutDefaults(AZStd::move(instance), json);
+ }
+
// TemplatedClass
bool TemplatedClass::Equals(const TemplatedClass& rhs, bool fullReflection) const
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h
index db5db23fba..1830ca9e6f 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/TestCases_Classes.h
@@ -134,6 +134,35 @@ namespace JsonSerializationTests
SimpleRawEnum m_rawEnum{};
};
+ struct NonReflectedEnumWrapper
+ {
+ enum class SimpleEnumClass
+ {
+ Option1 = 1,
+ Option2,
+ };
+ enum SimpleRawEnum
+ {
+ RawOption1 = 1,
+ RawOption2,
+ };
+ AZ_CLASS_ALLOCATOR(NonReflectedEnumWrapper, AZ::SystemAllocator, 0);
+ AZ_RTTI(NonReflectedEnumWrapper, "{A80D5B6B-2FD1-46E9-A7A9-44C5E2650526}");
+
+ static constexpr bool SupportsPartialDefaults = true;
+
+ NonReflectedEnumWrapper() = default;
+ virtual ~NonReflectedEnumWrapper() = default;
+
+ bool Equals(const NonReflectedEnumWrapper& rhs, bool fullReflection) const;
+ static void Reflect(AZStd::unique_ptr& context, bool fullReflection);
+ static InstanceWithSomeDefaults GetInstanceWithSomeDefaults();
+ static InstanceWithoutDefaults GetInstanceWithoutDefaults();
+
+ SimpleEnumClass m_enumClass{};
+ SimpleRawEnum m_rawEnum{};
+ };
+
template
struct TemplatedClass
{
@@ -158,5 +187,7 @@ namespace AZ
{
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleEnumClass, "{AF6F1964-5B20-4689-BF23-F36B9C9AAE6A}");
AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::SimpleEnumWrapper::SimpleRawEnum, "{EB24207F-B48F-4D8B-940D-3CD06A371739}");
+ AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleEnumClass, "{E80E4A41-B29E-4B7C-B630-3B599172C837}");
+ AZ_TYPE_INFO_SPECIALIZE(JsonSerializationTests::NonReflectedEnumWrapper::SimpleRawEnum, "{C42AF28D-4F84-4540-972A-5B6EEFAB13FF}");
AZ_TYPE_INFO_TEMPLATE(JsonSerializationTests::TemplatedClass, "{CA4ADF74-66E7-4D16-B4AC-F71278C60EC7}", AZ_TYPE_INFO_TYPENAME);
}
diff --git a/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp b/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp
index 985bc4665d..bdbfe6197f 100644
--- a/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp
+++ b/Code/Framework/AzFramework/AzFramework/ProjectManager/ProjectManager.cpp
@@ -99,51 +99,18 @@ namespace AzFramework::ProjectManager
AZ::AllocatorInstance::Create();
}
{
- const char projectsScript[] = "projects.py";
+ AZStd::string filename = "o3de";
+ AZ::IO::FixedMaxPath executablePath = AZ::Utils::GetExecutableDirectory();
+ executablePath /= filename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION;
- AZ_Warning("ProjectManager", false, "No project provided - launching project selector.");
-
- if (engineRootPath.empty())
+ if (!AZ::IO::SystemFile::Exists(executablePath.c_str()))
{
- AZ_Error("ProjectManager", false, "Couldn't find engine root");
+ AZ_Error("ProjectManager", false, "%s not found", executablePath.c_str());
return false;
}
- auto projectManagerPath = engineRootPath / "scripts" / "project_manager";
-
- if (!AZ::IO::SystemFile::Exists((projectManagerPath / projectsScript).c_str()))
- {
- AZ_Error("ProjectManager", false, "%s not found at %s!", projectsScript, projectManagerPath.c_str());
- return false;
- }
- AZ::IO::FixedMaxPathString executablePath;
- AZ::Utils::GetExecutablePathReturnType result = AZ::Utils::GetExecutablePath(executablePath.data(), executablePath.capacity());
- if (result.m_pathStored != AZ::Utils::ExecutablePathResult::Success)
- {
- AZ_Error("ProjectManager", false, "Could not determine executable path!");
- return false;
- }
- AZ::IO::FixedMaxPath parentPath(executablePath.c_str());
- auto exeFolder = parentPath.ParentPath();
- AZStd::fixed_string<8> debugOption;
- auto lastSep = exeFolder.Native().find_last_of(AZ_CORRECT_FILESYSTEM_SEPARATOR);
- if (lastSep != AZStd::string_view::npos)
- {
- exeFolder = exeFolder.Native().substr(lastSep + 1);
- }
- if (exeFolder == "debug")
- {
- // We need to use the debug version of the python interpreter to load up our debug version of our libraries which work with the debug version of QT living in this folder
- debugOption = "debug ";
- }
- AZ::IO::FixedMaxPath pythonPath = engineRootPath / "python";
- pythonPath /= AZ_TRAIT_AZFRAMEWORK_PYTHON_SHELL;
- auto cmdPath = AZ::IO::FixedMaxPathString::format("%s %s%s --executable_path=%s --parent_pid=%" PRIu32, pythonPath.Native().c_str(),
- debugOption.c_str(), (projectManagerPath / projectsScript).c_str(), executablePath.c_str(), AZ::Platform::GetCurrentProcessId());
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
-
- processLaunchInfo.m_commandlineParameters = cmdPath;
- processLaunchInfo.m_showWindow = false;
+ processLaunchInfo.m_commandlineParameters = executablePath.String();
launchSuccess = AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
}
if (ownsSystemAllocator)
diff --git a/Code/Framework/AzNetworking/CMakeLists.txt b/Code/Framework/AzNetworking/CMakeLists.txt
index 0fe95441ce..c6673058d7 100644
--- a/Code/Framework/AzNetworking/CMakeLists.txt
+++ b/Code/Framework/AzNetworking/CMakeLists.txt
@@ -65,5 +65,12 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
ly_add_googletest(
NAME AZ::AzNetworking.Tests
)
+
+ ly_add_googletest(
+ NAME AZ::AzNetworking.Tests.Sandbox
+ TARGET AZ::AzNetworking.Tests
+ TEST_SUITE sandbox
+ )
+
endif()
diff --git a/Code/Framework/AzNetworking/Tests/TcpTransport/TcpTransportTests.cpp b/Code/Framework/AzNetworking/Tests/TcpTransport/TcpTransportTests.cpp
index eed12e1881..7cc3af5a51 100644
--- a/Code/Framework/AzNetworking/Tests/TcpTransport/TcpTransportTests.cpp
+++ b/Code/Framework/AzNetworking/Tests/TcpTransport/TcpTransportTests.cpp
@@ -129,7 +129,7 @@ namespace UnitTest
#if AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
TEST_F(TcpTransportTests, DISABLED_TestSingleClient)
#else
- TEST_F(TcpTransportTests, TestSingleClient)
+ TEST_F(TcpTransportTests, SUITE_sandbox_TestSingleClient)
#endif // AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
{
TestTcpServer testServer;
@@ -157,7 +157,7 @@ namespace UnitTest
#if AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
TEST_F(TcpTransportTests, DISABLED_TestMultipleClients)
#else
- TEST_F(TcpTransportTests, TestMultipleClients)
+ TEST_F(TcpTransportTests, SUITE_sandbox_TestMultipleClients)
#endif // AZ_TRAIT_DISABLE_FAILED_NETWORKING_TESTS
{
constexpr uint32_t NumTestClients = 50;
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
index da529d9349..97c3041de6 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.cpp
@@ -14,9 +14,11 @@
#include
#include
#include
+#include
#include
#include
#include
+#include
#include
#include
#include
@@ -222,21 +224,52 @@ namespace AzToolsFramework
AzToolsFramework::Prefab::TemplateId templateId = m_prefabSystemComponent->GetTemplateIdFromFilePath(relativePath);
m_rootInstance->SetTemplateSourcePath(relativePath);
+
+ bool newLevelFromTemplate = false;
+
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
{
- // This has not been loaded yet, this is the case of being saved with a different name.
- // Create it
- m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
- HandleEntitiesAdded({m_rootInstance->m_containerEntity.get()});
+ AZStd::string watchFolder;
+ AZ::Data::AssetInfo assetInfo;
+ bool sourceInfoFound = false;
+ AzToolsFramework::AssetSystemRequestBus::BroadcastResult(
+ sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, DefaultLevelTemplateName,
+ assetInfo, watchFolder);
- AzToolsFramework::Prefab::PrefabDom dom;
- bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
- if (!success)
+ if (sourceInfoFound)
{
- AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
- return false;
+ AZStd::string fullPath;
+ AZ::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), fullPath);
+
+ // Get the default prefab and copy the Dom over to the new template being saved
+ Prefab::TemplateId defaultId = m_loaderInterface->LoadTemplateFromFile(fullPath.c_str());
+ Prefab::PrefabDom& dom = m_prefabSystemComponent->FindTemplateDom(defaultId);
+
+ Prefab::PrefabDom levelDefaultDom;
+ levelDefaultDom.CopyFrom(dom, levelDefaultDom.GetAllocator());
+
+ Prefab::PrefabDomPath sourcePath("/Source");
+ sourcePath.Set(levelDefaultDom, relativePath.c_str());
+
+ templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(levelDefaultDom));
+ newLevelFromTemplate = true;
}
- templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
+ else
+ {
+ // Create an empty level since we couldn't find the default template
+ m_rootInstance->m_containerEntity->AddComponent(aznew Prefab::EditorPrefabComponent());
+ HandleEntitiesAdded({ m_rootInstance->m_containerEntity.get() });
+
+ AzToolsFramework::Prefab::PrefabDom dom;
+ bool success = AzToolsFramework::Prefab::PrefabDomUtils::StoreInstanceInPrefabDom(*m_rootInstance, dom);
+ if (!success)
+ {
+ AZ_Error("Prefab", false, "Failed to convert current root instance into a DOM when saving file '%.*s'", AZ_STRING_ARG(filename));
+ return false;
+ }
+ templateId = m_prefabSystemComponent->AddTemplate(relativePath, std::move(dom));
+ }
+
if (templateId == AzToolsFramework::Prefab::InvalidTemplateId)
{
AZ_Error("Prefab", false, "Couldn't add new template id '%i' when saving file '%.*s'", templateId, AZ_STRING_ARG(filename));
@@ -253,6 +286,13 @@ namespace AzToolsFramework
m_prefabSystemComponent->RemoveTemplate(prevTemplateId);
}
+ // If we have a new level from a template, we need to make sure to propagate the changes here otherwise
+ // the entities from the new template won't show up
+ if (newLevelFromTemplate)
+ {
+ m_prefabSystemComponent->PropagateTemplateChanges(templateId);
+ }
+
AZStd::string out;
if (m_loaderInterface->SaveTemplateToString(m_rootInstance->GetTemplateId(), out))
{
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h
index 3be9b95df0..606d5f495f 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Entity/PrefabEditorEntityOwnershipService.h
@@ -216,5 +216,7 @@ namespace AzToolsFramework
Prefab::PrefabLoaderInterface* m_loaderInterface;
AzFramework::EntityContextId m_entityContextId;
AZ::SerializeContext m_serializeContext;
+
+ static inline constexpr const char* DefaultLevelTemplateName = "Prefabs/Default_Level.prefab";
};
}
diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h
index 48b5148d3c..4cf6d077e7 100644
--- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h
+++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/PropertyEditor/GenericComboBoxCtrl.h
@@ -83,7 +83,7 @@ namespace AzToolsFramework
protected:
QWidget* GetFirstInTabOrder() override;
QWidget* GetLastInTabOrder() override;
- void UpdateTabOrder() override;
+ void UpdateTabOrder() override;
void onChildComboBoxValueChange(int comboBoxIndex) override;
@@ -93,7 +93,7 @@ namespace AzToolsFramework
void addElementImpl(const AZStd::pair& genericValue);
- QLabel* m_warningLabel = nullptr;
+ QLabel* m_warningLabel = nullptr;
DHQComboBox* m_pComboBox;
AZStd::vector> m_values;
AZ::AttributeFunction * m_postChangeNotifyCB{};
@@ -131,6 +131,11 @@ namespace AzToolsFramework
template
AzToolsFramework::PropertyHandlerBase* RegisterGenericComboBoxHandler()
{
+ if (!AzToolsFramework::PropertyTypeRegistrationMessages::Bus::FindFirstHandler())
+ {
+ return nullptr;
+ }
+
auto propertyHandler = aznew GenericComboBoxHandler();
AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, propertyHandler);
return propertyHandler;
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ShaderEnable.lua b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ShaderEnable.lua
index 69df610ab2..778edeea18 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ShaderEnable.lua
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardMultilayerPBR_ShaderEnable.lua
@@ -24,7 +24,7 @@ function Process(context)
local shadowMap = context:GetShaderByTag("Shadowmap")
local forwardPassEDS = context:GetShaderByTag("ForwardPass_EDS")
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
- local shadowMapWitPS = context:GetShaderByTag("Shadowmap_WithPS")
+ local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS")
local forwardPass = context:GetShaderByTag("ForwardPass")
local shadingAffectsDepth = parallaxEnabled and parallaxPdoEnabled;
@@ -34,6 +34,6 @@ function Process(context)
forwardPassEDS:SetEnabled(not shadingAffectsDepth)
depthPassWithPS:SetEnabled(shadingAffectsDepth)
- shadowMapWitPS:SetEnabled(shadingAffectsDepth)
+ shadowMapWithPS:SetEnabled(shadingAffectsDepth)
forwardPass:SetEnabled(shadingAffectsDepth)
end
diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua
index 2733713122..e502eb38f8 100644
--- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua
+++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ShaderEnable.lua
@@ -32,7 +32,7 @@ function Process(context)
local lowEndForwardEDS = context:GetShaderByTag("LowEndForward_EDS")
local depthPassWithPS = context:GetShaderByTag("DepthPass_WithPS")
- local shadowMapWitPS = context:GetShaderByTag("Shadowmap_WithPS")
+ local shadowMapWithPS = context:GetShaderByTag("Shadowmap_WithPS")
local forwardPass = context:GetShaderByTag("ForwardPass")
local lowEndForward = context:GetShaderByTag("LowEndForward")
@@ -43,7 +43,7 @@ function Process(context)
lowEndForwardEDS:SetEnabled(false)
depthPassWithPS:SetEnabled(true)
- shadowMapWitPS:SetEnabled(true)
+ shadowMapWithPS:SetEnabled(true)
forwardPass:SetEnabled(true)
lowEndForward:SetEnabled(true)
else
@@ -53,7 +53,7 @@ function Process(context)
lowEndForwardEDS:SetEnabled((opacityMode == OpacityMode_Opaque) or (opacityMode == OpacityMode_Blended) or (opacityMode == OpacityMode_TintedTransparent))
depthPassWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
- shadowMapWitPS:SetEnabled(opacityMode == OpacityMode_Cutout)
+ shadowMapWithPS:SetEnabled(opacityMode == OpacityMode_Cutout)
forwardPass:SetEnabled(opacityMode == OpacityMode_Cutout)
lowEndForward:SetEnabled(opacityMode == OpacityMode_Cutout)
end
diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp
index ade4b5b592..9b40097716 100644
--- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp
+++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.cpp
@@ -203,7 +203,7 @@ namespace AZ
if (m_shadowingLightHandle.IsValid())
{
uint32_t shadowFilterMethod = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_shadowFilterMethod;
- RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(AZ::Name{"o_directional_shadow_filtering_method"}, AZ::RPI::ShaderOptionValue{shadowFilterMethod});
+ RPI::ShaderSystemInterface::Get()->SetGlobalShaderOption(m_directionalShadowFilteringMethodName, AZ::RPI::ShaderOptionValue{shadowFilterMethod});
const uint32_t cascadeCount = m_shadowData.at(nullptr).GetData(m_shadowingLightHandle.GetIndex()).m_cascadeCount;
ShadowProperty& property = m_shadowProperties.GetData(m_shadowingLightHandle.GetIndex());
@@ -656,6 +656,7 @@ namespace AZ
CacheRenderPipelineIdsForPersistentView();
SetConfigurationToPasses();
SetCameraViewNameToPass();
+ UpdateViewsOfCascadeSegments();
}
void DirectionalLightFeatureProcessor::CacheCascadedShadowmapsPass() {
@@ -1344,6 +1345,15 @@ namespace AZ
}
}
+ void DirectionalLightFeatureProcessor::UpdateViewsOfCascadeSegments()
+ {
+ if (m_shadowingLightHandle.IsValid())
+ {
+ const uint16_t cascadeCount = GetCascadeCount(m_shadowingLightHandle);
+ UpdateViewsOfCascadeSegments(m_shadowingLightHandle, cascadeCount);
+ }
+ }
+
Aabb DirectionalLightFeatureProcessor::CalculateShadowViewAabb(
LightHandle handle,
const RPI::View* cameraView,
diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h
index a276ea3f3e..f8c00c859c 100644
--- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h
+++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DirectionalLightFeatureProcessor.h
@@ -296,6 +296,8 @@ namespace AZ
//! This updates the shadowmap view.
void UpdateShadowmapViews(LightHandle handle);
+ void UpdateViewsOfCascadeSegments();
+
//! This calculate shadow view AABB.
Aabb CalculateShadowViewAabb(
LightHandle handle,
@@ -372,6 +374,7 @@ namespace AZ
uint32_t m_shadowmapIndexTableBufferNameIndex = 0;
Name m_lightTypeName = Name("directional");
+ Name m_directionalShadowFilteringMethodName = Name("o_directional_shadow_filtering_method");
static constexpr const char* FeatureProcessorName = "DirectionalLightFeatureProcessor";
};
} // namespace Render
diff --git a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp
index 0a64c7b408..8e68c8cb44 100644
--- a/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp
+++ b/Gems/EMotionFX/Code/Source/Integration/System/SystemComponent.cpp
@@ -890,7 +890,7 @@ namespace EMotionFX
#if AZ_TRAIT_EMOTIONFX_MAIN_WINDOW_DETACHED
emotionFXWindowOptions.detachedWindow = true;
#endif
- emotionFXWindowOptions.optionalMenuText = "Animation Editor (PREVIEW)";
+ emotionFXWindowOptions.optionalMenuText = "Animation Editor";
EditorRequests::Bus::Broadcast(&EditorRequests::RegisterViewPane, EMStudio::MainWindow::GetEMotionFXPaneName(), LyViewPane::CategoryTools, emotionFXWindowOptions, windowCreationFunc);
}
diff --git a/Gems/LyShine/Code/CMakeLists.txt b/Gems/LyShine/Code/CMakeLists.txt
index 732bd1cfd4..796cb22292 100644
--- a/Gems/LyShine/Code/CMakeLists.txt
+++ b/Gems/LyShine/Code/CMakeLists.txt
@@ -86,7 +86,7 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
Gem::LyShine.Static
Legacy::CryCommon
Gem::LmbrCentral
- Gem::TextureAtlas
+ Gem::TextureAtlas.Editor
Gem::AtomToolsFramework.Static
Gem::AtomToolsFramework.Editor
${additional_dependencies}
@@ -118,10 +118,10 @@ if (PAL_TRAIT_BUILD_HOST_TOOLS)
AZ::AssetBuilderSDK
Gem::LyShine.Editor.Static
Gem::LmbrCentral
- Gem::TextureAtlas
+ Gem::TextureAtlas.Editor
RUNTIME_DEPENDENCIES
Gem::LmbrCentral.Editor
- Gem::TextureAtlas
+ Gem::TextureAtlas.Editor
)
endif()
@@ -176,7 +176,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED)
Legacy::CryCommon
AZ::AssetBuilderSDK
Gem::LmbrCentral
- Gem::TextureAtlas
+ Gem::TextureAtlas.Editor
Gem::LyShine.Editor.Static
)
ly_add_googletest(
diff --git a/Gems/LyShine/Code/Source/UiTextComponent.cpp b/Gems/LyShine/Code/Source/UiTextComponent.cpp
index 648013108b..72c36ed66d 100644
--- a/Gems/LyShine/Code/Source/UiTextComponent.cpp
+++ b/Gems/LyShine/Code/Source/UiTextComponent.cpp
@@ -40,6 +40,7 @@
#include "RenderGraph.h"
#include
+#include
namespace
{
@@ -1076,7 +1077,7 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname,
{
m_filepath = texturePathname;
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePath, m_filepath);
- m_texture = nullptr;
+ m_texture.reset();
m_size = AZ::Vector2(0.0f, 0.0f);
m_vAlign = vAlign;
m_yOffset = yOffset;
@@ -1094,24 +1095,11 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname,
else
{
// Load the texture
- uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
- ITexture* texture = gEnv->pRenderer->EF_LoadTexture(texturePathname.c_str(), loadTextureFlags);
-
- if (!texture || !texture->IsTextureLoaded())
+ m_texture = CDraw2d::LoadTexture(m_filepath);
+ if (m_texture)
{
- gEnv->pSystem->Warning(
- VALIDATOR_MODULE_SHINE,
- VALIDATOR_WARNING,
- VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
- texturePathname.c_str(),
- "No texture file found for image: %s. "
- "NOTE: File must be in current project or a gem.",
- texturePathname.c_str());
- }
- else
- {
- m_texture = texture;
- m_size = AZ::Vector2(static_cast(m_texture->GetWidth()), static_cast(m_texture->GetHeight()));
+ AZ::RHI::Size size = m_texture->GetDescriptor().m_size;
+ m_size = AZ::Vector2(size.m_width, size.m_height);
}
}
@@ -1127,17 +1115,6 @@ UiTextComponent::InlineImage::InlineImage(const AZStd::string& texturePathname,
////////////////////////////////////////////////////////////////////////////////////////////////////
UiTextComponent::InlineImage::~InlineImage()
{
- // In order to avoid the texture being deleted while there are still commands on the render
- // thread command queue that use it, we queue a command to delete the texture onto the
- // command queue.
-
- if (m_texture && !m_atlas)
- {
- SResourceAsync* pInfo = new SResourceAsync();
- pInfo->eClassName = eRCN_Texture;
- pInfo->pResource = m_texture;
- gEnv->pRenderer->ReleaseResourceAsync(pInfo);
- }
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1148,13 +1125,6 @@ bool UiTextComponent::InlineImage::OnAtlasLoaded(const TextureAtlasNamespace::Te
m_coordinates = atlas->GetAtlasCoordinates(m_filepath);
if (m_coordinates.GetWidth() > 0)
{
- if (m_texture)
- {
- SResourceAsync* pInfo = new SResourceAsync();
- pInfo->eClassName = eRCN_Texture;
- pInfo->pResource = m_texture;
- gEnv->pRenderer->ReleaseResourceAsync(pInfo);
- }
m_atlas = atlas;
m_texture = m_atlas->GetTexture();
return true;
@@ -1177,25 +1147,7 @@ bool UiTextComponent::InlineImage::OnAtlasUnloaded(const TextureAtlasNamespace::
else
{
// Load the texture
- uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
- ITexture* texture = gEnv->pRenderer->EF_LoadTexture(m_filepath.c_str(), loadTextureFlags);
-
- if (!texture || !texture->IsTextureLoaded())
- {
- gEnv->pSystem->Warning(
- VALIDATOR_MODULE_SHINE,
- VALIDATOR_WARNING,
- VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
- m_filepath.c_str(),
- "No texture file found for image: %s. "
- "NOTE: File must be in current project or a gem.",
- m_filepath.c_str());
- m_texture = nullptr;
- }
- else
- {
- m_texture = texture;
- }
+ m_texture = CDraw2d::LoadTexture(m_filepath);
}
return true;
}
@@ -1869,7 +1821,7 @@ void UiTextComponent::Render(LyShine::IRenderGraph* renderGraph)
UiTransformInterface::RectPointsArray rectPoints;
GetTextBoundingBoxPrivate(GetDrawBatchLines(), m_selectionStart, m_selectionEnd, rectPoints);
- ITexture* whiteTexture = gEnv->pRenderer->GetWhiteTexture();
+ auto systemImage = AZ::RPI::ImageSystemInterface::Get()->GetSystemImage(AZ::RPI::SystemImage::White);
bool isClampTextureMode = true;
uint32 packedColor = (m_textSelectionColor.GetA8() << 24) | (m_textSelectionColor.GetR8() << 16) | (m_textSelectionColor.GetG8() << 8) | m_textSelectionColor.GetB8();
@@ -1878,7 +1830,12 @@ void UiTextComponent::Render(LyShine::IRenderGraph* renderGraph)
{
IRenderer::DynUiPrimitive* primitive = renderGraph->GetDynamicQuadPrimitive(rect.pt, packedColor);
primitive->m_next = nullptr;
- renderGraph->AddPrimitive(primitive, whiteTexture, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
+
+ LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph);
+ if (lyRenderGraph)
+ {
+ lyRenderGraph->AddPrimitiveAtom(primitive, systemImage, isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
+ }
}
}
@@ -1887,21 +1844,25 @@ void UiTextComponent::Render(LyShine::IRenderGraph* renderGraph)
{
for (auto batch : m_renderCache.m_imageBatches)
{
- ITexture* texture = batch->m_texture;
+ AZ::Data::Instance texture = batch->m_texture;
// If the fade value has changed we need to update the alpha values in the vertex colors but we do
// not want to touch or recompute the RGB values
if (batch->m_cachedPrimitive.m_vertices[0].color.a != finalAlphaByte)
{
- for (int i=0; i < 4; ++i)
+ for (int i = 0; i < 4; ++i)
{
batch->m_cachedPrimitive.m_vertices[i].color.a = finalAlphaByte;
}
}
bool isClampTextureMode = true;
- renderGraph->AddPrimitive(&batch->m_cachedPrimitive, texture,
- isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
+ LyShine::RenderGraph* lyRenderGraph = dynamic_cast(renderGraph);
+ if (lyRenderGraph)
+ {
+ lyRenderGraph->AddPrimitiveAtom(&batch->m_cachedPrimitive, texture,
+ isClampTextureMode, isTextureSRGB, isTexturePremultipliedAlpha, blendMode);
+ }
}
}
diff --git a/Gems/LyShine/Code/Source/UiTextComponent.h b/Gems/LyShine/Code/Source/UiTextComponent.h
index c3983c5454..b23f2a2886 100644
--- a/Gems/LyShine/Code/Source/UiTextComponent.h
+++ b/Gems/LyShine/Code/Source/UiTextComponent.h
@@ -21,13 +21,14 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
-#include
-#include
+#include
// Only needed for internal unit-testing
#include
@@ -91,7 +92,7 @@ public: //types
bool OnAtlasLoaded(const TextureAtlasNamespace::TextureAtlas* atlas);
bool OnAtlasUnloaded(const TextureAtlasNamespace::TextureAtlas* atlas);
- ITexture* m_texture;
+ AZ::Data::Instance m_texture;
AZ::Vector2 m_size;
VAlign m_vAlign;
float m_yOffset;
@@ -616,8 +617,8 @@ private: // types
struct RenderCacheImageBatch
{
- ITexture* m_texture;
- IRenderer::DynUiPrimitive m_cachedPrimitive;
+ AZ::Data::Instance m_texture;
+ IRenderer::DynUiPrimitive m_cachedPrimitive;
};
struct RenderCacheData
diff --git a/Gems/LyShine/Code/Source/UiTextInputComponent.cpp b/Gems/LyShine/Code/Source/UiTextInputComponent.cpp
index ca0d3fab02..6cfa2c911b 100644
--- a/Gems/LyShine/Code/Source/UiTextInputComponent.cpp
+++ b/Gems/LyShine/Code/Source/UiTextInputComponent.cpp
@@ -1450,13 +1450,17 @@ void UiTextInputComponent::CheckStartTextInput()
EBUS_EVENT_ID_RESULT(textString, m_textEntity, UiTextBus, GetText);
options.m_initialText = Utf8SubString(textString, m_textCursorPos, m_textSelectionStartPos);
+ AZ::EntityId canvasEntityId;
+ EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId);
+
+ // Calculate height available for virtual keyboard. In game mode, canvas size is the same as viewport size
+ AZ::Vector2 canvasSize;
+ EBUS_EVENT_ID_RESULT(canvasSize, canvasEntityId, UiCanvasBus, GetCanvasSize);
UiTransformInterface::RectPoints rectPoints;
EBUS_EVENT_ID(GetEntityId(), UiTransformBus, GetViewportSpacePoints, rectPoints);
const AZ::Vector2 bottomRight = rectPoints.GetAxisAlignedBottomRight();
- options.m_normalizedMinY = bottomRight.GetY() / static_cast(gEnv->pRenderer->GetHeight());
+ options.m_normalizedMinY = (canvasSize.GetY() > 0.0f) ? bottomRight.GetY() / canvasSize.GetY() : 0.0f;
- AZ::EntityId canvasEntityId;
- EBUS_EVENT_ID_RESULT(canvasEntityId, GetEntityId(), UiElementBus, GetCanvasEntityId);
EBUS_EVENT_ID_RESULT(options.m_localUserId, canvasEntityId, UiCanvasBus, GetLocalUserIdInputFilter);
AzFramework::InputTextEntryRequestBus::Broadcast(&AzFramework::InputTextEntryRequests::TextEntryStart, options);
diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp
index 9c9297ec1c..6f28cbfe19 100644
--- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp
@@ -512,7 +512,7 @@ namespace ScriptCanvasEditor
}
}
- bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, AZStd::unordered_map>& outSlotIdMap)
+ bool Graph::SanityCheckNodeReplacement(ScriptCanvas::Node* oldNode, ScriptCanvas::Node* newNode, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport)
{
auto findReplacementMatch = [](const ScriptCanvas::Slot* oldSlot, const AZStd::vector& newSlots)->ScriptCanvas::SlotId
{
@@ -529,14 +529,14 @@ namespace ScriptCanvasEditor
return {};
};
- oldNode->CustomizeReplacementNode(newNode, outSlotIdMap);
-
if (!newNode)
{
AZ_Warning("ScriptCanvas", false, "Replacement node can not be null.");
return false;
}
+ oldNode->CustomizeReplacementNode(newNode, nodeUpdateSlotReport.m_oldSlotsToNewSlots);
+
AZStd::unordered_map> slotNameMap = oldNode->GetReplacementSlotsMap();
const auto newSlots = newNode->GetAllSlots();
@@ -544,16 +544,19 @@ namespace ScriptCanvasEditor
bool usingDefaults = true;
size_t defaultMatchesFound = 0;
+ auto& oldSlotsToNewSlots = nodeUpdateSlotReport.m_oldSlotsToNewSlots;
+
for (auto oldSlot : oldSlots)
{
const ScriptCanvas::SlotId oldSlotId = oldSlot->GetId();
const AZStd::string oldSlotName = oldSlot->GetName();
- auto slotIdsIter = outSlotIdMap.find(oldSlotId);
+
+ auto slotIdsIter = oldSlotsToNewSlots.find(oldSlotId);
auto slotNamesIter = slotNameMap.find(oldSlotName);
// For old node slot remapping, we should get:
// 1. if old slot name is not static, we should find the mapping in user provided slot id map
// 2. if old slot name is static, we should find the mapping in codegen generated map (case 1 can override case 2)
- if (slotIdsIter != outSlotIdMap.end())
+ if (slotIdsIter != oldSlotsToNewSlots.end())
{
for (auto newSlotId : slotIdsIter->second)
{
@@ -581,9 +584,10 @@ namespace ScriptCanvasEditor
if (!newSlotName.empty())
{
auto newSlot = newNode->GetSlotByName(newSlotName);
+
if (!newSlot)
{
- AZ_Warning("ScriptCanvas", false, "Failed to find slot with name %s in replacement Node(%s).", newSlotName.c_str(), newNode->GetNodeName().c_str());
+ AZ_Warning("ScriptCanvas", false, "Failed to find slot with name %s in replacement Node (%s).", newSlotName.c_str(), newNode->GetNodeName().c_str());
return false;
}
else if (newSlot && oldSlot->GetType() != newSlot->GetType())
@@ -591,10 +595,11 @@ namespace ScriptCanvasEditor
AZ_Warning("ScriptCanvas", false, "Failed to map deprecated Node (%s) Slot (%s) to replacement Node (%s) Slot (%s).", oldNode->GetNodeName().c_str(), oldSlot->GetName().c_str(), newNode->GetNodeName().c_str(), newSlot->GetName().c_str());
return false;
}
+
newSlotIds.push_back(newSlot->GetId());
}
}
- outSlotIdMap.emplace(oldSlot->GetId(), newSlotIds);
+ oldSlotsToNewSlots.emplace(oldSlot->GetId(), newSlotIds);
}
else if (slotNameMap.empty())
{
@@ -605,7 +610,7 @@ namespace ScriptCanvasEditor
{
++defaultMatchesFound;
AZStd::vector slotIds{ newSlotId };
- outSlotIdMap.emplace(oldSlot->GetId(), slotIds);
+ oldSlotsToNewSlots.emplace(oldSlot->GetId(), slotIds);
}
}
else
@@ -615,7 +620,7 @@ namespace ScriptCanvasEditor
}
}
- if (usingDefaults && defaultMatchesFound != oldSlots.size())
+ if (usingDefaults && oldSlotsToNewSlots.size() != oldSlots.size())
{
AZ_Warning("ScriptCanvas", false, "Failed to remap deprecated Node(%s) not all old slots were present in the new node.", oldNode->GetNodeName().c_str());
}
@@ -690,8 +695,10 @@ namespace ScriptCanvasEditor
}
}
- AZ::Outcome Graph::ReplaceNodeByConfig(ScriptCanvas::Node* oldNode, const ScriptCanvas::NodeConfiguration& nodeConfig,
- ScriptCanvas::ReplacementConnectionMap& remapConnections)
+ AZ::Outcome Graph::ReplaceNodeByConfig
+ ( ScriptCanvas::Node* oldNode
+ , const ScriptCanvas::NodeConfiguration& nodeConfig
+ , ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport)
{
auto nodeEntity = oldNode->GetEntity();
if (!nodeEntity)
@@ -731,8 +738,8 @@ namespace ScriptCanvasEditor
AddNode(newNode->GetEntityId());
ScriptCanvas::NodeUtils::InitializeNode(newNode, nodeConfig);
- AZStd::unordered_map> slotIdMap;
- rollbackRequired = !SanityCheckNodeReplacement(oldNode, newNode, slotIdMap);
+ rollbackRequired = !SanityCheckNodeReplacement(oldNode, newNode, nodeUpdateSlotReport);
+ auto& slotIdMap = nodeUpdateSlotReport.m_oldSlotsToNewSlots;
if (rollbackRequired)
{
@@ -748,25 +755,15 @@ namespace ScriptCanvasEditor
else
{
nodeEntity->Activate();
-
newNode->SignalReconfigurationBegin();
-
newNode->SetNodeDisabledFlag(oldNode->GetNodeDisabledFlag());
+
for (auto slotIdIter : slotIdMap)
{
ScriptCanvas::Slot* oldSlot = oldNode->GetSlot(slotIdIter.first);
const ScriptCanvas::Endpoint oldEndpoint{ nodeEntity->GetId(), oldSlot->GetId() };
if (slotIdIter.second.size() == 0)
{
- // If remap id is empty, then we should just cache the old slot connection for delete
- if (oldSlot->IsInput())
- {
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForTargetEndpoint(*this, oldEndpoint, ScriptCanvas::Endpoint(), remapConnections);
- }
- else
- {
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForSourceEndpoint(*this, oldEndpoint, ScriptCanvas::Endpoint(), remapConnections);
- }
continue;
}
@@ -808,35 +805,11 @@ namespace ScriptCanvasEditor
ScriptCanvas::VersioningUtils::CopyOldValueToDataSlot(newSlot, oldSlot->GetVariableReference(), oldSlot->FindDatum());
}
-
- // if old slot is visible, we need to check its connections for remapping
- if (oldSlot->IsVisible())
- {
- ScriptCanvas::Endpoint newEndpoint;
- if (newSlot)
- {
- newEndpoint = { nodeEntity->GetId(), newSlot->GetId() };
- }
- else
- {
- AZ_Warning("ScriptCanvas", false, "Invalid slot! Unable to create new connection for Node (%s).", newNode->GetNodeName().c_str());
- }
-
- if (oldSlot->IsInput())
- {
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForTargetEndpoint(*this, oldEndpoint, newEndpoint, remapConnections);
- }
- else
- {
- ScriptCanvas::VersioningUtils::CreateRemapConnectionsForSourceEndpoint(*this, oldEndpoint, newEndpoint, remapConnections);
- }
- }
}
}
+
delete oldNode;
-
newNode->SignalReconfigurationEnd();
-
return AZ::Success(newNode);
}
}
@@ -3634,8 +3607,7 @@ namespace ScriptCanvasEditor
AZStd::unordered_map< AZ::EntityId, AZ::EntityId > scriptCanvasToGraphCanvasMapping;
- bool graphNeedsDirtying = false;
-
+ bool graphNeedsDirtying = !GetVersion().IsLatest();
{
QScopedValueRollback ignoreRequests(m_ignoreSaveRequests, true);
@@ -3659,7 +3631,8 @@ namespace ScriptCanvasEditor
AZStd::unordered_set deletedNodes;
AZStd::unordered_set assetSanitizationSet;
AZStd::unordered_set sanityCheckRequiredNodes;
- ScriptCanvas::ReplacementConnectionMap remapConnections;
+
+ ScriptCanvas::GraphUpdateSlotReport graphUpdateSlotReport;
for (const AZ::EntityId& scriptCanvasNodeId : nodeList)
{
@@ -3674,12 +3647,15 @@ namespace ScriptCanvasEditor
ScriptCanvas::NodeConfiguration nodeConfig = scriptCanvasNode->GetReplacementNodeConfiguration();
if (nodeConfig.IsValid())
{
- auto nodeOutcome = ReplaceNodeByConfig(scriptCanvasNode, nodeConfig, remapConnections);
+ ScriptCanvas::NodeUpdateSlotReport nodeUpdateSlotReport;
+ auto nodeOutcome = ReplaceNodeByConfig(scriptCanvasNode, nodeConfig, nodeUpdateSlotReport);
+
if (nodeOutcome.IsSuccess())
{
graphNeedsDirtying = true;
scriptCanvasNode = nodeOutcome.GetValue();
m_updateStrings.insert(AZStd::string::format("Replaced node (%s)", scriptCanvasNode->GetNodeName().c_str()));
+ ScriptCanvas::MergeUpdateSlotReport(scriptCanvasNodeId, graphUpdateSlotReport, nodeUpdateSlotReport);
}
}
}
@@ -3688,7 +3664,6 @@ namespace ScriptCanvasEditor
scriptCanvasToGraphCanvasMapping[scriptCanvasNodeId] = graphCanvasNodeId;
auto saveDataIter2 = m_graphCanvasSaveData.find(scriptCanvasNodeId);
-
if (saveDataIter2 != m_graphCanvasSaveData.end())
{
GraphCanvas::EntitySaveDataRequestBus::Event(graphCanvasNodeId, &GraphCanvas::EntitySaveDataRequests::ReadSaveData, (*saveDataIter2->second));
@@ -3699,7 +3674,7 @@ namespace ScriptCanvasEditor
GraphCanvas::SceneRequestBus::Event(graphCanvasGraphId, &GraphCanvas::SceneRequests::AddNode, graphCanvasNodeId, position, false);
- // If the node is deprecated, we want to stomp whatever style it had saved and apply the deperecated style
+ // If the node is deprecated, we want to stomp whatever style it had saved and apply the deprecated style
if (scriptCanvasNode->IsDeprecated())
{
GraphCanvas::NodeTitleRequestBus::Event(graphCanvasNodeId, &GraphCanvas::NodeTitleRequests::SetPaletteOverride, "DeprecatedNodeTitlePalette");
@@ -3719,27 +3694,13 @@ namespace ScriptCanvasEditor
}
}
- // Remap connections step should be done before editor processing connections for graph
- //
- // Delete underlying data conenections.
- for (auto remapConnection : remapConnections)
+ if (!graphUpdateSlotReport.IsEmpty())
{
- RemoveConnection(remapConnection.first);
+ // currently, it is expected that there are no deleted old slots, those need manual correction
+ AZ_Error("ScriptCanvas", graphUpdateSlotReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required");
+ UpdateConnectionStatus(*this, graphUpdateSlotReport);
}
- // Recreate connections in a separate pass to avoid triggering display updates for invalid slot ids.
- for (auto remapConnection : remapConnections)
- {
- for (auto newEndpointPair : remapConnection.second)
- {
- if (newEndpointPair.first.IsValid() && newEndpointPair.second.IsValid())
- {
- ConnectByEndpoint(newEndpointPair.first, newEndpointPair.second);
- }
- }
- }
- ////
-
AZStd::unordered_set graphCanvasNodesToDelete;
for (auto scriptCanvasNode : outOfDateNodes)
diff --git a/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp b/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp
index 7762e1d095..581c3775d6 100644
--- a/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp
+++ b/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp
@@ -424,24 +424,11 @@ namespace ScriptCanvasEditor
EditorGraphUpgradeMachine* sm = GetStateMachine();
auto* graph = sm->m_graph;
- // Delete underlying data connections.
- for (auto remapConnection : sm->m_replacementConnections)
+ if (!sm->m_updateReport.IsEmpty())
{
- graph->RemoveConnection(remapConnection.first);
- }
-
- // Recreate connections in a separate pass to avoid triggering display updates for invalid slot ids.
- for (auto remapConnection : sm->m_replacementConnections)
- {
- for (auto newEndpointPair : remapConnection.second)
- {
- if (newEndpointPair.first.IsValid() && newEndpointPair.second.IsValid())
- {
- graph->ConnectByEndpoint(newEndpointPair.first, newEndpointPair.second);
-
- Log("Replaced Connection: %s\n", Helpers::ConnectionToText(graph, newEndpointPair.first, newEndpointPair.second).c_str());
- }
- }
+ // currently, it is expected that there are no deleted old slots, those need manual correction
+ AZ_Error("ScriptCanvas", sm->m_updateReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required");
+ UpdateConnectionStatus(*graph, sm->m_updateReport);
}
}
@@ -455,16 +442,18 @@ namespace ScriptCanvasEditor
ScriptCanvas::NodeConfiguration nodeConfig = node->GetReplacementNodeConfiguration();
if (nodeConfig.IsValid())
{
- auto nodeOutcome = graph->ReplaceNodeByConfig(node, nodeConfig, sm->m_replacementConnections);
+ ScriptCanvas::NodeUpdateSlotReport nodeUpdateSlotReport;
+ auto nodeOutcome = graph->ReplaceNodeByConfig(node, nodeConfig, nodeUpdateSlotReport);
if (nodeOutcome.IsSuccess())
{
+ ScriptCanvas::MergeUpdateSlotReport(node->GetEntityId(), sm->m_updateReport, nodeUpdateSlotReport);
+
sm->m_allNodes.erase(node);
sm->m_outOfDateNodes.erase(node);
sm->m_sanityCheckRequiredNodes.erase(node);
-
sm->m_graphNeedsDirtying = true;
- auto replacedNode = nodeOutcome.GetValue();
+ auto replacedNode = nodeOutcome.GetValue();
sm->m_allNodes.insert(replacedNode);
if (replacedNode->IsOutOfDate(graph->GetVersion()))
diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h
index 3bd8270629..687d783e63 100644
--- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h
+++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h
@@ -42,6 +42,7 @@
namespace ScriptCanvas
{
struct NodeConfiguration;
+ struct NodeUpdateSlotReport;
}
namespace ScriptCanvasEditor
@@ -361,8 +362,8 @@ namespace ScriptCanvasEditor
void HandleFunctionDefinitionExtension(ScriptCanvas::Node* node, GraphCanvas::SlotId graphCanvasSlotId, const GraphCanvas::NodeId& nodeId);
//// Version Update code
- AZ::Outcome ReplaceNodeByConfig(ScriptCanvas::Node*, const ScriptCanvas::NodeConfiguration&, ScriptCanvas::ReplacementConnectionMap&);
- bool SanityCheckNodeReplacement(ScriptCanvas::Node*, ScriptCanvas::Node*, AZStd::unordered_map>&);
+ AZ::Outcome ReplaceNodeByConfig(ScriptCanvas::Node*, const ScriptCanvas::NodeConfiguration&, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport);
+ bool SanityCheckNodeReplacement(ScriptCanvas::Node*, ScriptCanvas::Node*, ScriptCanvas::NodeUpdateSlotReport& nodeUpdateSlotReport);
bool m_allowVersionUpdate = false;
AZStd::unordered_set< AZ::EntityId > m_queuedConvertingNodes;
diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h
index 791e649e3a..cc5315808e 100644
--- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h
+++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h
@@ -159,7 +159,7 @@ namespace ScriptCanvasEditor
AZStd::unordered_set m_deletedNodes;
AZStd::unordered_set m_assetSanitizationSet;
- ScriptCanvas::ReplacementConnectionMap m_replacementConnections;
+ ScriptCanvas::GraphUpdateSlotReport m_updateReport;
AZStd::unordered_map< AZ::EntityId, AZ::EntityId > m_scriptCanvasToGraphCanvasMapping;
diff --git a/Gems/ScriptCanvas/Code/Editor/Static/Include/ScriptCanvas/View/EditCtrls/GenericLineEditCtrl.h b/Gems/ScriptCanvas/Code/Editor/Static/Include/ScriptCanvas/View/EditCtrls/GenericLineEditCtrl.h
index 74f363f569..06a63fe8b6 100644
--- a/Gems/ScriptCanvas/Code/Editor/Static/Include/ScriptCanvas/View/EditCtrls/GenericLineEditCtrl.h
+++ b/Gems/ScriptCanvas/Code/Editor/Static/Include/ScriptCanvas/View/EditCtrls/GenericLineEditCtrl.h
@@ -123,6 +123,11 @@ namespace ScriptCanvasEditor
template
AzToolsFramework::PropertyHandlerBase* RegisterGenericLineEditHandler(const EditCtrl::PropertyToStringCB& propertyToStringCB, const EditCtrl::StringToPropertyCB& stringToPropertyCB)
{
+ if (!AzToolsFramework::PropertyTypeRegistrationMessages::Bus::FindFirstHandler())
+ {
+ return nullptr;
+ }
+
auto propertyHandler(aznew GenericLineEditHandler(propertyToStringCB, stringToPropertyCB));
AzToolsFramework::PropertyTypeRegistrationMessages::Bus::Broadcast(&AzToolsFramework::PropertyTypeRegistrationMessages::RegisterPropertyType, propertyHandler);
return propertyHandler;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja
index 089e5fe6ff..fbf2bd5355 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja
@@ -75,7 +75,7 @@ public: \
void ConfigureSlots() override; \
bool RequiresDynamicSlotOrdering() const override; \
bool IsDeprecated() const override; \
-{% if deprecationUuid is defined %} NodeConfiguration GetReplacementNodeConfiguration() const override; \
+{% if deprecationUuid is defined %} ScriptCanvas::NodeConfiguration GetReplacementNodeConfiguration() const override; \
{% endif %}
using Node::FindDatum; \
{% if Class.attrib['GraphEntryPoint'] is defined %} bool IsEntryPoint() const override { return {%if Class.attrib['GraphEntryPoint'] == "True" %}true{%else%}false{%endif%}; } \
@@ -168,4 +168,4 @@ struct {{ className | replace(' ','') }}Property
{% endfor %}
-{% endfor %}
+{% endfor %}
\ No newline at end of file
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Connection.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Connection.h
index 155e5bb4c2..e2cd7008c8 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Connection.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Connection.h
@@ -22,6 +22,7 @@
namespace ScriptCanvas
{
class Slot;
+ struct NodeUpdateSlotReport;
class Connection
: public AZ::Component
@@ -64,6 +65,8 @@ namespace ScriptCanvas
// GraphNotificationBus
void OnNodeRemoved(const ID& nodeId) override;
+ void UpdateConnectionStatus(NodeUpdateSlotReport& report);
+
protected:
//-------------------------------------------------------------------------
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.cpp
index dd223f34ec..0f49fb8b5d 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Contracts/MethodOverloadContract.cpp
@@ -33,7 +33,7 @@ namespace ScriptCanvas
{
if (m_availableIndexes.empty())
{
- return -1;
+ return std::numeric_limits::max();
}
return (*m_availableIndexes.begin());
@@ -151,19 +151,22 @@ namespace ScriptCanvas
for (const AZ::BehaviorParameter* behaviorParameter : paramTypes.second)
{
- ScriptCanvas::Data::Type dataType = ScriptCanvas::Data::FromAZType(behaviorParameter->m_typeId);
- if (ScriptCanvas::Data::IsValueType(dataType))
+ if (behaviorParameter)
{
- isValueType = true;
- }
- else if (ScriptCanvas::Data::IsContainerType(dataType))
- {
- isContainerType = true;
- }
+ ScriptCanvas::Data::Type dataType = ScriptCanvas::Data::FromAZType(behaviorParameter->m_typeId);
+ if (ScriptCanvas::Data::IsValueType(dataType))
+ {
+ isValueType = true;
+ }
+ else if (ScriptCanvas::Data::IsContainerType(dataType))
+ {
+ isContainerType = true;
+ }
- if (isValueType && isContainerType)
- {
- break;
+ if (isValueType && isContainerType)
+ {
+ break;
+ }
}
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp
index 8d24b67b4f..1637a2e71b 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp
@@ -616,6 +616,34 @@ namespace ScriptCanvas
return false;
}
+
+ void Graph::RemoveAllConnections()
+ {
+ for (auto connectionEntity : m_graphData.m_connections)
+ {
+ if (auto connection = connectionEntity ? AZ::EntityUtils::FindFirstDerivedComponent(connectionEntity) : nullptr)
+ {
+ if (connection->GetSourceEndpoint().IsValid())
+ {
+ EndpointNotificationBus::Event(connection->GetSourceEndpoint(), &EndpointNotifications::OnEndpointDisconnected, connection->GetTargetEndpoint());
+ }
+ if (connection->GetTargetEndpoint().IsValid())
+ {
+ EndpointNotificationBus::Event(connection->GetTargetEndpoint(), &EndpointNotifications::OnEndpointDisconnected, connection->GetSourceEndpoint());
+ }
+ }
+
+ GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnConnectionRemoved, connectionEntity->GetId());
+ }
+
+ for (auto& connectionRef : m_graphData.m_connections)
+ {
+ delete connectionRef;
+ }
+
+ m_graphData.m_connections.clear();
+ }
+
bool Graph::RemoveConnection(const AZ::EntityId& connectionId)
{
if (connectionId.IsValid())
@@ -752,7 +780,6 @@ namespace ScriptCanvas
auto* connectionEntity = aznew AZ::Entity("Connection");
connectionEntity->CreateComponent(sourceEndpoint, targetEndpoint);
-
AZ::Entity* nodeEntity{};
AZ::ComponentApplicationBus::BroadcastResult(nodeEntity, &AZ::ComponentApplicationRequests::FindEntity, sourceEndpoint.GetNodeId());
auto node = nodeEntity ? AZ::EntityUtils::FindFirstDerivedComponent(nodeEntity) : nullptr;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.h
index 1862ce4966..49b22db2bf 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.h
@@ -87,6 +87,7 @@ namespace ScriptCanvas
Slot* FindSlot(const Endpoint& endpoint) const override;
bool AddConnection(const AZ::EntityId&) override;
+ void RemoveAllConnections();
bool RemoveConnection(const AZ::EntityId& connectionId) override;
AZStd::vector GetConnections() const override;
AZStd::vector GetConnectedEndpoints(const Endpoint& firstEndpoint) const override;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h
index e34bdb1c71..8426e90515 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h
@@ -53,7 +53,9 @@ namespace ScriptCanvas
template
void AddDefaultInputAndOutputTypeSlot(DatumType&& defaultValue);
void AddInputTypeAndOutputTypeSlot(const Data::Type& type);
-
+
+ bool IsDeprecated() const override { return true; }
+
void OnActivate() override;
void OnInputChanged(const Datum& input, const SlotId& id) override;
void MarkDefaultableInput() override {}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp
index d37427af0b..9784cc97c4 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.cpp
@@ -347,6 +347,11 @@ namespace ScriptCanvas
}
}
+ void Slot::ClearDynamicGroup()
+ {
+ m_dynamicGroup = AZ::Crc32{};
+ }
+
void Slot::ConvertToLatentExecutionOut()
{
if (IsExecution() && IsOutput())
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h
index c65d4efc84..794ce091b1 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Slot.h
@@ -68,6 +68,8 @@ namespace ScriptCanvas
void AddContract(const ContractDescriptor& contractDesc);
+ void ClearDynamicGroup();
+
template
T* FindContract()
{
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp
index 8dff6da9b1..732455857e 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp
@@ -1036,12 +1036,12 @@ namespace ScriptCanvas
if (azrtti_istypeof(&node))
{
// todo Add node to these errors
- AddError(nullptr, ValidationConstPtr(aznew NotYetImplemented(node.GetEntityId(), AZStd::string::format("NodeableNodeOverloaded doesn't have enough data connected to select a valid overload: %s", node.GetDebugName().data()))));
+ AddError(nullptr, ValidationConstPtr(aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("%s: %s", ParseErrors::NodeableNodeOverloadAmbiguous, node.GetDebugName().data()))));
}
else
{
// todo Add node to these errors
- AddError(nullptr, ValidationConstPtr(aznew NotYetImplemented(node.GetEntityId(), AZStd::string::format("NodeableNode did not construct its internal node: %s", node.GetDebugName().data()))));
+ AddError(nullptr, ValidationConstPtr(aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("%s: %s", ParseErrors::NodeableNodeDidNotConstructInternalNodeable, node.GetDebugName().data()))));
}
}
}
@@ -2535,7 +2535,7 @@ namespace ScriptCanvas
if (IsInfiniteVariableWriteHandlingLoop(*this, variableHandling, variableHandling->m_function, true))
{
- AddError(variableHandling->m_function, aznew NotYetImplemented(AZ::EntityId(), ScriptCanvas::ParseErrors::InfiniteLoopWritingToVariable));
+ AddError(variableHandling->m_function, aznew Internal::ParseError(AZ::EntityId(), ScriptCanvas::ParseErrors::InfiniteLoopWritingToVariable));
return false;
}
@@ -3312,7 +3312,7 @@ namespace ScriptCanvas
}
else
{
- AddError(execution, aznew NotYetImplemented(execution->GetNodeId(), childOutSlotsOutcome.TakeError()));
+ AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), childOutSlotsOutcome.TakeError()));
}
}
}
@@ -3615,9 +3615,11 @@ namespace ScriptCanvas
void AbstractCodeModel::ParseExecutionMultipleOutSyntaxSugar(ExecutionTreePtr execution, const EndpointsResolved& executionOutNodes, const AZStd::vector& outSlots)
{
+ const auto executionNodeId = execution->GetId().m_node ? execution->GetId().m_node->GetEntityId() : AZ::EntityId();
+
if (executionOutNodes.size() != outSlots.size())
{
- AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarMismatchOutSize);
+ AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarMismatchOutSize);
}
if (execution->GetSymbol() != Symbol::Sequence)
@@ -3630,13 +3632,13 @@ namespace ScriptCanvas
if (!child)
{
- AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNullChildFound);
+ AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNullChildFound);
return;
}
if (child->m_execution)
{
- AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound);
+ AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound);
return;
}
@@ -3660,7 +3662,7 @@ namespace ScriptCanvas
if (execution->GetChildrenCount() != executionOutNodes.size())
{
- AddError(AZ::EntityId(), execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced);
+ AddError(executionNodeId, execution, ParseErrors::ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced);
return;
}
}
@@ -4187,7 +4189,7 @@ namespace ScriptCanvas
}
else
{
- AddError(nullptr, aznew NotYetImplemented(execution->GetNodeId(), dataSlotsOutcome.TakeError()));
+ AddError(nullptr, aznew Internal::ParseError(execution->GetNodeId(), dataSlotsOutcome.TakeError()));
}
}
}
@@ -4494,13 +4496,13 @@ namespace ScriptCanvas
}
else
{
- AddError(execution, aznew NotYetImplemented(execution->GetNodeId(), returnSlotsOutcome.TakeError()));
+ AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), returnSlotsOutcome.TakeError()));
}
}
}
else
{
- AddError(execution, aznew NotYetImplemented(execution->GetNodeId(), outputSlotsOutcome.TakeError()));
+ AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), outputSlotsOutcome.TakeError()));
}
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.cpp
index e04f7c1725..cda93c1b36 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.cpp
@@ -35,15 +35,6 @@ namespace ScriptCanvas
}
}
- AZStd::unordered_map> ArithmeticExpression::GetReplacementSlotsMap() const
- {
- AZStd::unordered_map> slotsMap;
- slotsMap.emplace(k_evaluateName, AZStd::vector{ "In" });
- slotsMap.emplace(k_outName, AZStd::vector{ "Out" });
- slotsMap.emplace(k_resultName, AZStd::vector{ "Result" });
- return slotsMap;
- }
-
void ArithmeticExpression::OnInit()
{
{
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.h
index 351d02f2cc..7c230b359a 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/BinaryOperator.h
@@ -72,7 +72,6 @@ namespace ScriptCanvas
bool IsDeprecated() const override { return true; }
- AZStd::unordered_map> GetReplacementSlotsMap() const override;
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map>& outSlotIdMap) const override;
protected:
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.cpp
index 0b7b6020e3..d730b6bcc9 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.cpp
@@ -94,8 +94,6 @@ namespace ScriptCanvas
void ForEach::OnInit()
{
- ResetLoop();
-
if (!m_sourceSlot.IsValid())
{
DynamicDataSlotConfiguration slotConfiguration;
@@ -130,33 +128,6 @@ namespace ScriptCanvas
EndpointNotificationBus::Handler::BusConnect({ GetEntityId(), m_sourceSlot });
}
- void ForEach::OnInputSignal(const SlotId& slotId)
- {
- auto inSlotId = ForEachProperty::GetInSlotId(this);
- if (slotId == inSlotId || slotId == SlotId{})
- {
- if (slotId == inSlotId)
- {
- if (!InitializeLoop())
- {
- // Loop initialization failed
- SignalOutput(ForEachProperty::GetFinishedSlotId(this));
- return;
- }
- }
-
- if (!m_breakCalled)
- {
- Iterate();
- }
- }
- else if (slotId == ForEachProperty::GetBreakSlotId(this))
- {
- m_breakCalled = true;
- SignalOutput(ForEachProperty::GetFinishedSlotId(this));
- }
- }
-
UpdateResult ForEach::OnUpdateNode()
{
if (auto continueSlot = GetSlotByNameAndType("Continue", CombinedSlotType::ExecutionIn))
@@ -167,161 +138,6 @@ namespace ScriptCanvas
return UpdateResult::DirtyGraph;
}
- bool ForEach::InitializeLoop()
- {
- ResetLoop();
-
- const Datum* input = FindDatum(m_sourceSlot);
-
- if (input && !input->Empty())
- {
- if (!Data::IsContainerType(input->GetType()))
- {
- SCRIPTCANVAS_REPORT_ERROR((*this), "Iteration not supported on this type: %s", Data::GetName(m_sourceContainer.GetType()).c_str());
- return false;
- }
-
- // Make a copy of the source datum
- m_sourceContainer = *input;
-
- // Get the size of the container
- auto sizeOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(m_sourceContainer, "Size");
-
- if (!sizeOutcome)
- {
- SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get size of container: %s", sizeOutcome.GetError().c_str());
- return false;
- }
-
- Datum sizeResult = sizeOutcome.TakeValue();
- const size_t* sizePtr = sizeResult.GetAs();
- m_size = sizePtr ? *sizePtr : 0;
-
- if (Data::IsSetContainerType(m_sourceContainer.GetType()) || Data::IsMapContainerType(m_sourceContainer.GetType()))
- {
- // If it's a map or set, get the vector of keys
- auto keysVectorOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(m_sourceContainer, "GetKeys");
-
- if (!keysVectorOutcome)
- {
- SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get vector of keys: %s", keysVectorOutcome.GetError().c_str());
- return false;
- }
-
- m_keysVector = keysVectorOutcome.TakeValue();
-
- // Check size of vector of keys for safety
- auto keysSizeOutcome = BehaviorContextMethodHelper::CallMethodOnDatum(m_keysVector, "Size");
-
- if (!keysSizeOutcome)
- {
- SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get size of vector of keys: %s", keysSizeOutcome.GetError().c_str());
- return false;
- }
-
- Datum keysSizeResult = keysSizeOutcome.TakeValue();
- const size_t* keysSizePtr = keysSizeResult.GetAs();
- size_t keysSize = keysSizePtr ? *keysSizePtr : 0;
-
- if (m_size != keysSize)
- {
- // This shouldn't happen
- SCRIPTCANVAS_REPORT_ERROR((*this), "Container size and vector of keys size mismatch.");
- return false;
- }
- }
-
- return true;
- }
-
- return false;
- }
-
- void ForEach::Iterate()
- {
- if (m_sourceContainer.Empty() || m_index >= m_size)
- {
- SignalOutput(ForEachProperty::GetFinishedSlotId(this));
- return;
- }
-
- Datum& container = Data::IsVectorContainerType(m_sourceContainer.GetType()) ? m_sourceContainer : m_keysVector;
-
- auto keyAtOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(container, "At", m_index);
-
- if (!keyAtOutcome)
- {
- SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get key in container: %s", keyAtOutcome.GetError().c_str());
- return;
- }
-
- Datum keyAtResult = keyAtOutcome.TakeValue();
-
- if (!SetPropertySlotData(keyAtResult, k_keySlotIndex))
- {
- // Unable to set property slot
- SCRIPTCANVAS_REPORT_ERROR((*this), "Unable to set one of the property slots on this node.");
- SignalOutput(ForEachProperty::GetFinishedSlotId(this));
- return;
- }
-
- if (Data::IsMapContainerType(m_sourceContainer.GetType()))
- {
- // If the container is a map, we want to get the value for the current key
- auto valueAtOutcome = BehaviorContextMethodHelper::CallMethodOnDatumUnpackOutcomeSuccess(m_sourceContainer, "At", keyAtResult);
-
- if (!valueAtOutcome)
- {
- SCRIPTCANVAS_REPORT_ERROR((*this), "Failed to get value for key in container: %s", valueAtOutcome.GetError().c_str());
- return;
- }
-
- Datum valueAtResult = valueAtOutcome.TakeValue();
-
- if (!SetPropertySlotData(valueAtResult, k_valueSlotIndex))
- {
- // Unable to set property slot
- SCRIPTCANVAS_REPORT_ERROR((*this), "Unable to set one of the property slots on this node.");
- SignalOutput(ForEachProperty::GetFinishedSlotId(this));
- return;
- }
- }
-
- ++m_index;
-
- SignalOutput(ForEachProperty::GetEachSlotId(this));
- }
-
- bool ForEach::SetPropertySlotData(Datum& atResult, size_t propertyIndex)
- {
- if (atResult.Empty())
- {
- // Something went wrong with the Behavior Context call
- SCRIPTCANVAS_REPORT_ERROR((*this), "Behavior Context call failed; unable to retrieve element from container.");
- return false;
- }
-
- if (m_propertySlots.size() <= propertyIndex)
- {
- // Missing a property slot
- SCRIPTCANVAS_REPORT_ERROR((*this), "Node in invalid state; missing a property slot.");
- return false;
- }
-
- PushOutput(atResult, *GetSlot(m_propertySlots[propertyIndex].m_propertySlotId));
- return true;
- }
-
- void ForEach::ResetLoop()
- {
- // Reset node state
- m_index = 0;
- m_size = 0;
- m_breakCalled = false;
- m_sourceContainer = Datum();
- m_keysVector = Datum();
- }
-
void ForEach::OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType)
{
if (dynamicGroup == GetContainerGroupId() && dataType.IsValid())
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.h
index 68e75adc80..32bca9eefd 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ForEach.h
@@ -56,44 +56,29 @@ namespace ScriptCanvas
bool IsBreakSlot(const SlotId&) const;
- bool IsOutOfDate(const VersionData& graphVersion) const override;
-
-
+ bool IsOutOfDate(const VersionData& graphVersion) const override;
UpdateResult OnUpdateNode() override;
- protected:
- ExecutionNameMap GetExecutionNameMap() const override;
-
- void OnInit() override;
- void OnInputSignal(const SlotId&) override;
-
- bool InitializeLoop();
- void Iterate();
- bool SetPropertySlotData(Datum& atResult, size_t propertyIndex);
- void ResetLoop();
-
- void OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType) override;
-
- void ClearPropertySlots();
- void AddPropertySlotsFromType(const Data::Type& dataType);
-
- static AZ::Crc32 GetContainerGroupId() { return AZ_CRC("ContainerGroup", 0xb81ed451); }
-
- SlotId m_sourceSlot;
- AZ::TypeId m_previousTypeId;
- AZStd::vector m_propertySlots;
-
+ private:
static const size_t k_keySlotIndex;
static const size_t k_valueSlotIndex;
- size_t m_index;
- size_t m_size;
+ static AZ::Crc32 GetContainerGroupId() { return AZ_CRC("ContainerGroup", 0xb81ed451); }
- bool m_breakCalled;
+ void AddPropertySlotsFromType(const Data::Type& dataType);
- Datum m_sourceContainer;
- Datum m_keysVector;
+ void ClearPropertySlots();
+
+ ExecutionNameMap GetExecutionNameMap() const override;
+
+ void OnInit() override;
+
+ void OnDynamicGroupDisplayTypeChanged(const AZ::Crc32& dynamicGroup, const Data::Type& dataType) override;
+
+ SlotId m_sourceSlot;
+ AZ::TypeId m_previousTypeId;
+ AZStd::vector m_propertySlots;
};
}
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp
index cec643d799..678ca60ef3 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.cpp
@@ -410,6 +410,11 @@ namespace ScriptCanvas
return m_asset.GetId();
}
+ const AZStd::string& FunctionCallNode::GetAssetHint() const
+ {
+ return m_asset.GetHint();
+ }
+
AZ::Outcome FunctionCallNode::GetDependencies() const
{
DependencyReport report;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h
index fe5b453cf3..003bc2581b 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h
@@ -70,6 +70,8 @@ namespace ScriptCanvas
AZ::Data::AssetId GetAssetId() const;
+ const AZStd::string& GetAssetHint() const;
+
const AZStd::string& GetName() const;
void Initialize(AZ::Data::AssetId assetId, const ScriptCanvas::Grammar::FunctionSourceId& sourceId);
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.cpp
index ad556ae093..a849983deb 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.cpp
@@ -19,6 +19,32 @@
#include
+namespace FunctionDefinitionNodeCpp
+{
+ void VersionUpdateRemoveDefaultDisplayGroup(ScriptCanvas::Nodes::Core::FunctionDefinitionNode& node)
+ {
+ using namespace ScriptCanvas;
+ using namespace ScriptCanvas::Nodes::Core;
+
+ AZ::SerializeContext* serializeContext{};
+ AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext);
+ if (serializeContext)
+ {
+ const auto& classData = serializeContext->FindClassData(azrtti_typeid());
+ if (classData && classData->m_version < FunctionDefinitionNode::NodeVersion::RemoveDefaultDisplayGroup)
+ {
+ for (auto& slot : node.ModAllSlots())
+ {
+ if (slot->GetType() == CombinedSlotType::DataIn || slot->GetType() == CombinedSlotType::DataOut)
+ {
+ slot->ClearDynamicGroup();
+ }
+ }
+ }
+ }
+ }
+}
+
namespace ScriptCanvas
{
namespace Nodes
@@ -113,6 +139,12 @@ namespace ScriptCanvas
}
}
+ void FunctionDefinitionNode::OnInit()
+ {
+ Nodeling::OnInit();
+ FunctionDefinitionNodeCpp::VersionUpdateRemoveDefaultDisplayGroup(*this);
+ }
+
void FunctionDefinitionNode::SetupSlots()
{
auto groupedSlots = GetSlotsWithDisplayGroup(GetSlotDisplayGroup());
@@ -208,7 +240,6 @@ namespace ScriptCanvas
slotConfiguration.SetConnectionType(connectionType);
slotConfiguration.m_displayGroup = GetDataDisplayGroup();
- slotConfiguration.m_dynamicGroup = GetDataDynamicTypeGroup();
slotConfiguration.m_dynamicDataType = DynamicDataType::Any;
slotConfiguration.m_isUserAdded = true;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h
index 20b20cb65d..04dc0c7103 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/FunctionDefinitionNode.h
@@ -29,14 +29,13 @@ namespace ScriptCanvas
class FunctionDefinitionNode
: public Internal::Nodeling
{
- private:
+ public:
enum NodeVersion
{
- Initial = 1
+ Initial = 1,
+ RemoveDefaultDisplayGroup,
};
- public:
-
SCRIPTCANVAS_NODE(FunctionDefinitionNode);
FunctionDefinitionNode() = default;
@@ -78,14 +77,15 @@ namespace ScriptCanvas
static constexpr AZ::Crc32 GetAddNodelingInputDataSlot() { return AZ_CRC_CE("AddNodelingInputDataSlot"); }
static constexpr AZ::Crc32 GetAddNodelingOutputDataSlot() { return AZ_CRC_CE("AddNodelingOutputDataSlot"); }
- static constexpr AZ::Crc32 GetDataDynamicTypeGroup() { return AZ_CRC_CE("DataGroup"); }
-
+
AZStd::string GetDataDisplayGroup() const { return "DataDisplayGroup"; }
SlotId HandleExtension(AZ::Crc32 extensionId) override;
void ConfigureVisualExtensions() override;
+ void OnInit() override;
+
void OnSetup() override;
private:
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp
index b6f7bc2972..4a9e8ac3e3 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp
@@ -208,7 +208,6 @@ namespace ScriptCanvas
}
}
-
void Method::InitializeMethod(const MethodConfiguration& config)
{
m_namespaces = config.m_namespaces ? *config.m_namespaces : m_namespaces;
@@ -239,7 +238,11 @@ namespace ScriptCanvas
for (size_t argIndex(0), sentinel(config.m_method.GetNumArguments()); argIndex != sentinel; ++argIndex)
{
SlotId addedSlot = AddMethodInputSlot(config, argIndex);
- MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex);
+
+ if (addedSlot.IsValid())
+ {
+ MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex);
+ }
}
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h
index 6a53054ddf..829dff2c29 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h
@@ -132,6 +132,8 @@ namespace ScriptCanvas
const Slot* GetIfBranchSlot(bool branch) const;
+ AZ_INLINE const AZStd::string& GetLookupName() const { return m_lookupName; }
+
AZ_INLINE AZStd::recursive_mutex& GetMutex() { return m_mutex; }
ConstSlotsOutcome GetSlotsInExecutionThreadByTypeImpl(const Slot& executionSlot, CombinedSlotType targetSlotType, const Slot* executionChildSlot) const override;
@@ -160,6 +162,8 @@ namespace ScriptCanvas
bool SanityCheckBranchOnResultMethod(const AZ::BehaviorMethod& branchOnResultMethod) const;
+ AZ_INLINE void SetClassNamePretty(AZStd::string_view classNamePretty) { m_classNamePretty = classNamePretty; }
+
void SetMethodUnchecked(const AZ::BehaviorMethod* method, const AZ::BehaviorClass* behaviorClass);
AZ_INLINE void SetWarnOnMissingFunction(bool enabled) { m_warnOnMissingFunction = enabled; }
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp
index ed7fce7ffc..bfd0bb824d 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp
@@ -94,7 +94,7 @@ namespace ScriptCanvas
{
if (!m_updatingDisplay)
{
- RefreshActiveIndexes();
+ RefreshActiveIndexes(true, true);
UpdateSlotDisplay();
}
}
@@ -135,10 +135,8 @@ namespace ScriptCanvas
return Data::Type::Invalid();
}
- AZ::Outcome MethodOverloaded::GetFunctionCallName(const Slot* slot) const
+ AZ::Outcome MethodOverloaded::GetFunctionCallName([[maybe_unused]] const Slot* slot) const
{
- AZ_UNUSED(slot);
-
AZStd::string overloadName;
int activeIndex = GetActiveIndex();
@@ -188,7 +186,7 @@ namespace ScriptCanvas
// this prevents repeated updates based on changes to slots
Method::InitializeMethod(config);
-
+ SetClassNamePretty("");
RefreshActiveIndexes();
ConfigureContracts();
@@ -197,7 +195,12 @@ namespace ScriptCanvas
SlotId MethodOverloaded::AddMethodInputSlot(const MethodConfiguration& config, size_t argumentIndex)
{
const AZ::BehaviorParameter* argumentPtr = config.m_method.GetArgument(argumentIndex);
- AZ_Assert(argumentPtr, "Method: %s had a null argument at index: %d", config.m_lookupName->data(), argumentIndex);
+
+ if (!argumentPtr)
+ {
+ return SlotId{};
+ }
+
const auto& argument = *argumentPtr;
auto nameAndToolTip = MethodHelper::GetArgumentNameAndToolTip(config, argumentIndex);
@@ -507,7 +510,7 @@ namespace ScriptCanvas
}
}
- void MethodOverloaded::RefreshActiveIndexes(bool checkForConnections)
+ void MethodOverloaded::RefreshActiveIndexes(bool checkForConnections, bool adjustSlots)
{
DataIndexMapping concreteInputTypes;
DataIndexMapping concreteOutputTypes;
@@ -519,6 +522,35 @@ namespace ScriptCanvas
if (m_overloadSelection.m_availableIndexes.size() == 1)
{
auto methodOverload = m_overloadConfiguration.m_overloads[(*m_overloadSelection.m_availableIndexes.begin())];
+
+ if (adjustSlots)
+ {
+ const size_t numArguments = methodOverload.first->GetNumArguments();
+ const size_t numInputSlots = m_orderedInputSlotIds.size();
+
+ if (numArguments > numInputSlots)
+ {
+ MethodConfiguration config(*methodOverload.first, GetMethodType());
+ AZStd::string_view lookupName = GetLookupName();
+ config.m_lookupName = &lookupName;
+
+ for (size_t index = numInputSlots; index != numArguments; ++index)
+ {
+ AddMethodInputSlot(config, index);
+ }
+ }
+ else if (numArguments < numInputSlots)
+ {
+ const size_t removeCount = numInputSlots - numArguments;
+ // remove extra slots, assuming remaining ones are of valid type (if not valid name)
+ for (size_t count = 0; count != removeCount; ++count)
+ {
+ RemoveSlot(m_orderedInputSlotIds.back());
+ m_orderedInputSlotIds.pop_back();
+ }
+ }
+ }
+
SetMethodUnchecked(methodOverload.first, methodOverload.second);
}
}
@@ -681,9 +713,6 @@ namespace ScriptCanvas
return AZ::Success();
}
-
}
-
}
-
}
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h
index 1fffbd7eac..517d3dd072 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h
@@ -106,7 +106,7 @@ namespace ScriptCanvas
void SetupMethodData(const AZ::BehaviorMethod* lookupMethod, const AZ::BehaviorClass* lookupClass);
void ConfigureContracts();
- void RefreshActiveIndexes(bool checkForConnections = true);
+ void RefreshActiveIndexes(bool checkForConnections = true, bool adjustSlots = false);
void FindDataIndexMappings(DataIndexMapping& inputMapping, DataIndexMapping& outputMapping, bool checkForConnections) const;
void UpdateSlotDisplay();
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.cpp
index b8c1e9e400..6f8a23a2ed 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.cpp
@@ -393,14 +393,6 @@ namespace ScriptCanvas
AZ_UNUSED(sourceType);
}
- AZStd::unordered_map> OperatorBase::GetReplacementSlotsMap() const
- {
- AZStd::unordered_map> slotsMap;
- slotsMap.emplace("In", AZStd::vector{ "In" });
- slotsMap.emplace("Out", AZStd::vector{ "Out" });
- return slotsMap;
- }
-
void OperatorBase::CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map>& outSlotIdMap) const
{
auto newDataInSlots = replacementNode->GetSlotsByType(ScriptCanvas::CombinedSlotType::DataIn);
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.h
index bc49f3fac6..7091d7fa87 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Operator.h
@@ -57,7 +57,6 @@ namespace ScriptCanvas
AZStd::vector< SourceSlotConfiguration > m_sourceSlotConfigurations;
};
- AZStd::unordered_map> GetReplacementSlotsMap() const override;
void CustomizeReplacementNode(Node* replacementNode, AZStd::unordered_map>& outSlotIdMap) const override;
using TypeList = AZStd::vector;
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml
index 21adecb8fe..e1ea8a4b73 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Time/Timer.ScriptCanvasGrammar.xml
@@ -8,7 +8,7 @@
Base="ScriptCanvas::Node"
Version="2"
GeneratePropertyFriend="True"
- DeprecationUUID="32A4BEDC-C207-4472-61DE-9A716402620A"
+ DeprecationUUID="{32A4BEDC-C207-4472-61DE-9A716402620A}"
Deprecated="This node has been deprecated in favor of the nodeable form"
Description="Provides a time value.">
@@ -25,4 +25,4 @@
IsInput="False"
IsOutput="True" />
-
+
\ No newline at end of file
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h
index 16ac7e1fa0..def4fa7761 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h
@@ -62,6 +62,8 @@ namespace ScriptCanvas
constexpr const char* NoChildrenAfterRoot = "No children after parsing function root";
constexpr const char* NoChildrenInExtraction = "No children found in property extraction node";
constexpr const char* NoDataPresent = "Could not construct from graph, no graph data was present";
+ constexpr const char* NodeableNodeOverloadAmbiguous = "NodeableNodeOverloaded doesn't have enough data connected to select a valid overload";
+ constexpr const char* NodeableNodeDidNotConstructInternalNodeable = "NodeableNode did not construct its internal Nodeable";
constexpr const char* NoInputToForEach = "No Input To For Each Loop";
constexpr const char* NoOutForExecution = "No out slot for execution root";
constexpr const char* NoOutSlotInFunctionDefinitionStart = "No 'Out' slot in start of function definition";
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.cpp
index 5bf5f83916..0dc16f721c 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.cpp
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.cpp
@@ -12,9 +12,26 @@
#include "VersioningUtils.h"
#include
+#include
namespace ScriptCanvas
{
+ AZStd::vector GraphUpdateSlotReport::Convert(const Endpoint& oldEndpoint) const
+ {
+ auto iter = m_oldSlotsToNewSlots.find(oldEndpoint);
+ return iter != m_oldSlotsToNewSlots.end() ? iter->second : AZStd::vector{ oldEndpoint };
+ }
+
+ bool GraphUpdateSlotReport::IsEmpty() const
+ {
+ return m_deletedOldSlots.empty() && m_oldSlotsToNewSlots.empty();
+ }
+
+ bool NodeUpdateSlotReport::IsEmpty() const
+ {
+ return m_deletedOldSlots.empty() && m_oldSlotsToNewSlots.empty();
+ }
+
void VersioningUtils::CopyOldValueToDataSlot(Slot* newSlot, const VariableId& oldVariableReference, const Datum* oldDatum)
{
if (oldVariableReference.IsValid())
@@ -36,6 +53,99 @@ namespace ScriptCanvas
}
}
+ void MergeUpdateSlotReport(const AZ::EntityId& scriptCanvasNodeId, GraphUpdateSlotReport& report, const NodeUpdateSlotReport& source)
+ {
+ report.m_deletedOldSlots.reserve(source.m_deletedOldSlots.size());
+
+ for (auto& slotId : source.m_deletedOldSlots)
+ {
+ report.m_deletedOldSlots.insert({ scriptCanvasNodeId, slotId });
+ }
+
+ report.m_oldSlotsToNewSlots.reserve(source.m_oldSlotsToNewSlots.size());
+
+ for (auto& oldToNewIter : source.m_oldSlotsToNewSlots)
+ {
+ AZStd::vector newEndpoints;
+ newEndpoints.reserve(oldToNewIter.second.size());
+
+ for (auto& targetSlotId : oldToNewIter.second)
+ {
+ newEndpoints.push_back({ scriptCanvasNodeId, targetSlotId });
+ }
+
+ report.m_oldSlotsToNewSlots[{ scriptCanvasNodeId, oldToNewIter.first}] = AZStd::move(newEndpoints);
+ }
+ }
+
+ AZStd::vector> CollectEndpoints(const AZStd::vector& connections, bool logEntityNames)
+ {
+ AZStd::vector names;
+ AZStd::vector> endpoints;
+
+ for (auto& connectionEntity : connections)
+ {
+ if (logEntityNames)
+ {
+ names.push_back(connectionEntity->GetName());
+ }
+
+ if (auto connection = AZ::EntityUtils::FindFirstDerivedComponent(connectionEntity->GetId()))
+ {
+ endpoints.push_back(AZStd::make_pair(connection->GetSourceEndpoint(), connection->GetTargetEndpoint()));
+ }
+ }
+
+ if (logEntityNames)
+ {
+ AZStd::sort(names.begin(), names.end());
+
+ AZStd::string result = "\nConnection Name list:\n";
+ for (auto& name : names)
+ {
+ result += "\n";
+ result += name;
+ }
+
+ AZ_TracePrintf("ScriptCanvas", result.c_str());
+ }
+
+ return endpoints;
+ }
+
+ void UpdateConnectionStatus(Graph& graph, const GraphUpdateSlotReport& report)
+ {
+ GraphData* graphData = graph.GetGraphData();
+ if (!graphData)
+ {
+ AZ_Error("ScriptCanvas", false, "Graph was missing graph data to update");
+ return;
+ }
+
+ AZStd::unordered_set oldConnectedSlots;
+ AZ_TracePrintf("ScriptCanvas", "Connections list before: ");
+ auto endpoints = CollectEndpoints(graphData->m_connections, true);
+ graph.RemoveAllConnections();
+
+ for (auto& iter : endpoints)
+ {
+ const AZStd::vector& sources = report.Convert(iter.first);
+ const AZStd::vector& targets = report.Convert(iter.second);
+
+ for (const auto& source : sources)
+ {
+ for (const auto& target : targets)
+ {
+ graph.ConnectByEndpoint(source, target);
+ }
+ }
+ }
+
+ graphData->BuildEndpointMap();
+ AZ_TracePrintf("ScriptCanvas", "Connections list after: ");
+ CollectEndpoints(graphData->m_connections, true);
+ }
+
void VersioningUtils::CreateRemapConnectionsForSourceEndpoint(const Graph& graph, const Endpoint& oldSourceEndpoint, const Endpoint& newSourceEndpoint,
ReplacementConnectionMap& connectionMap)
{
diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.h
index 51960e08e7..a9a40305c3 100644
--- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.h
+++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Utils/VersioningUtils.h
@@ -15,6 +15,8 @@
#include
#include
+#include
+#include
#include
namespace AZ
@@ -25,13 +27,36 @@ namespace AZ
namespace ScriptCanvas
{
class Datum;
- class Endpoint;
class Graph;
class Slot;
- using ReplacementEndpointPairs = AZStd::unordered_set>;
+ using ReplacementEndpointPairs = AZStd::unordered_set>;
using ReplacementConnectionMap = AZStd::unordered_map;
+ struct NodeUpdateSlotReport
+ {
+ AZStd::unordered_set m_deletedOldSlots;
+ AZStd::unordered_map> m_oldSlotsToNewSlots;
+
+ bool IsEmpty() const;
+ };
+
+ struct GraphUpdateSlotReport
+ {
+ AZStd::unordered_set m_deletedOldSlots;
+ AZStd::unordered_map> m_oldSlotsToNewSlots;
+
+ AZStd::vector Convert(const Endpoint& oldEndpoint) const;
+
+ bool IsEmpty() const;
+ };
+
+ void MergeUpdateSlotReport(const AZ::EntityId& scriptCanvasNodeId, GraphUpdateSlotReport& report, const NodeUpdateSlotReport& source);
+
+ AZStd::vector> CollectEndpoints(const AZStd::vector& connections, bool logEntityNames = false);
+
+ void UpdateConnectionStatus(Graph& graph, const GraphUpdateSlotReport& report);
+
class VersioningUtils
{
public:
diff --git a/Gems/StartingPointInput/Code/Source/InputNode.ScriptCanvasGrammar.xml b/Gems/StartingPointInput/Code/Source/InputNode.ScriptCanvasGrammar.xml
index 9d6c555c97..8c8cc34597 100644
--- a/Gems/StartingPointInput/Code/Source/InputNode.ScriptCanvasGrammar.xml
+++ b/Gems/StartingPointInput/Code/Source/InputNode.ScriptCanvasGrammar.xml
@@ -6,8 +6,10 @@
PreferredClassName="Input Handler"
Uuid="{0B0AC61B-4BBA-42BF-BDCD-DAF2D3CA41A8}"
Base="ScriptCanvas::Node"
- Icon="Icons/ScriptCanvas/Bus.png"
+ Icon="Editor/Icons/ScriptCanvas/Bus.png"
EditAttributes="AZ::Edit::Attributes::Category@Gameplay/Input"
+ DeprecationUUID="{0A2EB488-5A6A-E166-BB62-23FF81499E33}"
+ Deprecated="This node has been deprecated in favor of the nodeable form"
GraphEntryPoint="True"
GeneratePropertyFriend="True"
Description="Handle processed input events found in input binding assets">
@@ -25,4 +27,4 @@
IsInput="False"
IsOutput="True" />
-
+
\ No newline at end of file
diff --git a/Gems/TextureAtlas/Code/CMakeLists.txt b/Gems/TextureAtlas/Code/CMakeLists.txt
index b7072321dc..5e29a7ea65 100644
--- a/Gems/TextureAtlas/Code/CMakeLists.txt
+++ b/Gems/TextureAtlas/Code/CMakeLists.txt
@@ -10,7 +10,7 @@
#
ly_add_target(
- NAME TextureAtlas ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+ NAME TextureAtlas.Static STATIC
NAMESPACE Gem
FILES_CMAKE
textureatlas_files.cmake
@@ -21,4 +21,46 @@ ly_add_target(
PRIVATE
Legacy::CryCommon
AZ::AzFramework
+ PUBLIC
+ Gem::Atom_RPI.Public
+ AZ::AtomCore
)
+
+ly_add_target(
+ NAME TextureAtlas ${PAL_TRAIT_MONOLITHIC_DRIVEN_MODULE_TYPE}
+ NAMESPACE Gem
+ FILES_CMAKE
+ textureatlas_module_files.cmake
+ INCLUDE_DIRECTORIES
+ PUBLIC
+ Include
+ BUILD_DEPENDENCIES
+ PRIVATE
+ Legacy::CryCommon
+ Gem::TextureAtlas.Static
+)
+
+if(PAL_TRAIT_BUILD_HOST_TOOLS)
+ ly_add_target(
+ NAME TextureAtlas.Editor GEM_MODULE
+ NAMESPACE Gem
+ FILES_CMAKE
+ textureatlas_module_files.cmake
+ textureatlas_builder_files.cmake
+ COMPILE_DEFINITIONS
+ PRIVATE
+ TEXTUREATLAS_EDITOR
+ INCLUDE_DIRECTORIES
+ PUBLIC
+ Include
+ BUILD_DEPENDENCIES
+ PRIVATE
+ Legacy::CryCommon
+ AZ::AzCore
+ AZ::AzFramework
+ AZ::AssetBuilderSDK
+ Gem::TextureAtlas.Static
+ Gem::ImageProcessingAtom.Headers
+ )
+endif()
+
diff --git a/Gems/TextureAtlas/Code/Include/TextureAtlas/TextureAtlas.h b/Gems/TextureAtlas/Code/Include/TextureAtlas/TextureAtlas.h
index c4e222230d..0703f19c29 100644
--- a/Gems/TextureAtlas/Code/Include/TextureAtlas/TextureAtlas.h
+++ b/Gems/TextureAtlas/Code/Include/TextureAtlas/TextureAtlas.h
@@ -16,7 +16,8 @@
#include
#include
-class ITexture;
+#include
+#include
namespace TextureAtlasNamespace
{
@@ -77,9 +78,9 @@ namespace TextureAtlasNamespace
//! Retrieve a coordinate set from the Atlas by its handle
virtual AtlasCoordinates GetAtlasCoordinates(const AZStd::string& handle) const = 0;
//! Links this atlas to an image pointer
- virtual void SetTexture(ITexture* image) = 0;
+ virtual void SetTexture(AZ::Data::Instance image) = 0;
//! Returns the image linked to this atlas
- virtual ITexture* GetTexture() const = 0;
+ virtual AZ::Data::Instance GetTexture() const = 0;
//! Returns the width of the atlas
virtual int GetWidth() const = 0;
//! Returns the height of the atlas
diff --git a/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderComponent.cpp b/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderComponent.cpp
index e8d4948cc9..0cbc653730 100644
--- a/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderComponent.cpp
+++ b/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderComponent.cpp
@@ -10,7 +10,6 @@
*
*/
-#include "ImageProcessing_precompiled.h"
#include "AtlasBuilderComponent.h"
#include
diff --git a/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.cpp b/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.cpp
index 81e98251cc..ca60d33c0a 100644
--- a/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.cpp
+++ b/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.cpp
@@ -10,7 +10,6 @@
*
*/
-#include "ImageProcessing_precompiled.h"
#include "AtlasBuilderWorker.h"
#include
@@ -19,22 +18,17 @@
#include
#include
#include
+#include
#include
#include
#include
#include
#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
+#include
+#include
+#include
+#include
#include
#include
@@ -44,13 +38,13 @@
namespace TextureAtlasBuilder
{
//! Counts leading zeros
- uint32 CountLeadingZeros32(uint32 x)
+ uint32_t CountLeadingZeros32(uint32_t x)
{
return x == 0 ? 32 : az_clz_u32(x);
}
//! Integer log2
- uint32 IntegerLog2(uint32 x)
+ uint32_t IntegerLog2(uint32_t x)
{
return 31 - CountLeadingZeros32(x);
}
@@ -113,13 +107,24 @@ namespace TextureAtlasBuilder
{
bool resolved = false;
- // Get full path by appending the relative path to the watch directory
- AZStd::string fullPath = watchDirectory;
- fullPath.append("/");
- fullPath.append(relativePath);
+ if (relativePath[0] == '@')
+ {
+ // Get full path by resolving the alias at the front of the path
+ char resolvedPath[AZ_MAX_PATH_LEN];
+ AZ::IO::FileIOBase::GetInstance()->ResolvePath(relativePath.c_str(), resolvedPath, AZ_MAX_PATH_LEN);
+ resolvedFullPathOut = resolvedPath;
+ resolved = true;
+ }
+ else
+ {
+ // Get full path by appending the relative path to the watch directory
+ AZStd::string fullPath = watchDirectory;
+ fullPath.append("/");
+ fullPath.append(relativePath);
- // Resolve to canonical path (remove "./" and "../")
- resolved = GetCanonicalPathFromFullPath(fullPath, resolvedFullPathOut);
+ // Resolve to canonical path (remove "./" and "../")
+ resolved = GetCanonicalPathFromFullPath(fullPath, resolvedFullPathOut);
+ }
return resolved;
}
@@ -140,23 +145,6 @@ namespace TextureAtlasBuilder
return result;
}
- const ImageProcessing::PresetSettings* GetImageProcessPresetSettings(const AZStd::string& presetName, const AZStd::string& platformIdentifier)
- {
- // Get the specified presetId
- AZ::Uuid presetId = ImageProcessing::BuilderSettingManager::Instance()->GetPresetIdFromName(presetName);
- if (presetId.IsNull())
- {
- AZ_Error("Texture Editor", false, "Texture Preset %s has no associated UUID.", presetName.c_str());
- return nullptr;
- }
-
- // Get the preset settings for the platform this job is building for
- const ImageProcessing::PresetSettings* presetSettings = ImageProcessing::BuilderSettingManager::Instance()->GetPreset(
- presetId, platformIdentifier);
-
- return presetSettings;
- }
-
// Reflect the input parameters
void AtlasBuilderInput::Reflect(AZ::ReflectContext* context)
{
@@ -474,7 +462,7 @@ namespace TextureAtlasBuilder
{
AZStd::string ext;
AzFramework::StringFunc::Path::GetExtension(candidates[i].c_str(), ext, false);
- if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds")
+ if (ext != "dds")
{
bool duplicate = false;
for (size_t j = 0; j < paths.size() && !duplicate; ++j)
@@ -589,7 +577,7 @@ namespace TextureAtlasBuilder
{
AddFolderContents(paths, child, valid);
}
- else if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds")
+ else if (ext != "dds")
{
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, child);
bool duplicate = false;
@@ -652,7 +640,11 @@ namespace TextureAtlasBuilder
// We process the same file for all platforms
for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms)
{
- if (ImageProcessing::BuilderSettingManager::Instance()->DoesSupportPlatform(info.m_identifier))
+ bool doesSupportPlatform = false;
+ ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(doesSupportPlatform,
+ &ImageProcessingAtom::ImageBuilderRequests::DoesSupportPlatform,
+ info.m_identifier);
+ if (doesSupportPlatform)
{
AssetBuilderSDK::JobDescriptor descriptor = GetJobDescriptor(request.m_sourceFile, input);
descriptor.SetPlatformIdentifier(info.m_identifier.c_str());
@@ -707,12 +699,8 @@ namespace TextureAtlasBuilder
// Before we begin, let's make sure we are not meant to abort.
AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId);
- AZStd::vector productFilepaths;
-
const AZStd::string path = request.m_fullPath;
- bool imageProcessingSuccessful = false;
-
// read in settings/filepaths
AtlasBuilderInput input;
input.m_forceSquare = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("forceSquare"))->second.c_str());
@@ -752,43 +740,37 @@ namespace TextureAtlasBuilder
// Default to the TextureAtlas preset which is currently set to use compression for all platforms except for iOS.
// Currently the only fully supported compression for iOS is PVRTC which requires the texture to be square and a power of 2.
// Due to this limitation, we default to using no compression for iOS until ASTC is fully supported
- const AZStd::string defaultPresetName = "TextureAtlas";
+ const AZStd::string defaultPresetName = "UserInterface_Compressed";
input.m_presetName = defaultPresetName;
}
- // Get a preset to use for the output image
- const ImageProcessing::PresetSettings* preset = GetImageProcessPresetSettings(input.m_presetName, request.m_platformInfo.m_identifier);
- if (preset)
+ bool isFormatSquarePow2 = false;
+ ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(isFormatSquarePow2,
+ &ImageProcessingAtom::ImageBuilderRequests::IsPresetFormatSquarePow2,
+ input.m_presetName, request.m_platformInfo.m_identifier);
+
+ if (isFormatSquarePow2)
{
- // Check the preset's pixel format requirements
- const ImageProcessing::PixelFormatInfo* pixelFormatInfo = ImageProcessing::CPixelFormats::GetInstance().GetPixelFormatInfo(preset->m_pixelFormat);
- if (pixelFormatInfo && pixelFormatInfo->bSquarePow2)
- {
- // Override the user config settings to force square and power of 2.
- // Otherwise the image conversion process will stretch the image to satisfy these requirements
- input.m_forceSquare = true;
- input.m_forcePowerOf2 = true;
- }
- }
- else
- {
- AZ_Error("AtlasBuilder", false, "Could not find a preset setting for the output image.");
- return;
+ // Override the user config settings to force square and power of 2.
+ // Otherwise the image conversion process will stretch the image to satisfy these requirements
+ input.m_forceSquare = true;
+ input.m_forcePowerOf2 = true;
}
// Read in images
- AZStd::vector images;
+ AZStd::vector images;
AZ::u64 totalArea = 0;
int maxArea = input.m_maxDimension * input.m_maxDimension;
bool sizeFailure = false;
for (int i = 0; i < input.m_filePaths.size() && !jobCancelListener.IsCancelled(); ++i)
{
- ImageProcessing::IImageObject* inputImage = ImageProcessing::LoadImageFromFile(input.m_filePaths[i]);
+ ImageProcessingAtom::IImageObjectPtr inputImage;
+ ImageProcessingAtom::ImageProcessingRequestBus::BroadcastResult(inputImage, &ImageProcessingAtom::ImageProcessingRequests::LoadImage, input.m_filePaths[i]);
+
// Check if we were able to load the image
if (inputImage)
{
- ImageProcessing::IImageObjectPtr image = ImageProcessing::IImageObjectPtr(inputImage);
- images.push_back(image);
+ images.push_back(inputImage);
totalArea += inputImage->GetWidth(0) * inputImage->GetHeight(0);
}
else
@@ -837,8 +819,13 @@ namespace TextureAtlasBuilder
// Add white texture if we need to
if (input.m_includeWhiteTexture)
{
- ImageProcessing::IImageObjectPtr texture(ImageProcessing::IImageObject::CreateImage(
- cellSize, cellSize, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8));
+ ImageProcessingAtom::IImageObjectPtr texture;
+ ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(texture,
+ &ImageProcessingAtom::ImageBuilderRequests::CreateImage,
+ aznumeric_cast(cellSize),
+ aznumeric_cast(cellSize),
+ 1,
+ ImageProcessingAtom::EPixelFormat::ePixelFormat_R8G8B8A8);
// Make the texture white
texture->ClearColor(1, 1, 1, 1);
@@ -897,8 +884,8 @@ namespace TextureAtlasBuilder
}
if (input.m_forcePowerOf2)
{
- resultWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultWidth - 1))));
- resultHeight = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultHeight - 1))));
+ resultWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultWidth - 1))));
+ resultHeight = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultHeight - 1))));
}
else
{
@@ -918,8 +905,13 @@ namespace TextureAtlasBuilder
}
// Process texture sheet
- ImageProcessing::IImageObjectPtr outImage(ImageProcessing::IImageObject::CreateImage(
- resultWidth, resultHeight, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8));
+ ImageProcessingAtom::IImageObjectPtr outImage;
+ ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(outImage,
+ &ImageProcessingAtom::ImageBuilderRequests::CreateImage,
+ aznumeric_cast(resultWidth),
+ aznumeric_cast(resultHeight),
+ 1,
+ ImageProcessingAtom::EPixelFormat::ePixelFormat_R8G8B8A8);
// Clear the sheet
outImage->ClearColor(input.m_unusedColor.GetR(), input.m_unusedColor.GetG(), input.m_unusedColor.GetB(), input.m_unusedColor.GetA());
@@ -1010,54 +1002,21 @@ namespace TextureAtlasBuilder
// Output texture sheet
AZStd::string imageFileName, imageOutputPath;
AzFramework::StringFunc::Path::GetFileName(request.m_sourceFile.c_str(), imageFileName);
- imageFileName += ".dds";
+ imageFileName += ".texatlas";
AzFramework::StringFunc::Path::Join(
request.m_tempDirPath.c_str(), imageFileName.c_str(), imageOutputPath, true, true);
- // Let the ImageProcessor do the rest of the work.
- ImageProcessing::TextureSettings textureSettings;
- textureSettings.m_preset = preset->m_uuid;
+ AZStd::vector outProducts;
+ ImageProcessingAtom::ImageBuilderRequestBus::BroadcastResult(outProducts,
+ &ImageProcessingAtom::ImageBuilderRequests::ConvertImageObject,
+ outImage,
+ input.m_presetName,
+ request.m_platformInfo.m_identifier,
+ imageOutputPath,
+ request.m_sourceFileUUID,
+ request.m_sourceFile);
- // Mipmaps for the texture atlas would require more work than the Image Processor does. This is because if we
- // let the Image Processor make mipmaps, it might bleed the textures in the atlas together.
- textureSettings.m_enableMipmap = false;
-
- // Check if the ImageBuilder wants to enable streaming
- bool isStreaming = ImageProcessing::BuilderSettingManager::Instance()
- ->GetBuilderSetting(request.m_platformInfo.m_identifier)
- ->m_enableStreaming;
-
- bool canOverridePreset = false;
- ImageProcessing::ImageConvertProcess* process =
- new ImageProcessing::ImageConvertProcess(outImage,
- textureSettings,
- *preset,
- false,
- isStreaming,
- canOverridePreset,
- imageOutputPath,
- request.m_platformInfo.m_identifier);
-
- if (process != nullptr)
- {
- // the process can be stopped if the job is cancelled or the worker is shutting down
- while (!process->IsFinished() && !m_isShuttingDown && !jobCancelListener.IsCancelled())
- {
- process->UpdateProcess();
- }
-
- // get process result
- imageProcessingSuccessful = process->IsSucceed();
- process->GetAppendOutputFilePaths(productFilepaths);
-
- delete process;
- }
- else
- {
- imageProcessingSuccessful = false;
- }
-
- if (imageProcessingSuccessful)
+ if (!outProducts.empty())
{
TextureAtlasNamespace::TextureAtlasRequestBus::Broadcast(
&TextureAtlasNamespace::TextureAtlasRequests::SaveAtlasToFile, outputPath, output, resultWidth, resultHeight);
@@ -1067,27 +1026,23 @@ namespace TextureAtlasBuilder
// The Image Processing Gem can produce multiple output files under certain
// circumstances, but the texture atlas is not expected to produce such output
- if (productFilepaths.size() > 1)
+ if (outProducts.size() > 1)
{
AZ_Error("AtlasBuilder", false, "Image processing resulted in multiple output files. Texture atlas is expected to produce one output.");
response.m_outputProducts.clear();
return;
}
- if (productFilepaths.size() > 0)
- {
- response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(productFilepaths[0]));
- response.m_outputProducts.back().m_productAssetType = azrtti_typeid();
- response.m_outputProducts.back().m_productSubID = 1;
+ response.m_outputProducts.push_back(outProducts[0]);
+
+ // The texatlasidx file is a data file that indicates where the original parts are inside the atlas,
+ // and this would usually imply that it refers to its dds file in some way or needs it to function.
+ // The texatlasidx file should be the one that depends on the DDS because it's possible to use the DDS
+ // without the texatlasid, but not the other way around
+ AZ::Data::AssetId productAssetId(request.m_sourceFileUUID, response.m_outputProducts.back().m_productSubID);
+ response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependencies.push_back(AssetBuilderSDK::ProductDependency(productAssetId, 0));
+ response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependenciesHandled = true; // We've populated the dependencies immediately above so it's OK to tell the AP we've handled dependencies
- // The texatlasidx file is a data file that indicates where the original parts are inside the atlas,
- // and this would usually imply that it refers to its dds file in some way or needs it to function.
- // The texatlasidx file should be the one that depends on the DDS because its possible to use the DDS
- // without the texatlasid, but not the other way around
- AZ::Data::AssetId productAssetId(request.m_sourceFileUUID, response.m_outputProducts.back().m_productSubID);
- response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependencies.push_back(AssetBuilderSDK::ProductDependency(productAssetId, 0));
- response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependenciesHandled = true; // We've populated the dependencies immediately above so it's OK to tell the AP we've handled dependencies
- }
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
}
}
@@ -1315,7 +1270,7 @@ namespace TextureAtlasBuilder
if (powerOfTwo)
{
// Starting dimension needs to be rounded up to the nearest power of two
- dimension = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(dimension - 1))));
+ dimension = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(dimension - 1))));
}
AZStd::vector track;
@@ -1363,7 +1318,7 @@ namespace TextureAtlasBuilder
if (powerOfTwo)
{
// Starting dimension needs to be rounded up to the nearest power of two
- minWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(minWidth - 1))));
+ minWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(minWidth - 1))));
}
// Round min width up to the nearest compression unit
@@ -1400,7 +1355,7 @@ namespace TextureAtlasBuilder
// Find the height of the solution
for (int i = 0; i < track.size(); ++i)
{
- uint32 bottom = static_cast(AZStd::max(0, track[i].GetBottom()));
+ uint32_t bottom = static_cast(AZStd::max(0, track[i].GetBottom()));
if (height < bottom)
{
height = bottom;
@@ -1411,7 +1366,7 @@ namespace TextureAtlasBuilder
if (powerOfTwo)
{
// Starting dimensions need to be rounded up to the nearest power of two
- height = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(height - 1))));
+ height = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(height - 1))));
}
AZ::u32 resultArea = height * width;
diff --git a/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.h b/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.h
index 94e2b5b226..36f0c3d486 100644
--- a/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.h
+++ b/Gems/TextureAtlas/Code/Source/Editor/AtlasBuilderWorker.h
@@ -13,6 +13,7 @@
#pragma once
#include
+#include
#include
#include
#include
@@ -110,7 +111,7 @@ namespace TextureAtlasBuilder
enum class Product
{
TexatlasidxProduct = 0,
- DdsProduct = 1
+ StreamingImageProduct = 1
};
//! An asset builder for texture atlases
diff --git a/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.cpp b/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.cpp
index 70a1900c25..e84e843177 100644
--- a/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.cpp
+++ b/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.cpp
@@ -120,14 +120,14 @@ namespace TextureAtlasNamespace
}
// Links this atlas to an image pointer
- void TextureAtlasImpl::SetTexture(ITexture* image)
+ void TextureAtlasImpl::SetTexture(AZ::Data::Instance image)
{
// We don't need to delete the old value because the pointer is handled elsewhere
m_image = image;
}
// Returns the image linked to this atlas
- ITexture* TextureAtlasImpl::GetTexture() const
+ AZ::Data::Instance TextureAtlasImpl::GetTexture() const
{
return m_image;
}
diff --git a/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h b/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h
index af611c8c7d..22c03e0e3c 100644
--- a/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h
+++ b/Gems/TextureAtlas/Code/Source/TextureAtlasImpl.h
@@ -20,7 +20,8 @@
#include "TextureAtlas/TextureAtlas.h"
#include "TextureAtlas/TextureAtlasBus.h"
-#include
+#include
+#include
namespace TextureAtlasNamespace
{
@@ -61,10 +62,10 @@ namespace TextureAtlasNamespace
AtlasCoordinates GetAtlasCoordinates(const AZStd::string& handle) const override;
//! Links this atlas to an image pointer
- void SetTexture(ITexture* image) override;
+ void SetTexture(AZ::Data::Instance image) override;
//! Returns the image linked to this atlas
- ITexture* GetTexture() const override;
+ AZ::Data::Instance GetTexture() const override;
//! Replaces the mappings of this Texture Atlas Object, with the source's mappings
void OverwriteMappings(TextureAtlasImpl* source);
@@ -80,7 +81,7 @@ namespace TextureAtlasNamespace
private:
AZStd::unordered_map m_data;
- ITexture* m_image;
+ AZ::Data::Instance m_image;
int m_width;
int m_height;
};
diff --git a/Gems/TextureAtlas/Code/Source/TextureAtlasModule.cpp b/Gems/TextureAtlas/Code/Source/TextureAtlasModule.cpp
index 478a3f8ca6..90114f6e79 100644
--- a/Gems/TextureAtlas/Code/Source/TextureAtlasModule.cpp
+++ b/Gems/TextureAtlas/Code/Source/TextureAtlasModule.cpp
@@ -16,6 +16,10 @@
#include "TextureAtlasSystemComponent.h"
+#ifdef TEXTUREATLAS_EDITOR
+#include "Editor/AtlasBuilderComponent.h"
+#endif
+
#include
namespace TextureAtlasNamespace
@@ -33,6 +37,9 @@ namespace TextureAtlasNamespace
// Push results of [MyComponent]::CreateDescriptor() into m_descriptors here.
m_descriptors.insert(m_descriptors.end(), {
TextureAtlasSystemComponent::CreateDescriptor(),
+#ifdef TEXTUREATLAS_EDITOR
+ TextureAtlasBuilder::AtlasBuilderComponent::CreateDescriptor(), //builder component for texture atlas
+#endif
});
}
diff --git a/Gems/TextureAtlas/Code/Source/TextureAtlasSystemComponent.cpp b/Gems/TextureAtlas/Code/Source/TextureAtlasSystemComponent.cpp
index 80d4898c41..24a5126df4 100644
--- a/Gems/TextureAtlas/Code/Source/TextureAtlasSystemComponent.cpp
+++ b/Gems/TextureAtlas/Code/Source/TextureAtlasSystemComponent.cpp
@@ -22,7 +22,25 @@
#include
#include
-#include
+#include
+
+namespace
+{
+ AZ::Data::Instance LoadAtlasImage(const AZStd::string& imagePath)
+ {
+ // The file may not be in the AssetCatalog at this point if it is still processing or doesn't exist on disk.
+ // Use GenerateAssetIdTEMP instead of GetAssetIdByPath so that it will return a valid AssetId anyways
+ AZ::Data::AssetId streamingImageAssetId;
+ AZ::Data::AssetCatalogRequestBus::BroadcastResult(
+ streamingImageAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GenerateAssetIdTEMP,
+ imagePath.c_str());
+
+ streamingImageAssetId.m_subId = AZ::RPI::StreamingImageAsset::GetImageAssetSubId();
+ auto streamingImageAsset = AZ::Data::AssetManager::Instance().FindOrCreateAsset(streamingImageAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
+ AZ::Data::Instance image = AZ::RPI::StreamingImage::FindOrCreate(streamingImageAsset);
+ return image;
+ }
+}
namespace TextureAtlasNamespace
{
@@ -95,27 +113,15 @@ namespace TextureAtlasNamespace
// We reload the image here to prevent stuttering in the editor
if (iterator->second.m_atlas && iterator->second.m_atlas->GetTexture())
{
- SResourceAsync* pInfo = new SResourceAsync();
- pInfo->eClassName = eRCN_Texture;
- pInfo->pResource = iterator->second.m_atlas->GetTexture();
- // ToDo: Update to work with Atom? LYN-3680
- // ???->ReleaseResourceAsync(pInfo);
+ iterator->second.m_atlas->GetTexture().reset();
}
- // Reload Texture
- AZStd::string imagePath = iterator->second.m_path.substr(0, iterator->second.m_path.find_last_of('.'));
- imagePath.append(".dds");
-
- // ToDo: Update to work with Atom? LYN-3680
- // uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
- ITexture* texture = nullptr;
-
- if (!texture || !texture->IsTextureLoaded())
+ AZStd::string imagePath = iterator->second.m_path;
+ AZ::Data::Instance texture = LoadAtlasImage(imagePath);
+ if (!texture)
{
- gEnv->pSystem->Warning(VALIDATOR_MODULE_UNKNOWN,
- VALIDATOR_WARNING,
- VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
- imagePath.c_str(),
- "No texture file found for texture atlas: %s. "
+ AZ_Error("TextureAtlasSystemComponent",
+ false,
+ "Failed to find or create an image instance for texture atlas '%s'"
"NOTE: File must be in current project or a gem.",
imagePath.c_str());
TextureAtlas* temp = iterator->second.m_atlas;
@@ -123,6 +129,7 @@ namespace TextureAtlasNamespace
TextureAtlasNotificationBus::Broadcast(&TextureAtlasNotifications::OnAtlasUnloaded, temp);
return;
}
+
iterator->second.m_atlas->SetTexture(texture);
TextureAtlasNotificationBus::Broadcast(&TextureAtlasNotifications::OnAtlasReloaded, iterator->second.m_atlas);
break;
@@ -186,30 +193,23 @@ namespace TextureAtlasNamespace
delete[] buffer;
if (loadedAtlas)
{
- // Get the image path based on the atlas path
+ // Convert to image path based on the atlas path
AZStd::string imagePath = path;
- AzFramework::StringFunc::Path::ReplaceExtension(imagePath, "dds");
-
- // Load the image in
- // ToDo: Update to work with Atom? LYN-3680
- // uint32 loadTextureFlags = (FT_USAGE_ALLOWREADSRGB | FT_DONT_STREAM);
- ITexture* texture = nullptr;
-
- if (!texture || !texture->IsTextureLoaded())
+ AzFramework::StringFunc::Path::ReplaceExtension(imagePath, "texatlas");
+ AZ::Data::Instance texture = LoadAtlasImage(imagePath);
+ if (!texture)
{
- gEnv->pSystem->Warning(VALIDATOR_MODULE_UNKNOWN,
- VALIDATOR_WARNING,
- VALIDATOR_FLAG_FILE | VALIDATOR_FLAG_TEXTURE,
- imagePath.c_str(),
- "No texture file found for texture atlas: %s. "
+ AZ_Error("TextureAtlasSystemComponent",
+ false,
+ "Failed to find or create an image instance for texture atlas '%s'"
"NOTE: File must be in current project or a gem.",
- imagePath.c_str());
+ path.c_str());
+
delete loadedAtlas;
return nullptr;
}
else
{
- texture->SetFilter(FILTER_LINEAR);
// Add the atlas to the list
AtlasInfo info(loadedAtlas, assetPath);
++info.m_refs;
@@ -241,11 +241,7 @@ namespace TextureAtlasNamespace
// Tell the renderer to release the texture.
if (temp.m_atlas && temp.m_atlas->GetTexture())
{
- SResourceAsync* pInfo = new SResourceAsync();
- pInfo->eClassName = eRCN_Texture;
- pInfo->pResource = temp.m_atlas->GetTexture();
- // ToDo: Update to work with Atom? LYN-3680
- // ???->ReleaseResourceAsync(pInfo);
+ temp.m_atlas->GetTexture().reset();
}
// Delete the atlas
SAFE_DELETE(temp.m_atlas);
diff --git a/Gems/TextureAtlas/Code/textureatlas_builder_files.cmake b/Gems/TextureAtlas/Code/textureatlas_builder_files.cmake
new file mode 100644
index 0000000000..51cb991aa8
--- /dev/null
+++ b/Gems/TextureAtlas/Code/textureatlas_builder_files.cmake
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+
+set(FILES
+ Source/Editor/AtlasBuilderComponent.h
+ Source/Editor/AtlasBuilderComponent.cpp
+ Source/Editor/AtlasBuilderWorker.h
+ Source/Editor/AtlasBuilderWorker.cpp
+)
diff --git a/Gems/TextureAtlas/Code/textureatlas_files.cmake b/Gems/TextureAtlas/Code/textureatlas_files.cmake
index 2da4e9ce1d..c45c1d49a8 100644
--- a/Gems/TextureAtlas/Code/textureatlas_files.cmake
+++ b/Gems/TextureAtlas/Code/textureatlas_files.cmake
@@ -15,7 +15,6 @@ set(FILES
Include/TextureAtlas/TextureAtlasBus.h
Include/TextureAtlas/TextureAtlasNotificationBus.h
Include/TextureAtlas/TextureAtlas.h
- Source/TextureAtlasModule.cpp
Source/TextureAtlasSystemComponent.cpp
Source/TextureAtlasSystemComponent.h
Source/TextureAtlasImpl.h
diff --git a/Gems/TextureAtlas/Code/textureatlas_module_files.cmake b/Gems/TextureAtlas/Code/textureatlas_module_files.cmake
new file mode 100644
index 0000000000..00e18d92bc
--- /dev/null
+++ b/Gems/TextureAtlas/Code/textureatlas_module_files.cmake
@@ -0,0 +1,14 @@
+#
+# 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.
+#
+
+set(FILES
+ Source/TextureAtlasModule.cpp
+)
diff --git a/cmake/LYTestWrappers.cmake b/cmake/LYTestWrappers.cmake
index 2a65929cf6..b4d6fe308e 100644
--- a/cmake/LYTestWrappers.cmake
+++ b/cmake/LYTestWrappers.cmake
@@ -370,6 +370,7 @@ endfunction()
#! ly_add_googletest: Adds a new RUN_TEST using for the specified target using the supplied command or fallback to running
# googletest tests through AzTestRunner
# \arg:NAME Name to for the test run target
+# \arg:TARGET Name of the target module that is being run for tests. If not provided, will default to 'NAME'
# \arg:TEST_REQUIRES(optional) List of system resources that are required to run this test.
# Only available option is "gpu"
# \arg:TEST_SUITE(optional) - "smoke" or "periodic" or "sandbox" - prevents the test from running normally
@@ -384,14 +385,20 @@ function(ly_add_googletest)
message(FATAL_ERROR "Platform does not support test targets")
endif()
- set(one_value_args NAME TEST_SUITE)
+ set(one_value_args NAME TARGET TEST_SUITE)
set(multi_value_args TEST_COMMAND COMPONENT)
cmake_parse_arguments(ly_add_googletest "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
+ if (ly_add_googletest_TARGET)
+ set(target_name ${ly_add_googletest_TARGET})
+ else()
+ set(target_name ${ly_add_googletest_NAME})
+ endif()
+
# AzTestRunner modules only supports google test libraries, regardless of whether or not
# google test suites are supported
- set_property(GLOBAL APPEND PROPERTY LY_AZTESTRUNNER_TEST_MODULES "${ly_add_googletest_NAME}")
+ set_property(GLOBAL APPEND PROPERTY LY_AZTESTRUNNER_TEST_MODULES "${target_name}")
if(NOT PAL_TRAIT_TEST_GOOGLE_TEST_SUPPORTED)
return()
@@ -400,7 +407,7 @@ function(ly_add_googletest)
if (ly_add_googletest_TEST_SUITE AND NOT ly_add_googletest_TEST_SUITE STREQUAL "main")
# if a suite is specified, we filter to only accept things which match that suite (in c++)
- set(non_ide_params "-gtest_filter=*SUITE_${ly_add_googletest_TEST_SUITE}*")
+ set(non_ide_params "--gtest_filter=*SUITE_${ly_add_googletest_TEST_SUITE}*")
else()
# otherwise, if its the main suite we only runs things that dont have any of the other suites.
# Note: it doesn't do AND, only 'or' - so specifying SUITE_main:REQUIRES_gpu
@@ -412,11 +419,11 @@ function(ly_add_googletest)
if(NOT ly_add_googletest_TEST_COMMAND)
# Use the NAME parameter as the build target
- set(build_target ${ly_add_googletest_NAME})
+ set(build_target ${target_name})
ly_strip_target_namespace(TARGET ${build_target} OUTPUT_VARIABLE build_target)
if(NOT TARGET ${build_target})
- message(FATAL_ERROR "A valid build target \"${build_target}\" for test run \"${ly_add_googletest_NAME}\" has not been found.\
+ message(FATAL_ERROR "A valid build target \"${build_target}\" for test run \"${target_name}\" has not been found.\
A valid target via the TARGET parameter or a custom TEST_COMMAND must be supplied")
endif()
diff --git a/scripts/build/Platform/Linux/build_config.json b/scripts/build/Platform/Linux/build_config.json
index 5d96ae7846..c1646fc863 100644
--- a/scripts/build/Platform/Linux/build_config.json
+++ b/scripts/build/Platform/Linux/build_config.json
@@ -83,7 +83,7 @@
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all",
- "CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest --repeat until-pass:5"
+ "CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
}
},
"test_profile_nounity": {
@@ -95,7 +95,7 @@
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=FALSE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "all",
- "CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest --repeat until-pass:5"
+ "CTEST_OPTIONS": "-E (Gem::EMotionFX.Editor.Tests|Gem::AWSClientAuth.Tests|Gem::AWSCore.Editor.Tests) -L FRAMEWORK_googletest"
}
},
"asset_profile": {
@@ -143,7 +143,26 @@
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_periodic",
- "CTEST_OPTIONS": "-L \"(SUITE_periodic)\""
+ "CTEST_OPTIONS": "-L (SUITE_periodic)"
+ }
+ },
+ "sandbox_test_profile": {
+ "TAGS": [
+ "nightly-incremental",
+ "nightly-clean",
+ "weekly-build-metrics"
+ ],
+ "PIPELINE_ENV": {
+ "ON_FAILURE_MARK": "UNSTABLE"
+ },
+ "COMMAND": "build_test_linux.sh",
+ "PARAMETERS": {
+ "CONFIGURATION": "profile",
+ "OUTPUT_DIRECTORY": "build/linux",
+ "CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
+ "CMAKE_LY_PROJECTS": "AutomatedTesting",
+ "CMAKE_TARGET": "all",
+ "CTEST_OPTIONS": "-L (SUITE_sandbox)"
}
},
"benchmark_test_profile": {
@@ -159,7 +178,7 @@
"CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_UNITY_BUILD=TRUE -DLY_PARALLEL_LINK_JOBS=4 -DO3DE_HOME_PATH=\"${WORKSPACE}/home\" -DO3DE_REGISTER_ENGINE_PATH=\"${WORKSPACE}/o3de\" -DO3DE_REGISTER_THIS_ENGINE=TRUE",
"CMAKE_LY_PROJECTS": "AutomatedTesting",
"CMAKE_TARGET": "TEST_SUITE_benchmark",
- "CTEST_OPTIONS": "-L \"(SUITE_benchmark)\""
+ "CTEST_OPTIONS": "-L (SUITE_benchmark)"
}
},
"release": {
diff --git a/scripts/project_manager/projects.py b/scripts/project_manager/projects.py
index 51db7a6440..51ffc2be91 100755
--- a/scripts/project_manager/projects.py
+++ b/scripts/project_manager/projects.py
@@ -34,7 +34,7 @@ from cmake.Tools import registration
o3de_folder = registration.get_o3de_folder()
o3de_logs_folder = registration.get_o3de_logs_folder()
-project_manager_log_file_path = o3de_log_folder / "project_manager.log"
+project_manager_log_file_path = o3de_logs_folder / "project_manager.log"
log_file_handler = RotatingFileHandler(filename=project_manager_log_file_path, maxBytes=1024 * 1024, backupCount=1)
formatter = logging.Formatter('%(asctime)s | %(levelname)s : %(message)s')
log_file_handler.setFormatter(formatter)