diff --git a/Assets/Editor/Editor.tip b/Assets/Editor/Editor.tip
deleted file mode 100644
index 969e9d5ab5..0000000000
--- a/Assets/Editor/Editor.tip
+++ /dev/null
@@ -1,34 +0,0 @@
-CryEngine tips of the day
-
-You can toggle snap to grid by pressing G.
-Ctrl+Shift+Clicking somewhere with an object selected quickly moves the object to that position when in move mode.
-Pressing M will open the material editor.
-Show and Hide helpers is bound to Shift + Space by default.
-Enable AI/Physics is bound to Ctrl + P by default.
-You can save a viewport location by pressing Ctrl + F1 through f12 and go to that position using Shift + F1 through F12.
-You can link objects together by using the link command on the top menu of the editor.
-Pressing 1 through 5 on the keyboard will cycle through brush operations such as move or scale.
-You can simply bind keyboard shortcuts to editor functions by going to Tools --> Customize Keyboard.
-Pressing H will hide the selected objects, Ctrl-H will unhide all hidden objects.
-Pressing F will freeze the selected objects, Ctrl-F will unfreeze all frozen objects.
-Pressing F3 will toggle wireframe view.
-Camera/terrain collision can be toggled using Q.
-You can restart the Editor by pressing the restart button on your PC.
-Pressing Ctrl-C with an object selected will clone that object.
-Toggle the console by pressing the tilde (~) key.
-You can dock windows by dragging them onto the blue helpers that appear when you grab a window by the titlebar.
-You can select materials by clicking on the dropper icon in the material editor and then clicking on the material you wish to select.
-You can right click on the previewer in the material editor and change the model to different shapes and background colors.
-Materials can be saved in the local level folder for re-distribution.
-Always keep your level free of errors and immidiately fix errors reported by the error report screen when you load your level.
-You must always export to engine before you can run it in pure game mode. (File --> Export to engine)
-You must re-triangulate AI before playing your level in game mode. (AI --> Generate all navigation)
-You must always re-generate surface textures after you finish painting the terrain. (File --> Regenerate surface textures)
-Press Ctrl-G or F12 to go into the Game mode, ESC to return to Editing mode.
-Quickly rebuild a level (without regenerating the ground texture) by pressing Ctrl-E.
-Hold down the third mouse button and drag to move the camera up and down.
-Missing objects are represented by a bright yellow sphere.
-Hold Alt + Middle Mouse button to rotate around an object.
-Select multiple objects by holding Ctrl.
-You can place multiple instances of vegetation by holding Shift and clicking on the terrain.
-A number of useful commands can be found in Tools --> User commands. This can also be dragged and docked to the main window.
\ No newline at end of file
diff --git a/AutomatedTesting/EngineFinder.cmake b/AutomatedTesting/EngineFinder.cmake
index fbbe3d8cfe..eef3aa3cae 100644
--- a/AutomatedTesting/EngineFinder.cmake
+++ b/AutomatedTesting/EngineFinder.cmake
@@ -15,6 +15,8 @@ include_guard()
# Read the engine name from the project_json file
file(READ ${CMAKE_CURRENT_LIST_DIR}/project.json project_json)
+set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/project.json)
+
string(JSON LY_ENGINE_NAME_TO_USE ERROR_VARIABLE json_error GET ${project_json} engine)
if(json_error)
message(FATAL_ERROR "Unable to read key 'engine' from 'project.json', error: ${json_error}")
@@ -30,6 +32,7 @@ endif()
# Find a key that matches LY_ENGINE_NAME_TO_USE and use that as the engine path.
if(EXISTS ${manifest_path})
file(READ ${manifest_path} manifest_json)
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${manifest_path})
string(JSON engines_path_count ERROR_VARIABLE json_error LENGTH ${manifest_json} engines_path)
if(json_error)
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
index f463210cb0..0146aa3981 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/AWS/CMakeLists.txt
@@ -21,6 +21,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
TEST_SUITE periodic
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/${PAL_PLATFORM_NAME}/
+ TIMEOUT 3000
RUNTIME_DEPENDENCIES
Legacy::Editor
AZ::AssetProcessor
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py
index 04be31759d..511d9b3ecd 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/aws_metrics/aws_metrics_automation_test.py
@@ -18,11 +18,12 @@ import typing
from datetime import datetime
import ly_test_tools.log.log_monitor
-from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
-from AWS.common.aws_utils import aws_utils
-from AWS.common.aws_credentials import aws_credentials
+# fixture imports
from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
-from AWS.Windows.cdk.cdk import cdk
+from AWS.Windows.cdk.cdk_utils import Cdk
+from AWS.common.aws_utils import AwsUtils
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
+from AWS.common.aws_credentials import aws_credentials
from .aws_metrics_utils import aws_metrics_utils
AWS_METRICS_FEATURE_NAME = 'AWSMetrics'
@@ -32,7 +33,7 @@ logger = logging.getLogger(__name__)
def setup(launcher: ly_test_tools.launchers.Launcher,
- cdk: cdk,
+ cdk: Cdk,
asset_processor: asset_processor,
resource_mappings: resource_mappings,
context_variable: str = '') -> typing.Tuple[ly_test_tools.log.log_monitor.LogMonitor, str, str]:
@@ -116,18 +117,18 @@ def remove_file(file_path: str) -> None:
@pytest.mark.parametrize('region_name', ['us-west-2'])
@pytest.mark.parametrize('assume_role_arn', ['arn:aws:iam::645075835648:role/o3de-automation-tests'])
@pytest.mark.parametrize('session_name', ['o3de-Automation-session'])
-class TestAWSMetrics_Windows(object):
- def test_AWSMetrics_RealTimeAnalytics_MetricsSentToCloudWatch(self,
- level: str,
- launcher: ly_test_tools.launchers.Launcher,
- asset_processor: pytest.fixture,
- workspace: pytest.fixture,
- aws_utils: aws_utils,
- aws_credentials: aws_credentials,
- resource_mappings: resource_mappings,
- cdk: cdk,
- aws_metrics_utils: aws_metrics_utils,
- ):
+class TestAWSMetricsWindows(object):
+ def test_realtime_analytics_metrics_sent_to_cloudwatch(self,
+ level: str,
+ launcher: ly_test_tools.launchers.Launcher,
+ asset_processor: pytest.fixture,
+ workspace: pytest.fixture,
+ aws_utils: pytest.fixture,
+ aws_credentials: aws_credentials,
+ resource_mappings: pytest.fixture,
+ cdk: pytest.fixture,
+ aws_metrics_utils: aws_metrics_utils,
+ ):
"""
Tests that the submitted metrics are sent to CloudWatch for real-time analytics.
"""
@@ -148,7 +149,7 @@ class TestAWSMetrics_Windows(object):
'AWS/Lambda',
'Invocations',
[{'Name': 'FunctionName',
- 'Value': f'{stack_name}-AnalyticsProcessingLambda'}],
+ 'Value': f'{stack_name}-AnalyticsProcessingLambdaName'}],
start_time)
logger.info('Operational health metrics sent to CloudWatch.')
@@ -162,14 +163,14 @@ class TestAWSMetrics_Windows(object):
# Stop the Kinesis Data Analytics application.
aws_metrics_utils.stop_kinesis_data_analytics_application(analytics_application_name)
- def test_AWSMetrics_UnauthorizedUser_RequestRejected(self,
- level: str,
- launcher: ly_test_tools.launchers.Launcher,
- cdk: cdk,
- aws_credentials: aws_credentials,
- asset_processor: pytest.fixture,
- resource_mappings: resource_mappings,
- workspace: pytest.fixture):
+ def test_unauthorized_user_request_rejected(self,
+ level: str,
+ launcher: ly_test_tools.launchers.Launcher,
+ cdk: pytest.fixture,
+ aws_credentials: aws_credentials,
+ asset_processor: pytest.fixture,
+ resource_mappings: pytest.fixture,
+ workspace: pytest.fixture):
"""
Tests that unauthorized users cannot send metrics events to the AWS backed backend.
"""
@@ -187,14 +188,14 @@ class TestAWSMetrics_Windows(object):
assert result, 'Metrics events are sent successfully by unauthorized user'
logger.info('Unauthorized user is rejected to send metrics.')
- def test_AWSMetrics_BatchAnalytics_MetricsDeliveredToS3(self,
+ def test_batch_analytics_metrics_delivered_to_s3(self,
level: str,
launcher: ly_test_tools.launchers.Launcher,
- cdk: cdk,
+ cdk: pytest.fixture,
aws_credentials: aws_credentials,
asset_processor: pytest.fixture,
- resource_mappings: resource_mappings,
- aws_utils: aws_utils,
+ resource_mappings: pytest.fixture,
+ aws_utils: pytest.fixture,
aws_metrics_utils: aws_metrics_utils,
workspace: pytest.fixture):
"""
@@ -234,4 +235,3 @@ class TestAWSMetrics_Windows(object):
time.sleep(60)
# Empty the S3 bucket. S3 buckets can only be deleted successfully when it doesn't contain any object.
aws_metrics_utils.empty_s3_bucket(analytics_bucket_name)
-
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk_utils.py
similarity index 59%
rename from AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py
rename to AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk_utils.py
index 9254c3d4eb..172885ad60 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/cdk/cdk_utils.py
@@ -12,6 +12,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import os
import pytest
import boto3
+import uuid
+import logging
+import subprocess
+import botocore
import ly_test_tools.environment.process_utils as process_utils
from typing import List
@@ -19,22 +23,71 @@ from typing import List
BOOTSTRAP_STACK_NAME = 'CDKToolkit'
BOOTSTRAP_STAGING_BUCKET_LOGIC_ID = 'StagingBucket'
+logger = logging.getLogger(__name__)
+
+
class Cdk:
"""
Cdk class that provides methods to run cdk application commands.
Expects system to have NodeJS, AWS CLI and CDK installed globally and have their paths setup as env variables.
"""
- def __init__(self, cdk_path: str, project: str, account_id: str,
- workspace: pytest.fixture, session: boto3.session.Session):
+ def __init__(self):
+ self._cdk_env = ''
+ self._stacks = []
+ self._cdk_path = os.path.dirname(os.path.realpath(__file__))
+ self._session = ''
+
+ cdk_npm_latest_version_cmd = ['npm', 'view', 'aws-cdk', 'version']
+
+ output = process_utils.check_output(
+ cdk_npm_latest_version_cmd,
+ cwd=self._cdk_path,
+ shell=True)
+ cdk_npm_latest_version = output.split()[0]
+
+ cdk_version_cmd = ['cdk', 'version']
+ output = process_utils.check_output(
+ cdk_version_cmd,
+ cwd=self._cdk_path,
+ shell=True)
+ cdk_version = output.split()[0]
+ logger.info(f'Current CDK version {cdk_version}')
+
+ if cdk_version != cdk_npm_latest_version:
+ try:
+ logger.info(f'Updating CDK to latest')
+ # uninstall and reinstall cdk in case npm has been updated.
+ output = process_utils.check_output(
+ 'npm uninstall -g aws-cdk',
+ cwd=self._cdk_path,
+ shell=True)
+
+ logger.info(f'Uninstall CDK output: {output}')
+
+ output = process_utils.check_output(
+ 'npm install -g aws-cdk@latest',
+ cwd=self._cdk_path,
+ shell=True)
+
+ logger.info(f'Install CDK output: {output}')
+ except subprocess.CalledProcessError as error:
+ logger.warning(f'Failed reinstalling latest CDK on npm'
+ f'\nError:{error.stderr}')
+
+ def setup(self, cdk_path: str, project: str, account_id: str,
+ workspace: pytest.fixture, session: boto3.session.Session, bootstrap_required: bool):
"""
:param cdk_path: Path where cdk app.py is stored.
:param project: Project name used for cdk project name env variable.
:param account_id: AWS account id to use with cdk application.
:param workspace: ly_test_tools workspace fixture.
+ :param workspace: bootstrap_required deploys bootstrap stack.
"""
+
self._cdk_env = os.environ.copy()
- self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project
+ unique_id = uuid.uuid4().hex[-4:]
+ self._cdk_env['O3DE_AWS_PROJECT_NAME'] = project[:4] + unique_id if len(project) > 4 else project + unique_id
self._cdk_env['O3DE_AWS_DEPLOY_REGION'] = session.region_name
self._cdk_env['O3DE_AWS_DEPLOY_ACCOUNT'] = account_id
self._cdk_env['PATH'] = f'{workspace.paths.engine_root()}\\python;' + self._cdk_env['PATH']
@@ -43,27 +96,37 @@ class Cdk:
self._cdk_env['AWS_ACCESS_KEY_ID'] = credentials.access_key
self._cdk_env['AWS_SECRET_ACCESS_KEY'] = credentials.secret_key
self._cdk_env['AWS_SESSION_TOKEN'] = credentials.token
- self._stacks = []
self._cdk_path = cdk_path
+ self._session = session
+
output = process_utils.check_output(
'python -m pip install -r requirements.txt',
cwd=self._cdk_path,
env=self._cdk_env,
shell=True)
+ logger.info(f'Installing cdk python dependencies: {output}')
+
+ if bootstrap_required:
+ self.bootstrap()
+
def bootstrap(self) -> None:
"""
Deploy the bootstrap stack.
"""
- bootstrap_cmd = ['cdk', 'bootstrap',
- f'aws://{self._cdk_env["O3DE_AWS_DEPLOY_ACCOUNT"]}/{self._cdk_env["O3DE_AWS_DEPLOY_REGION"]}']
+ try:
+ bootstrap_cmd = ['cdk', 'bootstrap',
+ f'aws://{self._cdk_env["O3DE_AWS_DEPLOY_ACCOUNT"]}/{self._cdk_env["O3DE_AWS_DEPLOY_REGION"]}']
- process_utils.check_call(
- bootstrap_cmd,
- cwd=self._cdk_path,
- env=self._cdk_env,
- shell=True)
+ process_utils.check_call(
+ bootstrap_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+ except botocore.exceptions.ClientError as clientError:
+ logger.warning(f'Failed creating Bootstrap stack {BOOTSTRAP_STACK_NAME} not found. '
+ f'\nError:{clientError["Error"]["Message"]}')
def list(self) -> List[str]:
"""
@@ -131,83 +194,51 @@ class Cdk:
"""
Destroys the cdk application.
"""
- destroy_cdk_application_cmd = ['cdk', 'destroy', '-f']
- process_utils.check_output(
- destroy_cdk_application_cmd,
- cwd=self._cdk_path,
- env=self._cdk_env,
- shell=True)
+
+ logger.info(f'CDK Path {self._cdk_path}')
+ destroy_cdk_application_cmd = ['cdk', 'destroy', '--all', '-f']
+
+ try:
+ process_utils.check_output(
+ destroy_cdk_application_cmd,
+ cwd=self._cdk_path,
+ env=self._cdk_env,
+ shell=True)
+
+ except subprocess.CalledProcessError as e:
+ logger.error(e.output)
+ raise e
self._stacks = []
- self._cdk_path = ''
- @staticmethod
- def remove_bootstrap_stack(aws_utils: pytest.fixture) -> None:
+ def remove_bootstrap_stack(self) -> None:
"""
Remove the CDK bootstrap stack.
:param aws_utils: aws_utils fixture.
"""
# Check if the bootstrap stack exists.
- response = aws_utils.client('cloudformation').describe_stacks(
+ response = self._session.client('cloudformation').describe_stacks(
StackName=BOOTSTRAP_STACK_NAME
)
stacks = response.get('Stacks', [])
- if not stacks:
+ if not stacks or len(stacks) is 0:
return
# Clear the bootstrap staging bucket before deleting the bootstrap stack.
- response = aws_utils.client('cloudformation').describe_stack_resource(
+ response = self._session.client('cloudformation').describe_stack_resource(
StackName=BOOTSTRAP_STACK_NAME,
LogicalResourceId=BOOTSTRAP_STAGING_BUCKET_LOGIC_ID
)
staging_bucket_name = response.get('StackResourceDetail', {}).get('PhysicalResourceId', '')
if staging_bucket_name:
- s3 = aws_utils.resource('s3')
+ s3 = self._session.resource('s3')
bucket = s3.Bucket(staging_bucket_name)
for key in bucket.objects.all():
key.delete()
# Delete the bootstrap stack.
- aws_utils.client('cloudformation').delete_stack(
- StackName=BOOTSTRAP_STACK_NAME
- )
-
-
-@pytest.fixture(scope='function')
-def cdk(
- request: pytest.fixture,
- project: str,
- feature_name: str,
- workspace: pytest.fixture,
- aws_utils: pytest.fixture,
- bootstrap_required: bool = True,
- destroy_stacks_on_teardown: bool = True) -> Cdk:
- """
- Fixture for setting up a Cdk
- :param request: _pytest.fixtures.SubRequest class that handles getting
- a pytest fixture from a pytest function/fixture.
- :param project: Project name used for cdk project name env variable.
- :param feature_name: Feature gem name to expect cdk folder in.
- :param workspace: ly_test_tools workspace fixture.
- :param aws_utils: aws_utils fixture.
- :param bootstrap_required: Whether the bootstrap stack needs to be created to
- provision resources the AWS CDK needs to perform the deployment.
- :param destroy_stacks_on_teardown: option to control calling destroy ot the end of test.
- :return Cdk class object.
- """
-
- cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk'
- cdk_obj = Cdk(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session())
-
- if bootstrap_required:
- cdk_obj.bootstrap()
-
- def teardown():
- if destroy_stacks_on_teardown:
- cdk_obj.destroy()
- cdk_obj.remove_bootstrap_stack(aws_utils)
-
- request.addfinalizer(teardown)
-
- return cdk_obj
+ # Should not need to delete the stack if S3 bucket can be cleaned.
+ # self._session.client('cloudformation').delete_stack(
+ # StackName=BOOTSTRAP_STACK_NAME
+ # )
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
index 7b9c549f6c..f8aa5b85eb 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_anonymous_credentials.py
@@ -12,9 +12,10 @@ import os
import logging
import ly_test_tools.log.log_monitor
+# fixture imports
from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
-from AWS.Windows.cdk.cdk import cdk
-from AWS.common.aws_utils import aws_utils
+from AWS.Windows.cdk.cdk_utils import Cdk
+from AWS.common.aws_utils import AwsUtils
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
AWS_PROJECT_NAME = 'AWS-AutomationTest'
@@ -75,5 +76,5 @@ class TestAWSClientAuthAnonymousCredentials(object):
expected_lines=['(Script) - Success anonymous credentials'],
unexpected_lines=['(Script) - Fail anonymous credentials'],
halt_on_unexpected=True,
- )
+ )
assert result, 'Anonymous credentials fetched successfully.'
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py
index 89b859dd0f..28b17fdeee 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/Windows/client_auth/test_password_signin.py
@@ -12,9 +12,10 @@ import os
import logging
import ly_test_tools.log.log_monitor
+# fixture imports
from AWS.Windows.resource_mappings.resource_mappings import resource_mappings
-from AWS.Windows.cdk.cdk import cdk
-from AWS.common.aws_utils import aws_utils
+from AWS.Windows.cdk.cdk_utils import Cdk
+from AWS.common.aws_utils import AwsUtils
from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
AWS_PROJECT_NAME = 'AWS-AutomationTest'
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
index ff33f58d1d..fc3c5095e3 100644
--- a/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
+++ b/AutomatedTesting/Gem/PythonTests/AWS/common/aws_utils.py
@@ -8,11 +8,12 @@ remove or modify any license notices. This file is distributed on an "AS IS" BAS
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
"""
import boto3
-import pytest
import logging
logger = logging.getLogger(__name__)
-logging.getLogger('boto').setLevel(logging.CRITICAL)
+logging.getLogger('boto3').setLevel(logging.WARNING)
+logging.getLogger('botocore').setLevel(logging.WARNING)
+logging.getLogger('nose').setLevel(logging.WARNING)
class AwsUtils:
@@ -63,28 +64,3 @@ class AwsUtils:
clears stored session
"""
self._assume_session = None
-
-
-@pytest.fixture(scope='function')
-def aws_utils(
- request: pytest.fixture,
- assume_role_arn: str,
- session_name: str,
- region_name: str):
- """
- Fixture for AWS util functions
- :param request: _pytest.fixtures.SubRequest class that handles getting
- a pytest fixture from a pytest function/fixture.
- :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials.
- :param session_name: Session name to set.
- :param region_name: AWS account region to set for session.
- :return AWSUtils class object.
- """
- aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name)
-
- def teardown():
- aws_utils_obj.destroy()
-
- request.addfinalizer(teardown)
-
- return aws_utils_obj
diff --git a/AutomatedTesting/Gem/PythonTests/AWS/conftest.py b/AutomatedTesting/Gem/PythonTests/AWS/conftest.py
new file mode 100644
index 0000000000..47f9b5cefe
--- /dev/null
+++ b/AutomatedTesting/Gem/PythonTests/AWS/conftest.py
@@ -0,0 +1,87 @@
+"""
+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.
+"""
+import pytest
+import logging
+from AWS.common.aws_utils import AwsUtils
+from AWS.Windows.cdk.cdk_utils import Cdk
+
+logger = logging.getLogger(__name__)
+
+
+@pytest.fixture(scope='function')
+def aws_utils(
+ request: pytest.fixture,
+ assume_role_arn: str,
+ session_name: str,
+ region_name: str):
+ """
+ Fixture for AWS util functions
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param assume_role_arn: Role used to fetch temporary aws credentials, configure service clients with obtained credentials.
+ :param session_name: Session name to set.
+ :param region_name: AWS account region to set for session.
+ :return AWSUtils class object.
+ """
+
+ aws_utils_obj = AwsUtils(assume_role_arn, session_name, region_name)
+
+ def teardown():
+ aws_utils_obj.destroy()
+
+ request.addfinalizer(teardown)
+
+ return aws_utils_obj
+
+# Set global pytest variable for cdk to avoid recreating instance
+pytest.cdk_obj = None
+
+
+@pytest.fixture(scope='function')
+def cdk(
+ request: pytest.fixture,
+ project: str,
+ feature_name: str,
+ workspace: pytest.fixture,
+ aws_utils: pytest.fixture,
+ bootstrap_required: bool = True,
+ destroy_stacks_on_teardown: bool = True) -> Cdk:
+ """
+ Fixture for setting up a Cdk
+ :param request: _pytest.fixtures.SubRequest class that handles getting
+ a pytest fixture from a pytest function/fixture.
+ :param project: Project name used for cdk project name env variable.
+ :param feature_name: Feature gem name to expect cdk folder in.
+ :param workspace: ly_test_tools workspace fixture.
+ :param aws_utils: aws_utils fixture.
+ :param bootstrap_required: Whether the bootstrap stack needs to be created to
+ provision resources the AWS CDK needs to perform the deployment.
+ :param destroy_stacks_on_teardown: option to control calling destroy ot the end of test.
+ :return Cdk class object.
+ """
+
+ cdk_path = f'{workspace.paths.engine_root()}/Gems/{feature_name}/cdk'
+ logger.info(f'CDK Path {cdk_path}')
+
+ if pytest.cdk_obj is None:
+ pytest.cdk_obj = Cdk()
+
+ pytest.cdk_obj.setup(cdk_path, project, aws_utils.assume_account_id(), workspace, aws_utils.assume_session(),
+ bootstrap_required)
+ def teardown():
+ if destroy_stacks_on_teardown:
+ pytest.cdk_obj.destroy()
+ # Enable after https://github.com/aws/aws-cdk/issues/986 is fixed.
+ # Until then clean the bootstrap bucket manually.
+ # cdk_obj.remove_bootstrap_stack()
+
+ request.addfinalizer(teardown)
+
+ return pytest.cdk_obj
diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
index 8142691464..c6ed6c7538 100644
--- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
+++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt
@@ -60,5 +60,4 @@ add_subdirectory(streaming)
add_subdirectory(smoke)
## AWS ##
-# Enable when AWS Gems work on Linux and Android.
-# add_subdirectory(AWS)
+add_subdirectory(AWS)
diff --git a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py
index 86bfc48636..aae01e4652 100755
--- a/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py
+++ b/AutomatedTesting/Gem/PythonTests/NvCloth/TestSuite_Active.py
@@ -24,12 +24,11 @@ from base import TestAutomationBase
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
- @pytest.mark.xfail(reason="Running with atom null renderer is causing this test to fail")
+
def test_C18977329_NvCloth_AddClothSimulationToMesh(self, request, workspace, editor, launcher_platform):
from . import C18977329_NvCloth_AddClothSimulationToMesh as test_module
self._run_test(request, workspace, editor, test_module)
- @pytest.mark.xfail(reason="Running with atom null renderer is causing this test to fail")
def test_C18977330_NvCloth_AddClothSimulationToActor(self, request, workspace, editor, launcher_platform):
from . import C18977330_NvCloth_AddClothSimulationToActor as test_module
self._run_test(request, workspace, editor, test_module)
diff --git a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py
index 57cdc8f9c5..40291b2114 100755
--- a/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py
+++ b/AutomatedTesting/Gem/PythonTests/physics/C4044695_PhysXCollider_AddMultipleSurfaceFbx.py
@@ -102,7 +102,7 @@ def C4044695_PhysXCollider_AddMultipleSurfaceFbx():
# 6) Check if multiple material slots show up under Materials section in the PhysX Collider component
pte = collider_component.get_property_tree()
def get_surface_count():
- count = pte.get_container_count("Collider Configuration|Physics Material|Mesh Surfaces")
+ count = pte.get_container_count("Collider Configuration|Physics Materials|Slots")
return count.GetValue()
Report.result(
diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py
index 2b82c3e596..291bb96627 100755
--- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py
+++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Periodic.py
@@ -93,11 +93,13 @@ class TestAutomation(TestAutomationBase):
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C4044457_Material_RestitutionCombine.setreg_override', 'AutomatedTesting/Registry')
def test_C4044457_Material_RestitutionCombine(self, request, workspace, editor, launcher_platform):
from . import C4044457_Material_RestitutionCombine as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C4044456_Material_FrictionCombine.setreg_override', 'AutomatedTesting/Registry')
def test_C4044456_Material_FrictionCombine(self, request, workspace, editor, launcher_platform):
from . import C4044456_Material_FrictionCombine as test_module
self._run_test(request, workspace, editor, test_module)
@@ -194,6 +196,7 @@ class TestAutomation(TestAutomationBase):
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C18981526_Material_RestitutionCombinePriority.setreg_override', 'AutomatedTesting/Registry')
def test_C18981526_Material_RestitutionCombinePriority(self, request, workspace, editor, launcher_platform):
from . import C18981526_Material_RestitutionCombinePriority as test_module
self._run_test(request, workspace, editor, test_module)
@@ -229,6 +232,7 @@ class TestAutomation(TestAutomationBase):
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C18977601_Material_FrictionCombinePriority.setreg_override', 'AutomatedTesting/Registry')
def test_C18977601_Material_FrictionCombinePriority(self, request, workspace, editor, launcher_platform):
from . import C18977601_Material_FrictionCombinePriority as test_module
self._run_test(request, workspace, editor, test_module)
@@ -250,6 +254,7 @@ class TestAutomation(TestAutomationBase):
@pytest.mark.xfail(
reason="This test needs new physics asset with multiple materials to be more stable.")
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C4044697_Material_PerfaceMaterialValidation.setreg_override', 'AutomatedTesting/Registry')
def test_C4044697_Material_PerfaceMaterialValidation(self, request, workspace, editor, launcher_platform):
from . import C4044697_Material_PerfaceMaterialValidation as test_module
self._run_test(request, workspace, editor, test_module)
@@ -282,6 +287,7 @@ class TestAutomation(TestAutomationBase):
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override', 'AutomatedTesting/Registry')
def test_C15556261_PhysXMaterials_CharacterControllerMaterialAssignment(self, request, workspace, editor, launcher_platform):
from . import C15556261_PhysXMaterials_CharacterControllerMaterialAssignment as test_module
self._run_test(request, workspace, editor, test_module)
@@ -326,6 +332,7 @@ class TestAutomation(TestAutomationBase):
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
+ @fm.file_override('physxsystemconfiguration.setreg','C4044461_Material_Restitution.setreg_override', 'AutomatedTesting/Registry')
def test_C4044461_Material_Restitution(self, request, workspace, editor, launcher_platform):
from . import C4044461_Material_Restitution as test_module
self._run_test(request, workspace, editor, test_module)
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
new file mode 100644
index 0000000000..af8a7f5c8e
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/ClientAuth.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0f4d4e0155feaa76c80a14128000a0fd9570ab76e79f4847eaef9006324a4d2
+size 9084
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
new file mode 100644
index 0000000000..a2bbdfce39
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/ConitoAnonymousAuthorization.scriptcanvas
@@ -0,0 +1,2358 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
new file mode 100644
index 0000000000..d4e3d33551
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/Environment.xml
@@ -0,0 +1 @@
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
new file mode 100644
index 0000000000..d827d4da29
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/LevelData/TimeOfDay.xml
@@ -0,0 +1 @@
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
new file mode 100644
index 0000000000..56c3f1efd4
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/level.pak b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak
new file mode 100644
index 0000000000..8da6f7f7d6
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:da041115014f11696d5878d5c21247c17b8d694fa9674e30692259261a7223a2
+size 3792
diff --git a/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuth/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly
new file mode 100644
index 0000000000..24fe4f2482
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/ClientAuthPasswordSignIn.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:43b1a23b62fe2ffa05545ac99524f40b6fff49d6e35925b9d6138c00d8082e86
+size 9073
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas
new file mode 100644
index 0000000000..ffc3064084
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/PasswordSignIn.scriptcanvas
@@ -0,0 +1,6642 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml
new file mode 100644
index 0000000000..f3e20f9b63
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak
new file mode 100644
index 0000000000..49349b01e1
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a58292341785cb260dc0ccf346259e35e2817ee48fc401a21ab528f6afb97b52
+size 3551
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignIn/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly
new file mode 100644
index 0000000000..3500584d99
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/ClientAuthPasswordSignUp.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f3d5121b26608b02747e245071ccff29ac57358cb6349ec9495a7a003ac12467
+size 8942
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas
new file mode 100644
index 0000000000..632d27d5b0
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/PasswordSignUp.scriptcanvas
@@ -0,0 +1,4408 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml
new file mode 100644
index 0000000000..a9b73a9fb3
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak
new file mode 100644
index 0000000000..85d3c59f9b
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:605391d415b828b100bada11d108099520c0b6a020f17588887b610475805d90
+size 3546
diff --git a/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/tags.txt b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/ClientAuthPasswordSignUp/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/Levels/AWS/Metrics/Metrics.ly b/AutomatedTesting/Levels/AWS/Metrics/Metrics.ly
new file mode 100644
index 0000000000..12998e89be
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Metrics/Metrics.ly
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:023992998ab5a1d64b38dacd1d5e1a9dc930ff704289c0656ed6eaba6951d660
+size 9066
diff --git a/AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua b/AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua
new file mode 100644
index 0000000000..42484ff4e5
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Metrics/Script/Metrics.lua
@@ -0,0 +1,79 @@
+----------------------------------------------------------------------------------------------------
+--
+-- 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.
+--
+--
+----------------------------------------------------------------------------------------------------
+local metrics = {
+}
+
+function metrics:OnActivate()
+ self.tickTime = 0
+ self.numSubmittedMetricsEvents = 0
+
+ self.tickBusHandler = TickBus.Connect(self,self.entityId)
+ self.metricsNotificationHandler = AWSMetricsNotificationBus.Connect(self, self.entityId)
+
+ LyShineLua.ShowMouseCursor(true)
+end
+
+function metrics:OnSendMetricsSuccess(requestId)
+ Debug.Log("Metrics is sent successfully.")
+end
+
+function metrics:OnSendMetricsFailure(requestId, errorMessage)
+ Debug.Log("Failed to send metrics.")
+end
+
+function metrics:OnDeactivate()
+ AWSMetricsRequestBus.Broadcast.FlushMetrics()
+ Debug.Log("Stop generating new test events and flushed the buffered metrics.")
+
+ self.tickBusHandler:Disconnect()
+ self.metricsNotificationHandler:Disconnect()
+end
+
+function metrics:OnTick(deltaTime, timePoint)
+ self.tickTime = self.tickTime + deltaTime
+
+ if self.tickTime > 2.0 then
+ defaultAttribute = AWSMetrics_MetricsAttribute()
+ defaultAttribute:SetName("event_name")
+ defaultAttribute:SetStrValue("login")
+
+ customAttribute = AWSMetrics_MetricsAttribute()
+ customAttribute:SetName("custom_attribute")
+ customAttribute:SetStrValue("value")
+
+ attributeList = AWSMetrics_AttributesSubmissionList()
+ attributeList.attributes:push_back(defaultAttribute)
+ attributeList.attributes:push_back(customAttribute)
+
+
+ if self.numSubmittedMetricsEvents % 2 == 0 then
+ if AWSMetricsRequestBus.Broadcast.SubmitMetrics(attributeList.attributes, 0, "lua", false) then
+ Debug.Log("Submitted metrics without buffer.")
+ else
+ Debug.Log("Failed to Submit metrics without buffer.")
+ end
+ else
+ if AWSMetricsRequestBus.Broadcast.SubmitMetrics(attributeList.attributes, 0, "lua", true) then
+ Debug.Log("Submitted metrics with buffer.")
+ else
+ Debug.Log("Failed to Submit metrics with buffer.")
+ end
+ end
+
+ self.numSubmittedMetricsEvents = self.numSubmittedMetricsEvents + 1
+ self.tickTime = 0
+ end
+end
+
+return metrics
diff --git a/AutomatedTesting/Levels/AWS/Metrics/filelist.xml b/AutomatedTesting/Levels/AWS/Metrics/filelist.xml
new file mode 100644
index 0000000000..3539102346
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Metrics/filelist.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/AutomatedTesting/Levels/AWS/Metrics/level.pak b/AutomatedTesting/Levels/AWS/Metrics/level.pak
new file mode 100644
index 0000000000..fd1f5ac6ad
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Metrics/level.pak
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e7c0c07b13bb64db344b94d5712e1e802e607a9dee506768b34481f4a76d8505
+size 3593
diff --git a/AutomatedTesting/Levels/AWS/Metrics/tags.txt b/AutomatedTesting/Levels/AWS/Metrics/tags.txt
new file mode 100644
index 0000000000..0d6c1880e7
--- /dev/null
+++ b/AutomatedTesting/Levels/AWS/Metrics/tags.txt
@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly
index 1afbf787db..9a1b1fe59a 100644
--- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly
+++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/C18977329_NvCloth_AddClothSimulationToMesh.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:e15d484113e8151072b410924747a8ad304f6f12457fad577308c0491693ab34
-size 5472
+oid sha256:6517300fb1ce70c4696286e14715c547cfd175eabbb2042f7f2a456b15054224
+size 5253
diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml
index 9775a35c53..2cf4d55bf0 100644
--- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml
+++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/filelist.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak
index 08a775b6c8..954bb1912f 100644
--- a/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak
+++ b/AutomatedTesting/Levels/NvCloth/C18977329_NvCloth_AddClothSimulationToMesh/level.pak
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:64de37c805b0be77cdb7a85b5406af58b7f845e7d97fec1721ac5d789bb641db
-size 38856
+oid sha256:ce32a7cdf3ed37751385b3bb18f05206702978363f325d06727b5eb20d40b7eb
+size 38563
diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly
index 385027c479..9ef8bc0525 100644
--- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly
+++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/C18977330_NvCloth_AddClothSimulationToActor.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7b595323d4d51211463dea0338abb6ce2a4a0a8d41efb12ac3c9dccd1f972171
-size 5504
+oid sha256:89dbcec013cb819e52ec0f8fed0a9e417fd32eac8aeb67d3958266bb6089ec21
+size 5505
diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml
index 7ccc1d51eb..a7de99a91c 100644
--- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml
+++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/filelist.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak
index 12ce03fa87..ad10c72b31 100644
--- a/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak
+++ b/AutomatedTesting/Levels/NvCloth/C18977330_NvCloth_AddClothSimulationToActor/level.pak
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:617c455668fc41cb7fd69de690e4aa3c80f2cb36deaa371902b79de18fcd1cb2
-size 39233
+oid sha256:622c2624b04e07b704520f32c458b50d5a50de1ef116b7bc9c3c0ccb6f4a4ecc
+size 3606
diff --git a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly b/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly
index a649728997..87166a9d8d 100644
--- a/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly
+++ b/AutomatedTesting/Levels/Physics/C5340400_RigidBody_ManualMomentOfInertia/C5340400_RigidBody_ManualMomentOfInertia.ly
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b6e408095c15a388768b7f70b6049f33c894aab3e51f2d744bc1ae1d18668ee4
-size 9694
+oid sha256:824a51a375f19274d5698ff08af0fdc3dc18204505c73a943de748455d108b01
+size 6181
diff --git a/AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override b/AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override
new file mode 100644
index 0000000000..a329434623
--- /dev/null
+++ b/AutomatedTesting/Registry/C15556261_PhysXMaterials_CharacterControllerMaterialAssignment.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{70D4A444-AFD4-57C4-9885-63F25AC3C281}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c15556261_physxmaterials_charactercontrollermaterialassignment/library.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override b/AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override
new file mode 100644
index 0000000000..44a91c67cb
--- /dev/null
+++ b/AutomatedTesting/Registry/C18977601_Material_FrictionCombinePriority.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{B8749DAB-15DA-5A61-B565-C853673604CD}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c18977601_material_frictioncombinepriority/friction_combine.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override b/AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override
new file mode 100644
index 0000000000..8de10787f1
--- /dev/null
+++ b/AutomatedTesting/Registry/C18981526_Material_RestitutionCombinePriority.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{AED48B18-0F3F-5E59-A8FF-30DB134B307B}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c18981526_material_restitutioncombinepriority/restitution_combine.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override b/AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override
new file mode 100644
index 0000000000..83f7079e1f
--- /dev/null
+++ b/AutomatedTesting/Registry/C4044456_Material_FrictionCombine.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{8D2C4A29-E0FC-564F-82C9-24BBA30C5A90}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c4044456_material_frictioncombine/friction_combine.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override b/AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override
new file mode 100644
index 0000000000..96836b6ae4
--- /dev/null
+++ b/AutomatedTesting/Registry/C4044457_Material_RestitutionCombine.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{D5D6A6DE-E636-5638-B30D-6CE2FDC321F8}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c4044457_material_restitutioncombine/restitution_combine.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override b/AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override
new file mode 100644
index 0000000000..21b285506b
--- /dev/null
+++ b/AutomatedTesting/Registry/C4044461_Material_Restitution.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{E4117B5B-8D9A-5C1D-BA1E-C36542A6588D}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c4044461_material_restitution/restitution.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override b/AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override
new file mode 100644
index 0000000000..d585a4c468
--- /dev/null
+++ b/AutomatedTesting/Registry/C4044697_Material_PerfaceMaterialValidation.setreg_override
@@ -0,0 +1,115 @@
+{
+ "Amazon": {
+ "Gems": {
+ "PhysX": {
+ "PhysXSystemConfiguration": {
+ "CollisionConfig": {
+ "Layers": {
+ "LayerNames": [
+ "Default",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ "TouchBend"
+ ]
+ },
+ "Groups": {
+ "GroupPresets": [
+ {
+ "Name": "All",
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{CDB6B8D8-5CD0-40A8-874D-839B00A92EBB}"
+ },
+ "Name": "None",
+ "Group": {
+ "Mask": 0
+ },
+ "ReadOnly": true
+ },
+ {
+ "Id": {
+ "GroupId": "{22769429-5D46-429B-829A-0115239D9AAA}"
+ },
+ "Name": "All_NoTouchBend",
+ "Group": {
+ "Mask": 9223372036854775807
+ },
+ "ReadOnly": true
+ }
+ ]
+ }
+ },
+ "MaterialLibrary": {
+ "assetId": {
+ "guid": "{2E85B457-ED19-5FE3-90B4-6EFFB4D0E682}"
+ },
+ "loadBehavior": "QueueLoad",
+ "assetHint": "levels/physics/c4044697_material_perfacematerialvalidation/test_library.physmaterial"
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas b/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas
index b24a477a2e..9b1357eebe 100644
--- a/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas
+++ b/AutomatedTesting/ScriptCanvas/C12712455_ScriptCanvas_ShapeCastVerification.scriptcanvas
@@ -3,34 +3,158 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -41,7 +165,7 @@
-
+
@@ -65,9 +189,374 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -75,7 +564,7 @@
-
+
@@ -278,21 +767,21 @@
-
+
-
+
-
+
@@ -335,7 +824,7 @@
-
+
@@ -378,7 +867,7 @@
-
+
@@ -416,227 +905,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -713,21 +982,12 @@
-
+
-
-
-
-
-
-
-
-
-
-
+
@@ -1321,7 +1581,7 @@
-
+
@@ -1386,598 +1646,21 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
@@ -2020,7 +1703,7 @@
-
+
@@ -2063,7 +1746,7 @@
-
+
@@ -2101,7 +1784,7 @@
-
+
@@ -2178,125 +1861,340 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
-
+
-
+
-
+
@@ -2309,79 +2207,17 @@
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -2389,10 +2225,10 @@
-
+
-
+
@@ -2402,17 +2238,48 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -2420,7 +2287,7 @@
-
+
@@ -2433,28 +2300,152 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2470,7 +2461,7 @@
-
+
@@ -2478,49 +2469,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -2528,7 +2477,7 @@
-
+
@@ -2545,37 +2494,16 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -2583,7 +2511,7 @@
-
+
@@ -2591,229 +2519,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -2823,11 +2529,296 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -2837,14 +2828,6 @@
-
-
-
-
-
-
-
-
@@ -2853,6 +2836,14 @@
+
+
+
+
+
+
+
+
@@ -2868,7 +2859,7 @@
-
+
diff --git a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp
index 3f7a3c3a5d..0d45a3fb6c 100644
--- a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.cpp
@@ -36,6 +36,12 @@ namespace AZ
Color* color = reinterpret_cast(outputValue);
AZ_Assert(color, "Output value for JsonColorSerializer can't be null.");
+ if (IsExplicitDefault(inputValue))
+ {
+ *color = Color::CreateZero();
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Color value set to default of zero.");
+ }
+
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
@@ -43,10 +49,14 @@ namespace AZ
case rapidjson::kObjectType:
return LoadObject(*color, inputValue, context);
- case rapidjson::kStringType: // fall through
- case rapidjson::kNumberType: // fall through
- case rapidjson::kNullType: // fall through
- case rapidjson::kFalseType: // fall through
+ case rapidjson::kStringType:
+ [[fallthrough]];
+ case rapidjson::kNumberType:
+ [[fallthrough]];
+ case rapidjson::kNullType:
+ [[fallthrough]];
+ case rapidjson::kFalseType:
+ [[fallthrough]];
case rapidjson::kTrueType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. Colors can only be read from arrays or objects.");
@@ -91,6 +101,11 @@ namespace AZ
}
}
+ auto JsonColorSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
JsonSerializationResult::Result JsonColorSerializer::LoadObject(Color& output, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
diff --git a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h
index b7b948a25a..cd16506b28 100644
--- a/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Math/ColorSerializer.h
@@ -28,6 +28,8 @@ namespace AZ
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
+
private:
enum class LoadAlpha
{
diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp
index 0b7e3300cf..7f412f68e6 100644
--- a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.cpp
@@ -263,7 +263,7 @@ namespace AZ::JsonMathMatrixSerializerInternal
template
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId,
- const rapidjson::Value& inputValue, JsonDeserializerContext& context)
+ const rapidjson::Value& inputValue, JsonDeserializerContext& context, bool isExplicitDefault)
{
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
@@ -279,6 +279,12 @@ namespace AZ::JsonMathMatrixSerializerInternal
MatrixType* matrix = reinterpret_cast(outputValue);
AZ_Assert(matrix, "Output value for JsonMatrix%zux%zuSerializer can't be null.", RowCount, ColumnCount);
+ if (isExplicitDefault)
+ {
+ *matrix = MatrixType::CreateIdentity();
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Matrix value set to identity matrix.");
+ }
+
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
@@ -381,6 +387,16 @@ namespace AZ::JsonMathMatrixSerializerInternal
namespace AZ
{
+ // BaseJsonMatrixSerializer
+
+ AZ_CLASS_ALLOCATOR_IMPL(BaseJsonMatrixSerializer, SystemAllocator, 0);
+
+ auto BaseJsonMatrixSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
+
// Matrix3x3
AZ_CLASS_ALLOCATOR_IMPL(JsonMatrix3x3Serializer, SystemAllocator, 0);
@@ -389,10 +405,7 @@ namespace AZ
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
return JsonMathMatrixSerializerInternal::Load(
- outputValue,
- outputValueTypeId,
- inputValue,
- context);
+ outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonMatrix3x3Serializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -401,11 +414,7 @@ namespace AZ
outputValue.SetObject();
return JsonMathMatrixSerializerInternal::StoreRotationAndScale(
- outputValue,
- inputValue,
- defaultValue,
- valueTypeId,
- context);
+ outputValue, inputValue, defaultValue, valueTypeId, context);
}
@@ -417,10 +426,7 @@ namespace AZ
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
return JsonMathMatrixSerializerInternal::Load(
- outputValue,
- outputValueTypeId,
- inputValue,
- context);
+ outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonMatrix3x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -428,19 +434,11 @@ namespace AZ
{
outputValue.SetObject();
- auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale(
- outputValue,
- inputValue,
- defaultValue,
- valueTypeId,
- context);
+ auto result =
+ JsonMathMatrixSerializerInternal::StoreRotationAndScale(outputValue, inputValue, defaultValue, valueTypeId, context);
- auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation(
- outputValue,
- inputValue,
- defaultValue,
- valueTypeId,
- context);
+ auto resultTranslation =
+ JsonMathMatrixSerializerInternal::StoreTranslation(outputValue, inputValue, defaultValue, valueTypeId, context);
result.GetResultCode().Combine(resultTranslation);
return result;
@@ -454,10 +452,7 @@ namespace AZ
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
return JsonMathMatrixSerializerInternal::Load(
- outputValue,
- outputValueTypeId,
- inputValue,
- context);
+ outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonMatrix4x4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -465,19 +460,11 @@ namespace AZ
{
outputValue.SetObject();
- auto result = JsonMathMatrixSerializerInternal::StoreRotationAndScale(
- outputValue,
- inputValue,
- defaultValue,
- valueTypeId,
- context);
+ auto result =
+ JsonMathMatrixSerializerInternal::StoreRotationAndScale(outputValue, inputValue, defaultValue, valueTypeId, context);
- auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation(
- outputValue,
- inputValue,
- defaultValue,
- valueTypeId,
- context);
+ auto resultTranslation =
+ JsonMathMatrixSerializerInternal::StoreTranslation(outputValue, inputValue, defaultValue, valueTypeId, context);
result.GetResultCode().Combine(resultTranslation);
return result;
diff --git a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h
index 81c9635a79..773859a2c8 100644
--- a/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Math/MathMatrixSerializer.h
@@ -16,11 +16,18 @@
namespace AZ
{
- class JsonMatrix3x3Serializer
- : public BaseJsonSerializer
+ class BaseJsonMatrixSerializer : public BaseJsonSerializer
{
public:
- AZ_RTTI(JsonMatrix3x3Serializer, "{8C76CD6A-8576-4604-A746-CF7A7F20F366}", BaseJsonSerializer);
+ AZ_RTTI(BaseJsonMatrixSerializer, "{18CA4637-C9B7-454B-9126-107E18A8C096}", BaseJsonSerializer);
+ AZ_CLASS_ALLOCATOR_DECL;
+ OperationFlags GetOperationsFlags() const override;
+ };
+
+ class JsonMatrix3x3Serializer : public BaseJsonMatrixSerializer
+ {
+ public:
+ AZ_RTTI(JsonMatrix3x3Serializer, "{8C76CD6A-8576-4604-A746-CF7A7F20F366}", BaseJsonMatrixSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -28,11 +35,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonMatrix3x4Serializer
- : public BaseJsonSerializer
+ class JsonMatrix3x4Serializer : public BaseJsonMatrixSerializer
{
public:
- AZ_RTTI(JsonMatrix3x4Serializer, "{E801333B-4AF1-4F43-976C-579670B02DC5}", BaseJsonSerializer);
+ AZ_RTTI(JsonMatrix3x4Serializer, "{E801333B-4AF1-4F43-976C-579670B02DC5}", BaseJsonMatrixSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -40,11 +46,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonMatrix4x4Serializer
- : public BaseJsonSerializer
+ class JsonMatrix4x4Serializer : public BaseJsonMatrixSerializer
{
public:
- AZ_RTTI(JsonMatrix4x4Serializer, "{46E888FC-248A-4910-9221-4E101A10AEA1}", BaseJsonSerializer);
+ AZ_RTTI(JsonMatrix4x4Serializer, "{46E888FC-248A-4910-9221-4E101A10AEA1}", BaseJsonMatrixSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
diff --git a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp
index aa9686f709..7225f1713c 100644
--- a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.cpp
@@ -124,7 +124,7 @@ namespace AZ
template
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
- JsonDeserializerContext& context)
+ JsonDeserializerContext& context, bool isExplicitDefault)
{
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
@@ -138,6 +138,12 @@ namespace AZ
VectorType* vector = reinterpret_cast(outputValue);
AZ_Assert(vector, "Output value for JsonVector%iSerializer can't be null.", ElementCount);
+ if (isExplicitDefault)
+ {
+ *vector = VectorType::CreateZero();
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Math vector value set to default of zero.");
+ }
+
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
@@ -145,10 +151,14 @@ namespace AZ
case rapidjson::kObjectType:
return LoadObject(*vector, inputValue, context);
- case rapidjson::kStringType: // fall through
- case rapidjson::kNumberType: // fall through
- case rapidjson::kNullType: // fall through
- case rapidjson::kFalseType: // fall through
+ case rapidjson::kStringType:
+ [[fallthrough]];
+ case rapidjson::kNumberType:
+ [[fallthrough]];
+ case rapidjson::kNullType:
+ [[fallthrough]];
+ case rapidjson::kFalseType:
+ [[fallthrough]];
case rapidjson::kTrueType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. Math vectors can only be read from arrays or objects.");
@@ -189,6 +199,16 @@ namespace AZ
}
}
+
+ // BaseJsonVectorSerializer
+
+ AZ_CLASS_ALLOCATOR_IMPL(BaseJsonVectorSerializer, SystemAllocator, 0);
+
+ auto BaseJsonVectorSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
// Vector2
@@ -197,7 +217,8 @@ namespace AZ
JsonSerializationResult::Result JsonVector2Serializer::Load(void* outputValue, const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
- return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context);
+ return JsonMathVectorSerializerInternal::Load(
+ outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonVector2Serializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -214,7 +235,8 @@ namespace AZ
JsonSerializationResult::Result JsonVector3Serializer::Load(void* outputValue, const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
- return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context);
+ return JsonMathVectorSerializerInternal::Load(
+ outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonVector3Serializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -231,7 +253,8 @@ namespace AZ
JsonSerializationResult::Result JsonVector4Serializer::Load(void* outputValue, const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
- return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context);
+ return JsonMathVectorSerializerInternal::Load(
+ outputValue, outputValueTypeId, inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonVector4Serializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -252,7 +275,7 @@ namespace AZ
// check for "yaw, pitch, roll" object
if (inputValue.IsObject())
{
- if (inputValue.GetObject().ObjectEmpty())
+ if (IsExplicitDefault(inputValue))
{
Quaternion* outQuaternion = reinterpret_cast(outputValue);
*outQuaternion = Quaternion::CreateIdentity();
@@ -283,7 +306,7 @@ namespace AZ
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read quaternion.");
}
- return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context);
+ return JsonMathVectorSerializerInternal::Load(outputValue, outputValueTypeId, inputValue, context, false);
}
JsonSerializationResult::Result JsonQuaternionSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
diff --git a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h
index 9c2606b932..0f81709c17 100644
--- a/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Math/MathVectorSerializer.h
@@ -16,11 +16,18 @@
namespace AZ
{
- class JsonVector2Serializer
- : public BaseJsonSerializer
+ class BaseJsonVectorSerializer : public BaseJsonSerializer
{
public:
- AZ_RTTI(JsonVector2Serializer, "{E1EAA209-9682-4120-B26B-3EDD9AD56D6F}", BaseJsonSerializer);
+ AZ_RTTI(BaseJsonVectorSerializer, "{C188D355-E6DF-4590-8B31-F40591F48A8E}", BaseJsonSerializer);
+ AZ_CLASS_ALLOCATOR_DECL;
+ OperationFlags GetOperationsFlags() const override;
+ };
+
+ class JsonVector2Serializer : public BaseJsonVectorSerializer
+ {
+ public:
+ AZ_RTTI(JsonVector2Serializer, "{E1EAA209-9682-4120-B26B-3EDD9AD56D6F}", BaseJsonVectorSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -28,11 +35,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonVector3Serializer
- : public BaseJsonSerializer
+ class JsonVector3Serializer : public BaseJsonVectorSerializer
{
public:
- AZ_RTTI(JsonVector3Serializer, "{BF82BBF3-3CD9-48DA-97CC-E4DF2EF01552}", BaseJsonSerializer);
+ AZ_RTTI(JsonVector3Serializer, "{BF82BBF3-3CD9-48DA-97CC-E4DF2EF01552}", BaseJsonVectorSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -40,11 +46,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonVector4Serializer
- : public BaseJsonSerializer
+ class JsonVector4Serializer : public BaseJsonVectorSerializer
{
public:
- AZ_RTTI(JsonVector4Serializer, "{05B45EA7-7102-4281-8AA0-2AC72D74AAFD}", BaseJsonSerializer);
+ AZ_RTTI(JsonVector4Serializer, "{05B45EA7-7102-4281-8AA0-2AC72D74AAFD}", BaseJsonVectorSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -52,11 +57,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonQuaternionSerializer
- : public BaseJsonSerializer
+ class JsonQuaternionSerializer : public BaseJsonVectorSerializer
{
public:
- AZ_RTTI(JsonQuaternionSerializer, "{18604375-3606-49AC-B366-0F6DF9149FF3}", BaseJsonSerializer);
+ AZ_RTTI(JsonQuaternionSerializer, "{18604375-3606-49AC-B366-0F6DF9149FF3}", BaseJsonVectorSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp
index 36c40265af..b3c9ea3b7c 100644
--- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.cpp
@@ -33,6 +33,12 @@ namespace AZ
AZ::Transform* transformInstance = reinterpret_cast(outputValue);
AZ_Assert(transformInstance, "Output value for JsonTransformSerializer can't be null.");
+ if (IsExplicitDefault(inputValue))
+ {
+ *transformInstance = AZ::Transform::CreateIdentity();
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Transform value set to identity.");
+ }
+
JSR::ResultCode result(JSR::Tasks::ReadField);
{
@@ -72,7 +78,7 @@ namespace AZ
return context.Report(
result,
- result.GetProcessing() != JSR::Processing::Halted ? "Succesfully loaded Transform information."
+ result.GetProcessing() != JSR::Processing::Halted ? "Successfully loaded Transform information."
: "Failed to load Transform information.");
}
@@ -140,4 +146,9 @@ namespace AZ
: "Failed to store Transform information.");
}
+ auto JsonTransformSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h
index e03c41e31d..ef277f831a 100644
--- a/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Math/TransformSerializer.h
@@ -30,6 +30,8 @@ namespace AZ
rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue, const Uuid& valueTypeId,
JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
+
private:
// Note: These need to be defined as "const char[]" instead of "const char*" so that they can be implicitly converted
// to a rapidjson::GenericStringRef<>. (This also lets rapidjson get the string length at compile time)
diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp
index 9da7b11805..458744d5b2 100644
--- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.cpp
@@ -33,6 +33,11 @@ namespace AZ
AZStd::regex_constants::icase | AZStd::regex_constants::optimize);
}
+ auto JsonUuidSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
JsonSerializationResult::Result JsonUuidSerializer::Load(void* outputValue, const Uuid& outputValueTypeId,
const rapidjson::Value& inputValue, JsonDeserializerContext& context)
{
@@ -53,13 +58,24 @@ namespace AZ
Uuid* valAsUuid = reinterpret_cast(outputValue);
+ if (IsExplicitDefault(inputValue))
+ {
+ *valAsUuid = AZ::Uuid::CreateNull();
+ return MessageResult("Uuid value set to default of null.", JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed));
+ }
+
switch (inputValue.GetType())
{
- case rapidjson::kArrayType: // fallthrough
- case rapidjson::kObjectType:// fallthrough
- case rapidjson::kFalseType: // fallthrough
- case rapidjson::kTrueType: // fallthrough
- case rapidjson::kNumberType:// fallthrough
+ case rapidjson::kArrayType:
+ [[fallthrough]];
+ case rapidjson::kObjectType:
+ [[fallthrough]];
+ case rapidjson::kFalseType:
+ [[fallthrough]];
+ case rapidjson::kTrueType:
+ [[fallthrough]];
+ case rapidjson::kNumberType:
+ [[fallthrough]];
case rapidjson::kNullType:
return MessageResult("Unsupported type. Uuids can only be read from strings.",
JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported));
diff --git a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h
index 1c350a2fcd..43487dcc10 100644
--- a/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Math/UuidSerializer.h
@@ -41,6 +41,8 @@ namespace AZ
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
+
//! Does the same as load, but doesn't report through the provided callback in the settings. Instead the final
//! ResultCode and message are returned and it's up to the caller to report if need needed.
MessageResult UnreportedLoad(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue);
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp
index d5a1730364..2e53eb5697 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.cpp
@@ -32,13 +32,24 @@ namespace AZ
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
- return LoadContainer(outputValue, outputValueTypeId, inputValue, context);
+ return LoadContainer(outputValue, outputValueTypeId, inputValue, false, context);
- case rapidjson::kObjectType: // fall through
- case rapidjson::kNullType: // fall through
- case rapidjson::kStringType: // fall through
- case rapidjson::kFalseType: // fall through
- case rapidjson::kTrueType: // fall through
+ case rapidjson::kObjectType:
+ if (IsExplicitDefault(inputValue))
+ {
+ // Because this serializer has only the operation flag "InitializeNewInstance" set, the only time this will be called with
+ // an explicit default is when a new instance has been created.
+ return LoadContainer(outputValue, outputValueTypeId, inputValue, true, context);
+ }
+ [[fallthrough]];
+ case rapidjson::kNullType:
+ [[fallthrough]];
+ case rapidjson::kStringType:
+ [[fallthrough]];
+ case rapidjson::kFalseType:
+ [[fallthrough]];
+ case rapidjson::kTrueType:
+ [[fallthrough]];
case rapidjson::kNumberType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. AZStd::array entries can only be read from an array.");
@@ -129,7 +140,16 @@ namespace AZ
}
}
- JsonSerializationResult::Result JsonArraySerializer::LoadContainer(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
+ auto JsonArraySerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
+ JsonSerializationResult::Result JsonArraySerializer::LoadContainer(
+ void* outputValue,
+ const Uuid& outputValueTypeId,
+ const rapidjson::Value& inputValue,
+ bool isNewInstance,
JsonDeserializerContext& context)
{
namespace JSR = JsonSerializationResult; // Used to remove name conflicts in AzCore in uber builds.
@@ -154,14 +174,7 @@ namespace AZ
"Unable to retrieve the correct container information for AZStd::array instance.");
}
- const size_t size = container->Size(outputValue);
- if (inputValue.Size() < size)
- {
- return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
- "Not enough entries in JSON array to load an AZStd::array from.");
- }
-
- ContinuationFlags flags = ContinuationFlags::None;
+ ContinuationFlags flags = isNewInstance ? ContinuationFlags::LoadAsNewInstance : ContinuationFlags::None;
Uuid elementTypeId = Uuid::CreateNull();
auto typeEnumCallback = [&elementTypeId, &flags](const Uuid&, const SerializeContext::ClassElement* genericClassElement)
{
@@ -175,13 +188,23 @@ namespace AZ
};
container->EnumTypes(typeEnumCallback);
+ const size_t size = container->Size(outputValue);
+ if (!isNewInstance && inputValue.Size() < size)
+ {
+ return context.Report(
+ JSR::Tasks::ReadField, JSR::Outcomes::Unsupported, "Not enough entries in JSON array to load an AZStd::array from.");
+ }
+
+ rapidjson::Value explicitDefaultValue = GetExplicitDefault();
+
JSR::ResultCode retVal(JSR::Tasks::ReadField);
for (size_t i = 0; i < size; ++i)
{
ScopedContextPath subPath(context, i);
void* element = container->GetElementByIndex(outputValue, nullptr, i);
- JSR::ResultCode result = ContinueLoading(element, elementTypeId, inputValue[aznumeric_caster(i)], context, flags);
+ JSR::ResultCode result = ContinueLoading(
+ element, elementTypeId, isNewInstance ? explicitDefaultValue : inputValue[aznumeric_caster(i)], context, flags);
if (result.GetProcessing() == JSR::Processing::Halted)
{
return context.Report(result, "Failed to load data to element in AZStd::array.");
@@ -189,15 +212,19 @@ namespace AZ
retVal.Combine(result);
}
- if (container->Size(outputValue) == inputValue.Size())
+ if (isNewInstance)
+ {
+ return context.Report(retVal, "Filled new instance of AZStd::array with defaults.");
+ }
+ else if (container->Size(outputValue) == inputValue.Size())
{
return context.Report(retVal, "Successfully read entries into AZStd::array.");
}
else
{
retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Skipped));
- return context.Report(retVal,
- "Successfully read available entries into AZStd::array, but there were still values left in the JSON array.");
+ return context.Report(
+ retVal, "Successfully read available entries into AZStd::array, but there were still values left in the JSON array.");
}
}
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h
index 11edc87139..a6d8dd37e3 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/ArraySerializer.h
@@ -30,8 +30,14 @@ namespace AZ
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
+
protected:
- JsonSerializationResult::Result LoadContainer(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
+ JsonSerializationResult::Result LoadContainer(
+ void* outputValue,
+ const Uuid& outputValueTypeId,
+ const rapidjson::Value& inputValue,
+ bool isNewInstance,
JsonDeserializerContext& context);
};
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp
index 9a426a1e59..666fa0f96a 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp
@@ -216,9 +216,10 @@ namespace AZ
JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueLoading(
void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags)
{
+ bool loadAsNewInstance = (flags & ContinuationFlags::LoadAsNewInstance) == ContinuationFlags::LoadAsNewInstance;
return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer
? JsonDeserializer::LoadToPointer(object, typeId, value, context)
- : JsonDeserializer::Load(object, typeId, value, context);
+ : JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, context);
}
JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring(
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h
index 06c5eda6de..99b63bf4de 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h
@@ -163,15 +163,20 @@ namespace AZ
enum class ContinuationFlags
{
- None = 0, //! No extra flags.
- ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance.
- ReplaceDefault = 1 << 1 //! The default value provided for storing will be replaced with a newly created one.
+ None = 0, //! No extra flags.
+ ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance.
+ ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one.
+ LoadAsNewInstance = 1 << 2 //! Treats the value as if it's a newly created instance. This may trigger serializers marked with
+ //! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to
+ //! an array.
};
enum class OperationFlags
{
- None = 0, //! No flags that control how the custom json serializer is used.
- ManualDefault = 1 << 0 //! Even if an (explicit) default is found the custom json serializer will still be called.
+ None = 0, //! No flags that control how the custom json serializer is used.
+ ManualDefault = 1 << 0, //! Even if an (explicit) default is found the custom json serializer will still be called.
+ InitializeNewInstance = 1 << 1 //! If set, the custom json serializer will be called with an explicit default if a new
+ //! instance of its target type is created.
};
virtual ~BaseJsonSerializer() = default;
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp
index 400a3b7949..d61366413f 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BasicContainerSerializer.cpp
@@ -34,11 +34,16 @@ namespace AZ
case rapidjson::kArrayType:
return LoadContainer(outputValue, outputValueTypeId, inputValue, context);
- case rapidjson::kObjectType: // fall through
- case rapidjson::kNullType: // fall through
- case rapidjson::kStringType: // fall through
- case rapidjson::kFalseType: // fall through
- case rapidjson::kTrueType: // fall through
+ case rapidjson::kObjectType:
+ [[fallthrough]];
+ case rapidjson::kNullType:
+ [[fallthrough]];
+ case rapidjson::kStringType:
+ [[fallthrough]];
+ case rapidjson::kFalseType:
+ [[fallthrough]];
+ case rapidjson::kTrueType:
+ [[fallthrough]];
case rapidjson::kNumberType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. Basic containers can only be read from an array.");
@@ -123,6 +128,10 @@ namespace AZ
{
if (retVal.HasDoneWork())
{
+ // If at least one value was written, even if it has all defaults, then the array has
+ // a value written to it and is therefore not in a default state anymore.
+ retVal.Combine(JSR::ResultCode(JSR::Tasks::WriteValue, JSR::Outcomes::Success));
+
outputValue = AZStd::move(array);
return context.Report(retVal, "Content written to basic container.");
}
@@ -165,6 +174,7 @@ namespace AZ
ContinuationFlags flags = classElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER
? ContinuationFlags::ResolvePointer
: ContinuationFlags::None;
+ flags |= ContinuationFlags::LoadAsNewInstance;
const size_t capacity = container->IsFixedCapacity() ? container->Capacity(outputValue) : std::numeric_limits::max();
@@ -243,6 +253,11 @@ namespace AZ
}
size_t addedCount = container->Size(outputValue) - containerSize;
+ if (addedCount > 0)
+ {
+ // Values were added which means the container is no longer in its default state of being empty.
+ retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success));
+ }
AZStd::string_view message =
addedCount >= arraySize ? "Successfully read basic container.":
addedCount == 0 ? "Unable to read data for basic container." :
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp
index d37e512ac2..3a9b5323b0 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.cpp
@@ -82,12 +82,18 @@ namespace AZ
bool* valAsBool = reinterpret_cast(outputValue);
+ if (IsExplicitDefault(inputValue))
+ {
+ *valAsBool = {};
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Boolean value set to default of 'false'.");
+ }
+
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kObjectType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kNullType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. Booleans can't be read from arrays, objects or null.");
@@ -96,7 +102,7 @@ namespace AZ
return SerializerInternal::TextToValue(valAsBool, inputValue.GetString(), inputValue.GetStringLength(), context);
case rapidjson::kFalseType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kTrueType:
*valAsBool = inputValue.GetBool();
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success, "Successfully read boolean.");
@@ -145,4 +151,9 @@ namespace AZ
return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "Default boolean used.");
}
+
+ auto JsonBoolSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h
index ac288c73ed..f000a03317 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BoolSerializer.h
@@ -27,5 +27,6 @@ namespace AZ
JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
};
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp
index 9140be7fcd..0921587041 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.cpp
@@ -62,19 +62,26 @@ namespace AZ
}
template
- static JsonSerializationResult::Result Load(T* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context)
+ static JsonSerializationResult::Result Load(
+ T* outputValue, const rapidjson::Value& inputValue, JsonDeserializerContext& context, bool isExplicitDefault)
{
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
static_assert(AZStd::is_floating_point::value, "Expected T to be a floating point type");
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
+ if (isExplicitDefault)
+ {
+ *outputValue = {};
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Floating point value set to default of 0.0.");
+ }
+
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kObjectType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kNullType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. Floating point values can't be read from arrays, objects or null.");
@@ -83,7 +90,7 @@ namespace AZ
return TextToValue(outputValue, inputValue.GetString(), context);
case rapidjson::kFalseType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kTrueType:
*outputValue = inputValue.GetBool() ? 1.0f : 0.0f;
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success,
@@ -144,7 +151,8 @@ namespace AZ
"Unable to deserialize double to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerFloatingPointInternal::Load(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerFloatingPointInternal::Load(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonDoubleSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -156,6 +164,11 @@ namespace AZ
return SerializerFloatingPointInternal::Store(outputValue, inputValue, defaultValue, context);
}
+ auto JsonDoubleSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
JsonSerializationResult::Result JsonFloatSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
@@ -163,7 +176,8 @@ namespace AZ
"Unable to deserialize float to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerFloatingPointInternal::Load(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerFloatingPointInternal::Load(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonFloatSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -174,4 +188,9 @@ namespace AZ
AZ_UNUSED(valueTypeId);
return SerializerFloatingPointInternal::Store(outputValue, inputValue, defaultValue, context);
}
+
+ auto JsonFloatSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h
index 81e631d9ab..a8c37316f0 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/DoubleSerializer.h
@@ -28,6 +28,7 @@ namespace AZ
JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
};
class JsonFloatSerializer
@@ -40,5 +41,6 @@ namespace AZ
JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
};
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp
index cc365da4f7..a6b1118ac1 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.cpp
@@ -25,6 +25,8 @@
namespace AZ
{
+ AZ_CLASS_ALLOCATOR_IMPL(BaseJsonIntegerSerializer, SystemAllocator, 0);
+
AZ_CLASS_ALLOCATOR_IMPL(JsonCharSerializer, SystemAllocator, 0);
AZ_CLASS_ALLOCATOR_IMPL(JsonShortSerializer, SystemAllocator, 0);
AZ_CLASS_ALLOCATOR_IMPL(JsonIntSerializer, SystemAllocator, 0);
@@ -56,19 +58,25 @@ namespace AZ
template
static JsonSerializationResult::Result LoadInt(T* outputValue, const rapidjson::Value& inputValue,
- JsonDeserializerContext& context)
+ JsonDeserializerContext& context, bool isDefaultValue)
{
namespace JSR = JsonSerializationResult; // Used remove name conflicts in AzCore in uber builds.
static_assert(AZStd::is_integral(), "Expected T to be a signed or unsigned type");
AZ_Assert(outputValue, "Expected a valid pointer to load from json value.");
+ if (isDefaultValue)
+ {
+ *outputValue = {};
+ return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::DefaultsUsed, "Integer value set to default of zero.");
+ }
+
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kObjectType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kNullType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. Integers can't be read from arrays, objects or null.");
@@ -77,7 +85,7 @@ namespace AZ
return TextToValue(outputValue, inputValue.GetString(), context);
case rapidjson::kFalseType:
- // fallthrough
+ [[fallthrough]];
case rapidjson::kTrueType:
*outputValue = inputValue.GetBool() ? 1 : 0;
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Success,
@@ -125,6 +133,11 @@ namespace AZ
}
} // namespace SerializerInternal
+ auto BaseJsonIntegerSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
JsonSerializationResult::Result JsonCharSerializer::Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context)
{
@@ -132,7 +145,7 @@ namespace AZ
"Unable to deserialize char to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonCharSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
@@ -151,7 +164,7 @@ namespace AZ
"Unable to deserialize short to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonShortSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
@@ -170,7 +183,7 @@ namespace AZ
"Unable to deserialize int to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonIntSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
@@ -189,7 +202,7 @@ namespace AZ
"Unable to deserialize long to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
@@ -208,7 +221,7 @@ namespace AZ
"Unable to deserialize long long to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonLongLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
@@ -227,7 +240,8 @@ namespace AZ
"Unable to deserialize unsigned char to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonUnsignedCharSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -246,7 +260,8 @@ namespace AZ
"Unable to deserialize unsigned short to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonUnsignedShortSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -265,7 +280,8 @@ namespace AZ
"Unable to deserialize unsigned int to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonUnsignedIntSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -284,7 +300,8 @@ namespace AZ
"Unable to deserialize unsigned long to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonUnsignedLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
@@ -303,7 +320,8 @@ namespace AZ
"Unable to deserialize unsigned long long to json because the provided type is %s",
outputValueTypeId.ToString().c_str());
AZ_UNUSED(outputValueTypeId);
- return SerializerInternal::LoadInt(reinterpret_cast(outputValue), inputValue, context);
+ return SerializerInternal::LoadInt(
+ reinterpret_cast(outputValue), inputValue, context, IsExplicitDefault(inputValue));
}
JsonSerializationResult::Result JsonUnsignedLongLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h
index 9f522619ae..31d5a4164a 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/IntSerializer.h
@@ -18,11 +18,18 @@
namespace AZ
{
- class JsonCharSerializer
- : public BaseJsonSerializer
+ class BaseJsonIntegerSerializer : public BaseJsonSerializer
{
public:
- AZ_RTTI(JsonCharSerializer, "{CA2A4AAC-3068-40B2-94F8-A537FBA8236E}", BaseJsonSerializer);
+ AZ_RTTI(BaseJsonIntegerSerializer, "{FD060F54-D3B5-4D5B-B64A-AFE371CD6F20}", BaseJsonSerializer);
+ AZ_CLASS_ALLOCATOR_DECL;
+ OperationFlags GetOperationsFlags() const override;
+ };
+
+ class JsonCharSerializer : public BaseJsonIntegerSerializer
+ {
+ public:
+ AZ_RTTI(JsonCharSerializer, "{CA2A4AAC-3068-40B2-94F8-A537FBA8236E}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -30,11 +37,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonShortSerializer
- : public BaseJsonSerializer
+ class JsonShortSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonShortSerializer, "{3D6789BD-231B-4E5D-B81D-609E71A2BCB5}", BaseJsonSerializer);
+ AZ_RTTI(JsonShortSerializer, "{3D6789BD-231B-4E5D-B81D-609E71A2BCB5}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -42,11 +48,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonIntSerializer
- : public BaseJsonSerializer
+ class JsonIntSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonIntSerializer, "{29E26946-0F1F-44B0-A098-1171B7B0C8FA}", BaseJsonSerializer);
+ AZ_RTTI(JsonIntSerializer, "{29E26946-0F1F-44B0-A098-1171B7B0C8FA}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -54,11 +59,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonLongSerializer
- : public BaseJsonSerializer
+ class JsonLongSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonLongSerializer, "{0EB432D0-A0C8-43B2-9D65-A73A4D6DFE3E}", BaseJsonSerializer);
+ AZ_RTTI(JsonLongSerializer, "{0EB432D0-A0C8-43B2-9D65-A73A4D6DFE3E}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -66,11 +70,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonLongLongSerializer
- : public BaseJsonSerializer
+ class JsonLongLongSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonLongLongSerializer, "{5E7967DE-A4DC-40E1-81A1-2896A054BB8A}", BaseJsonSerializer);
+ AZ_RTTI(JsonLongLongSerializer, "{5E7967DE-A4DC-40E1-81A1-2896A054BB8A}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -78,11 +81,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonUnsignedCharSerializer
- : public BaseJsonSerializer
+ class JsonUnsignedCharSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonUnsignedCharSerializer, "{1E6D606F-8490-4736-AAFF-91046FDEA2BB}", BaseJsonSerializer);
+ AZ_RTTI(JsonUnsignedCharSerializer, "{1E6D606F-8490-4736-AAFF-91046FDEA2BB}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -90,11 +92,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonUnsignedShortSerializer
- : public BaseJsonSerializer
+ class JsonUnsignedShortSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonUnsignedShortSerializer, "{3C92D2CC-CB13-4A40-B779-47562EE36451}", BaseJsonSerializer);
+ AZ_RTTI(JsonUnsignedShortSerializer, "{3C92D2CC-CB13-4A40-B779-47562EE36451}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -102,11 +103,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonUnsignedIntSerializer
- : public BaseJsonSerializer
+ class JsonUnsignedIntSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonUnsignedIntSerializer, "{70C0714A-690D-4F30-8986-ABC9DEFE9D62}", BaseJsonSerializer);
+ AZ_RTTI(JsonUnsignedIntSerializer, "{70C0714A-690D-4F30-8986-ABC9DEFE9D62}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -114,11 +114,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonUnsignedLongSerializer
- : public BaseJsonSerializer
+ class JsonUnsignedLongSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonUnsignedLongSerializer, "{28E5499F-6AF4-4778-AE14-66BA40B56247}", BaseJsonSerializer);
+ AZ_RTTI(JsonUnsignedLongSerializer, "{28E5499F-6AF4-4778-AE14-66BA40B56247}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
@@ -126,11 +125,10 @@ namespace AZ
const Uuid& valueTypeId, JsonSerializerContext& context) override;
};
- class JsonUnsignedLongLongSerializer
- : public BaseJsonSerializer
+ class JsonUnsignedLongLongSerializer : public BaseJsonIntegerSerializer
{
public:
- AZ_RTTI(JsonUnsignedLongLongSerializer, "{AB048BB3-C280-4166-9E2E-54CE2C3413CA}", BaseJsonSerializer);
+ AZ_RTTI(JsonUnsignedLongLongSerializer, "{AB048BB3-C280-4166-9E2E-54CE2C3413CA}", BaseJsonIntegerSerializer);
AZ_CLASS_ALLOCATOR_DECL;
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp
index 9c4641741e..a0a2ea6c37 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp
@@ -19,25 +19,30 @@
#include
#include
#include
+#include
#include
namespace AZ
{
JsonSerializationResult::ResultCode JsonDeserializer::DeserializerDefaultCheck(BaseJsonSerializer* serializer, void* object,
- const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context)
+ const Uuid& typeId,const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context)
{
using namespace AZ::JsonSerializationResult;
bool isExplicitDefault = IsExplicitDefault(value);
bool manuallyDefaults = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::ManualDefault) ==
BaseJsonSerializer::OperationFlags::ManualDefault;
- return !isExplicitDefault || (isExplicitDefault && manuallyDefaults)
+ bool initializeNewInstance = (serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) ==
+ BaseJsonSerializer::OperationFlags::InitializeNewInstance;
+
+ return
+ !isExplicitDefault || (isExplicitDefault && manuallyDefaults) || (isExplicitDefault && isNewInstance && initializeNewInstance)
? serializer->Load(object, typeId, value, context)
: context.Report(Tasks::ReadField, Outcomes::DefaultsUsed, "Value has an explicit default.");
}
- JsonSerializationResult::ResultCode JsonDeserializer::Load(void* object, const Uuid& typeId, const rapidjson::Value& value,
- JsonDeserializerContext& context)
+ JsonSerializationResult::ResultCode JsonDeserializer::Load(
+ void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context)
{
using namespace AZ::JsonSerializationResult;
@@ -50,7 +55,7 @@ namespace AZ
BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId);
if (serializer)
{
- return DeserializerDefaultCheck(serializer, object, typeId, value, context);
+ return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context);
}
const SerializeContext::ClassData* classData = context.GetSerializeContext()->FindClassData(typeId);
@@ -72,7 +77,7 @@ namespace AZ
serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId());
if (serializer)
{
- return DeserializerDefaultCheck(serializer, object, typeId, value, context);
+ return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context);
}
}
@@ -133,7 +138,7 @@ namespace AZ
const SerializeContext::ClassData* resolvedClassData = context.GetSerializeContext()->FindClassData(resolvedTypeId);
if (resolvedClassData)
{
- status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, context);
+ status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, context);
*objectPtr = resolvedClassData->m_azRtti->Cast(*objectPtr, typeId);
@@ -174,7 +179,7 @@ namespace AZ
}
else
{
- return Load(object, classElement.m_typeId, value, context);
+ return Load(object, classElement.m_typeId, value, false, context);
}
}
@@ -591,7 +596,9 @@ namespace AZ
}
else
{
- status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, "Serialization information for target type not found.");
+ using ReporterString = AZStd::fixed_string<1024>;
+ status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown,
+ ReporterString::format("Serialization information for target type %s not found.", loadedTypeId.m_typeId.ToString().c_str()));
return ResolvePointerResult::FullyProcessed;
}
objectType = loadedTypeId.m_typeId;
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h
index 5954082ee0..1d16b49e39 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h
@@ -58,8 +58,8 @@ namespace AZ
JsonDeserializer(const JsonDeserializer& rhs) = delete;
JsonDeserializer(JsonDeserializer&& rhs) = delete;
- static JsonSerializationResult::ResultCode Load(void* object, const Uuid& typeId, const rapidjson::Value& value,
- JsonDeserializerContext& context);
+ static JsonSerializationResult::ResultCode Load(
+ void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context);
static JsonSerializationResult::ResultCode LoadToPointer(void* object, const Uuid& typeId, const rapidjson::Value& value,
JsonDeserializerContext& context);
@@ -120,6 +120,7 @@ namespace AZ
void* object,
const Uuid& typeId,
const rapidjson::Value& value,
+ bool isNewInstance,
JsonDeserializerContext& context);
};
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp
index 0629f1c32e..6fabf51237 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp
@@ -249,7 +249,7 @@ namespace AZ
{
StackedString path(StackedString::Format::JsonPointer);
JsonDeserializerContext context(settings);
- result = JsonDeserializer::Load(object, objectType, root, context);
+ result = JsonDeserializer::Load(object, objectType, root, false, context);
}
return result;
}
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp
index 437a648e1e..4dc3c44834 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/MapSerializer.cpp
@@ -190,6 +190,12 @@ namespace AZ
}
size_t addedCount = container->Size(outputValue) - containerSize;
+ if (addedCount > 0)
+ {
+ // If at least one entry was added then the map is no longer in it's default state so
+ // mark is with success so the result can at best be partial defaults.
+ retVal.Combine(JSR::ResultCode(JSR::Tasks::ReadField, JSR::Outcomes::Success));
+ }
AZStd::string_view message =
addedCount >= maximumSize ? "Successfully read associative container." :
addedCount == 0 ? "Unable to read data for the associative container." :
@@ -215,10 +221,10 @@ namespace AZ
// Load key
void* keyAddress = pairContainer->GetElementByIndex(address, pairElement, 0);
AZ_Assert(keyAddress, "Element reserved for associative container, but unable to retrieve address of the key.");
- ContinuationFlags keyLoadFlags = ContinuationFlags::None;
+ ContinuationFlags keyLoadFlags = ContinuationFlags::LoadAsNewInstance;
if (keyElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER)
{
- keyLoadFlags = ContinuationFlags::ResolvePointer;
+ keyLoadFlags |= ContinuationFlags::ResolvePointer;
*reinterpret_cast(keyAddress) = nullptr;
}
JSR::ResultCode keyResult = ContinueLoading(keyAddress, keyElement->m_typeId, key, context, keyLoadFlags);
@@ -231,10 +237,10 @@ namespace AZ
// Load value
void* valueAddress = pairContainer->GetElementByIndex(address, pairElement, 1);
AZ_Assert(valueAddress, "Element reserved for associative container, but unable to retrieve address of the value.");
- ContinuationFlags valueLoadFlags = ContinuationFlags::None;
+ ContinuationFlags valueLoadFlags = ContinuationFlags::LoadAsNewInstance;
if (valueElement->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER)
{
- valueLoadFlags = ContinuationFlags::ResolvePointer;
+ valueLoadFlags |= ContinuationFlags::ResolvePointer;
*reinterpret_cast(valueAddress) = nullptr;
}
JSR::ResultCode valueResult = ContinueLoading(valueAddress, valueElement->m_typeId, value, context, valueLoadFlags);
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp
index 5b43cec817..e8a6f549a7 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.cpp
@@ -34,13 +34,24 @@ namespace AZ
switch (inputValue.GetType())
{
case rapidjson::kArrayType:
- return LoadContainer(outputValue, outputValueTypeId, inputValue, context);
+ return LoadContainer(outputValue, outputValueTypeId, inputValue, false, context);
- case rapidjson::kObjectType: // fall through
- case rapidjson::kNullType: // fall through
- case rapidjson::kStringType: // fall through
- case rapidjson::kFalseType: // fall through
- case rapidjson::kTrueType: // fall through
+ case rapidjson::kObjectType:
+ if (IsExplicitDefault(inputValue))
+ {
+ // Because this serializer has only the operation flag "InitializeNewInstance" set, the only time this will be called with
+ // an explicit default is when a new instance has been created.
+ return LoadContainer(outputValue, outputValueTypeId, inputValue, true, context);
+ }
+ [[fallthrough]];
+ case rapidjson::kNullType:
+ [[fallthrough]];
+ case rapidjson::kStringType:
+ [[fallthrough]];
+ case rapidjson::kFalseType:
+ [[fallthrough]];
+ case rapidjson::kTrueType:
+ [[fallthrough]];
case rapidjson::kNumberType:
return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
"Unsupported type. AZStd::pair or AZStd::tuple can only be read from an array.");
@@ -127,8 +138,13 @@ namespace AZ
}
}
+ auto JsonTupleSerializer::GetOperationsFlags() const -> OperationFlags
+ {
+ return OperationFlags::InitializeNewInstance;
+ }
+
JsonSerializationResult::Result JsonTupleSerializer::LoadContainer(void* outputValue, const Uuid& outputValueTypeId,
- const rapidjson::Value& inputValue, JsonDeserializerContext& context)
+ const rapidjson::Value& inputValue, bool isNewInstance, JsonDeserializerContext& context)
{
namespace JSR = JsonSerializationResult; // Used to remove name conflicts in AzCore in uber builds.
@@ -154,13 +170,6 @@ namespace AZ
};
container->EnumTypes(typeCountCallback);
- rapidjson::SizeType arraySize = inputValue.Size();
- if (arraySize < typeCount)
- {
- return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
- "Not enough entries in array to load an AZStd::pair or AZStd::tuple from.");
- }
-
AZStd::vector classElements;
classElements.reserve(typeCount);
auto typeEnumCallback = [&classElements](const Uuid&, const SerializeContext::ClassElement* genericClassElement)
@@ -171,46 +180,80 @@ namespace AZ
container->EnumTypes(typeEnumCallback);
JSR::ResultCode retVal(JSR::Tasks::ReadField);
- rapidjson::SizeType arrayIndex = 0;
- size_t numElementsWritten = 0;
- for (size_t i = 0; i < typeCount; ++i)
+ if (isNewInstance)
{
- ScopedContextPath subPath(context, i);
-
- void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i);
- AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i);
+ rapidjson::Value explicitDefaultValue = GetExplicitDefault();
- ContinuationFlags flags = classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER
- ? ContinuationFlags::ResolvePointer
- : ContinuationFlags::None;
-
- while (arrayIndex < inputValue.Size())
+ for (size_t i = 0; i < typeCount; ++i)
{
- JSR::ResultCode result = ContinueLoading(elementAddress, classElements[i]->m_typeId, inputValue[arrayIndex], context, flags);
+ ScopedContextPath subPath(context, i);
+
+ void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i);
+ AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i);
+
+ ContinuationFlags flags = ContinuationFlags::LoadAsNewInstance;
+ flags |=
+ (classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? ContinuationFlags::ResolvePointer
+ : ContinuationFlags::None);
+ JSR::ResultCode result = ContinueLoading(elementAddress, classElements[i]->m_typeId, explicitDefaultValue, context, flags);
retVal.Combine(result);
- arrayIndex++;
if (result.GetProcessing() == JSR::Processing::Halted)
{
return context.Report(retVal, "Failed to read element for AZStd::pair or AZStd::tuple.");
}
- else if (result.GetProcessing() != JSR::Processing::Altered)
- {
- numElementsWritten++;
- break;
- }
}
- }
- if (numElementsWritten < typeCount)
- {
- AZStd::string_view message = numElementsWritten == 0 ?
- "Unable to read data for AZStd::pair or AZStd::tuple." :
- "Partially read data for AZStd::pair or AZStd::tuple.";
- return context.Report(retVal, message);
+ return context.Report(retVal, "Initialized AZStd::pair or AZStd::tuple to defaults.");
}
else
{
- return context.Report(retVal, "Successfully read AZStd::pair or AZStd::tuple.");
+ if (inputValue.Size() < typeCount)
+ {
+ return context.Report(
+ JSR::Tasks::ReadField, JSR::Outcomes::Unsupported,
+ "Not enough entries in array to load an AZStd::pair or AZStd::tuple from.");
+ }
+
+ rapidjson::SizeType arrayIndex = 0;
+ size_t numElementsWritten = 0;
+ for (size_t i = 0; i < typeCount; ++i)
+ {
+ ScopedContextPath subPath(context, i);
+
+ void* elementAddress = container->GetElementByIndex(outputValue, nullptr, i);
+ AZ_Assert(elementAddress, "Address of AZStd::pair or AZStd::tuple element %zu could not be retrieved.", i);
+
+ ContinuationFlags flags =
+ (classElements[i]->m_flags & SerializeContext::ClassElement::Flags::FLG_POINTER ? ContinuationFlags::ResolvePointer
+ : ContinuationFlags::None);
+ while (arrayIndex < inputValue.Size())
+ {
+ JSR::ResultCode result =
+ ContinueLoading(elementAddress, classElements[i]->m_typeId, inputValue[arrayIndex], context, flags);
+ retVal.Combine(result);
+ arrayIndex++;
+ if (result.GetProcessing() == JSR::Processing::Halted)
+ {
+ return context.Report(retVal, "Failed to read element for AZStd::pair or AZStd::tuple.");
+ }
+ else if (result.GetProcessing() != JSR::Processing::Altered)
+ {
+ numElementsWritten++;
+ break;
+ }
+ }
+ }
+
+ if (numElementsWritten < typeCount)
+ {
+ AZStd::string_view message = numElementsWritten == 0 ? "Unable to read data for AZStd::pair or AZStd::tuple."
+ : "Partially read data for AZStd::pair or AZStd::tuple.";
+ return context.Report(retVal, message);
+ }
+ else
+ {
+ return context.Report(retVal, "Successfully read AZStd::pair or AZStd::tuple.");
+ }
}
}
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h
index a105272811..70a506eb81 100644
--- a/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h
+++ b/Code/Framework/AzCore/AzCore/Serialization/Json/TupleSerializer.h
@@ -23,13 +23,20 @@ namespace AZ
public:
AZ_RTTI(JsonTupleSerializer, "{1AA0ADC1-395A-4223-8A73-304ACDEE7793}", BaseJsonSerializer);
AZ_CLASS_ALLOCATOR_DECL;
+
JsonSerializationResult::Result Load(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
JsonDeserializerContext& context) override;
JsonSerializationResult::Result Store(rapidjson::Value& outputValue, const void* inputValue, const void* defaultValue,
const Uuid& valueTypeId, JsonSerializerContext& context) override;
+ OperationFlags GetOperationsFlags() const override;
+
private:
- JsonSerializationResult::Result LoadContainer(void* outputValue, const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
+ JsonSerializationResult::Result LoadContainer(
+ void* outputValue,
+ const Uuid& outputValueTypeId,
+ const rapidjson::Value& inputValue,
+ bool isNewInstance,
JsonDeserializerContext& context);
};
} // namespace AZ
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp
index 2d2acd9d44..172a3697e4 100644
--- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp
@@ -816,7 +816,11 @@ namespace AZ::SettingsRegistryMergeUtils
}
}
- void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine, bool executeCommands)
+ // This function intentionally copies `commandLine`. It looks like it only uses it as a const reference, but the
+ // code in the loop makes calls that mutates the `commandLine` instance, invalidating the iterators. Making a copy
+ // ensures that the iterators remain valid.
+ // NOLINTNEXTLINE(performance-unnecessary-value-param)
+ void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands)
{
// Iterate over all the command line options in order to parse the --regset and --regremove
// arguments in the order they were supplied
@@ -831,7 +835,7 @@ namespace AZ::SettingsRegistryMergeUtils
continue;
}
}
- if (commandArgument.m_option == "regremove")
+ else if (commandArgument.m_option == "regremove")
{
if (!registry.Remove(commandArgument.m_value))
{
diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h
index b482530d24..dbeb1bfe24 100644
--- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h
+++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.h
@@ -15,11 +15,7 @@
#include
#include
#include
-
-namespace AZ
-{
- class CommandLine;
-}
+#include
namespace AZ::IO
{
@@ -217,7 +213,7 @@ namespace AZ::SettingsRegistryMergeUtils
//! example: --regdump /My/Array/With/Objects
//! --regdumpall Dumps the entire settings registry to output.
//! Note that this function is only called in development builds and is compiled out in release builds.
- void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, const AZ::CommandLine& commandLine, bool executeCommands);
+ void MergeSettingsToRegistry_CommandLine(SettingsRegistryInterface& registry, AZ::CommandLine commandLine, bool executeCommands);
//! Stores the command line settings into the Setting Registry
//! The arguments can be used later anywhere the command line is needed
diff --git a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
index 3e4ddac3af..47dba62ec8 100644
--- a/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
@@ -168,6 +168,10 @@ namespace JsonSerializationTests
{
features.EnableJsonType(rapidjson::kObjectType);
features.m_typeToInject = rapidjson::kNullType;
+ // Assets are not fully registered with the Serialize Context for historical reasons. Due to the missing
+ // information the Json Serializer Conformity Tests can't run the subsection of tests that explicitly
+ // require the missing information.
+ features.m_enableNewInstanceTests = false;
}
bool AreEqual(const Asset& lhs, const Asset& rhs) override
diff --git a/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp b/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp
index 4fa816cd4d..cb26937824 100644
--- a/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/Name/NameJsonSerializerTests.cpp
@@ -32,6 +32,11 @@ namespace JsonSerializationTests
AZ::NameDictionary::Destroy();
}
+ void Reflect(AZStd::unique_ptr& context)
+ {
+ AZ::Name::Reflect(context.get());
+ }
+
void Reflect(AZStd::unique_ptr& context)
{
AZ::Name::Reflect(context.get());
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp
index da66bdd0b5..f696a9d270 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/ArraySerializerTests.cpp
@@ -126,9 +126,9 @@ namespace JsonSerializationTests
{
auto array = AZStd::shared_ptr(new Array(), Deleter);
(*array)[0] = nullptr;
- (*array)[1] = aznew MultipleInheritence();
+ (*array)[1] = nullptr;
(*array)[2] = nullptr;
- (*array)[3] = aznew MultipleInheritence();
+ (*array)[3] = nullptr;
return array;
}
@@ -154,6 +154,7 @@ namespace JsonSerializationTests
null,
null,
{
+ "$type": "MultipleInheritence",
"base_var": 242.0,
"var1" : 142
}
@@ -246,56 +247,21 @@ namespace JsonSerializationTests
])";
}
- AZStd::string_view GetJsonFor_Store_SerializeFullySetInstance() override
- {
- // This is a unique situation because the $type is determined separate from other values, so all
- // member values can be changed, but since the default type matches the stored type the $type
- // will only be written if default values are explicitly kept.
- return R"(
- [
- {
- "$type": "MultipleInheritence",
- "base_var": 1142.0,
- "base2_var1": 1242.0,
- "base2_var2": 1342.0,
- "base2_var3": 1442.0,
- "var1" : 1542,
- "var2" : 1642.0
- },
- {
- "base_var": 2142.0,
- "base2_var1": 2242.0,
- "base2_var2": 2342.0,
- "base2_var3": 2442.0,
- "var1" : 2542,
- "var2" : 2642.0
- },
- {
- "$type": "MultipleInheritence",
- "base_var": 3142.0,
- "base2_var1": 3242.0,
- "base2_var2": 3342.0,
- "base2_var3": 3442.0,
- "var1" : 3542,
- "var2" : 3642.0
- },
- {
- "base_var": 4142.0,
- "base2_var1": 4242.0,
- "base2_var2": 4342.0,
- "base2_var3": 4442.0,
- "var1" : 4542,
- "var2" : 4642.0
- }
- ])";
- }
-
void Reflect(AZStd::unique_ptr& context) override
{
Base::Reflect(context);
MultipleInheritence::Reflect(context, true);
}
+ void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
+ {
+ Base::ConfigureFeatures(features);
+ // These tests don't work with pointers because there'll be a random value in the pointer
+ // which the Json Serialization will try to delete. The POD version of these tests already cover
+ // these cases.
+ features.m_enableNewInstanceTests = false;
+ }
+
bool AreEqual(const Array& lhs, const Array& rhs) override
{
size_t size = lhs.size();
@@ -311,6 +277,11 @@ namespace JsonSerializationTests
return rhs[i] == nullptr;
}
+ if (rhs[i] == nullptr)
+ {
+ return false;
+ }
+
if (!static_cast(lhs[i])->Equals(*static_cast(rhs[i]), true))
{
return false;
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp
index 88e888743e..508658e2a5 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/BasicContainerSerializerTests.cpp
@@ -54,6 +54,11 @@ namespace JsonSerializationTests
return AZStd::make_shared(Container{ 188, 288, 388 });
}
+ AZStd::shared_ptr CreateSingleArrayDefaultInstance() override
+ {
+ return AZStd::make_shared(Container{ 0 });
+ }
+
AZStd::string_view GetJsonForFullySetInstance() override
{
return "[188, 288, 388]";
@@ -120,6 +125,13 @@ namespace JsonSerializationTests
&SimplePointerTestDescription::Delete);
}
+ AZStd::shared_ptr CreateSingleArrayDefaultInstance() override
+ {
+ int* value = reinterpret_cast(azmalloc(sizeof(int), alignof(int)));
+ *value = 0;
+ return AZStd::shared_ptr(new Container{ value }, &SimplePointerTestDescription::Delete);
+ }
+
AZStd::string_view GetJsonForFullySetInstance() override
{
return "[188, 288, 388]";
@@ -180,6 +192,13 @@ namespace JsonSerializationTests
return instance;
}
+ AZStd::shared_ptr CreateSingleArrayDefaultInstance() override
+ {
+ auto instance = AZStd::make_shared();
+ *instance = { SimpleClass{} };
+ return instance;
+ }
+
AZStd::string_view GetJsonForFullySetInstance() override
{
return R"([
@@ -301,7 +320,7 @@ namespace JsonSerializationTests
ResultCode result = m_serializer->Store(*m_jsonDocument, &instance, &instance, azrtti_typeid(&instance), *m_jsonSerializationContext);
EXPECT_EQ(Processing::Completed, result.GetProcessing());
- EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
+ EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
Expect_DocStrEq("[{}]");
}
@@ -315,7 +334,7 @@ namespace JsonSerializationTests
ResultCode result = m_serializer->Store(*m_jsonDocument, &instance, nullptr, azrtti_typeid(&instance), *m_jsonSerializationContext);
EXPECT_EQ(Processing::Completed, result.GetProcessing());
- EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
+ EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
Expect_DocStrEq("[{},{}]");
}
@@ -330,7 +349,6 @@ namespace JsonSerializationTests
ResultCode result = m_serializer->Store(*m_jsonDocument, &instance, nullptr, azrtti_typeid(&instance), *m_jsonSerializationContext);
EXPECT_EQ(Processing::Completed, result.GetProcessing());
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
- EXPECT_NE(Outcomes::DefaultsUsed, result.GetOutcome());
Expect_DocStrEq(R"([{"$type": "SimpleInheritence"},{"$type": "SimpleInheritence"}])");
}
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp
index cf9d76e79d..cd6fcef5c5 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/BoolSerializerTests.cpp
@@ -63,6 +63,18 @@ namespace JsonSerializationTests
: public BaseJsonSerializerFixture
{
public:
+ struct BoolPointerWrapper
+ {
+ AZ_TYPE_INFO(BoolPointerWrapper, "{2E67C069-BB0F-4F00-A704-E964F5FE5ED2}");
+
+ bool* m_value{ nullptr };
+
+ ~BoolPointerWrapper()
+ {
+ azfree(m_value);
+ }
+ };
+
void SetUp() override
{
BaseJsonSerializerFixture::SetUp();
@@ -75,6 +87,12 @@ namespace JsonSerializationTests
BaseJsonSerializerFixture::TearDown();
}
+ void RegisterAdditional(AZStd::unique_ptr& serializeContext) override
+ {
+ serializeContext->Class()
+ ->Field("Value", &BoolPointerWrapper::m_value);
+ }
+
void Load(rapidjson::Value& testVal, bool expectedBool, AZ::JsonSerializationResult::Outcomes expectedOutcome)
{
using namespace AZ::JsonSerializationResult;
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp
index d19c38fcdc..1556318199 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/DoubleSerializerTests.cpp
@@ -32,7 +32,7 @@ namespace JsonSerializationTests
AZStd::shared_ptr CreateDefaultInstance() override
{
- return AZStd::make_shared(-2.0f);
+ return AZStd::make_shared(0.0f);
}
AZStd::shared_ptr CreateFullySetInstance() override
@@ -71,6 +71,20 @@ namespace JsonSerializationTests
: public BaseJsonSerializerFixture
{
public:
+ struct DoublePointerWrapper
+ {
+ AZ_TYPE_INFO(DoublePointerWrapper, "{C2FD9E0B-2641-4D24-A3D9-A29FD1A21A81}");
+
+ double* m_double{ nullptr };
+ float* m_float{ nullptr };
+
+ ~DoublePointerWrapper()
+ {
+ azfree(m_float);
+ azfree(m_double);
+ }
+ };
+
void SetUp() override
{
BaseJsonSerializerFixture::SetUp();
@@ -85,6 +99,13 @@ namespace JsonSerializationTests
BaseJsonSerializerFixture::TearDown();
}
+ void RegisterAdditional(AZStd::unique_ptr& serializeContext) override
+ {
+ serializeContext->Class()
+ ->Field("Double", &DoublePointerWrapper::m_double)
+ ->Field("Float", &DoublePointerWrapper::m_float);
+ }
+
void TestSerializers(rapidjson::Value& testVal, double expectedValue, AZ::JsonSerializationResult::Outcomes expectedOutcome)
{
using namespace AZ::JsonSerializationResult;
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h
index c0f470378c..9d7e58dd36 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializerConformityTests.h
@@ -62,6 +62,14 @@ namespace JsonSerializationTests
//! can be used to manually create these documents. If that is also not an option the tests can be
//! disabled by setting this flag to false.
bool m_supportsInjection{ true };
+ //! Enables the check that tries to determine if variables are initialized and if not whether they have the
+ //! OperationFlags::ManualDefault set. This applies for instance to integers, which won't be initialized if
+ //! constructed a new instance is created for pointers.
+ bool m_enableInitializationTest{ true };
+ //! Enable the test that creates a new instance of the provided test type through the factory that's found in
+ //! the Serialize Context. This test is automatically disabled for classes that don't have a factory or
+ //! have a null factory as well as for classes that have mandatory fields.
+ bool m_enableNewInstanceTests{ true };
private:
// There's no way to retrieve the number of types from RapidJSON so they're hard-coded here.
@@ -87,6 +95,7 @@ namespace JsonSerializationTests
{
public:
using Type = T;
+
virtual ~JsonSerializerConformityTestDescriptor() = default;
virtual AZStd::shared_ptr CreateSerializer() = 0;
@@ -104,13 +113,21 @@ namespace JsonSerializationTests
virtual AZStd::shared_ptr CreatePartialDefaultInstance() { return nullptr; }
//! Create an instance where all values are set to non-default values.
virtual AZStd::shared_ptr CreateFullySetInstance() = 0;
+ //! Create an instance of the target array type with a single value that has all defaults.
+ //! If the target type doesn't support arrays or requires more than one entry this can be ignored and
+ //! tests using this value will be skipped.
+ virtual AZStd::shared_ptr CreateSingleArrayDefaultInstance() { return nullptr; }
//! Get the json that represents the default instance.
//! If the target type doesn't support partial specialization this can be ignored and
//! tests for partial support will be skipped.
- virtual AZStd::string_view GetJsonForPartialDefaultInstance() { return ""; }
+ virtual AZStd::string_view GetJsonForPartialDefaultInstance() { return ""; }
//! Get the json that represents the instance with all values set.
virtual AZStd::string_view GetJsonForFullySetInstance() = 0;
+ //! Get the json that represents an array with a single value that has only defaults.
+ //! If the target type doesn't support arrays or requires more than one entry this can be ignored and
+ //! tests using this value will be skipped.
+ virtual AZStd::string_view GetJsonForSingleArrayDefaultInstance() { return "[{}]"; }
//! Get the json where additional values are added to the json file.
//! If this function is not overloaded, but features.m_supportsInjection is enabled then
//! the Json Serializer Conformity Tests will inject extra values in the json for a fully.
@@ -138,12 +155,15 @@ namespace JsonSerializationTests
virtual AZStd::string_view GetJsonFor_Load_DeserializeUnreflectedType() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Load_DeserializeFullySetInstance() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Load_DeserializePartialInstance() { return this->GetJsonForPartialDefaultInstance(); }
+ virtual AZStd::string_view GetJsonFor_Load_DeserializeArrayWithDefaultValue() { return this->GetJsonForSingleArrayDefaultInstance(); }
+ virtual AZStd::string_view GetJsonFor_Load_DeserializeFullInstanceOnTopOfPartialDefaulted() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Load_HaltedThroughCallback() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Store_SerializeWithDefaultsKept() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Store_SerializeFullySetInstance() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Store_SerializeWithoutDefault() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Store_SerializeWithoutDefaultAndDefaultsKept() { return this->GetJsonForFullySetInstance(); }
virtual AZStd::string_view GetJsonFor_Store_SerializePartialInstance() { return this->GetJsonForPartialDefaultInstance(); }
+ virtual AZStd::string_view GetJsonFor_Store_SerializeArrayWithSingleDefaultValue() { return this->GetJsonForSingleArrayDefaultInstance(); }
};
template
@@ -154,6 +174,21 @@ namespace JsonSerializationTests
using Description = T;
using Type = typename T::Type;
+ struct PointerWrapper
+ {
+ AZ_TYPE_INFO(PointerWrapper, "{32FA6645-074A-458A-B79C-B173D0BD4B42}");
+ AZ_CLASS_ALLOCATOR(PointerWrapper, AZ::SystemAllocator, 0);
+
+ Type* m_value{ nullptr };
+
+ ~PointerWrapper()
+ {
+ // Using free because not all types can safely use delete. Since this just to clear the memory to satisfy the memory
+ // leak test, this is fine.
+ azfree(m_value);
+ }
+ };
+
void SetUp() override
{
using namespace AZ::JsonSerializationResult;
@@ -165,6 +200,7 @@ namespace JsonSerializationTests
descriptor->ConfigureFeatures(this->m_features);
descriptor->Reflect(this->m_serializeContext);
descriptor->Reflect(this->m_jsonRegistrationContext);
+ this->m_serializeContext->template Class()->Field("Value", &PointerWrapper::m_value);
this->m_deserializationSettings->m_reporting = &Internal::VerifyCallback;
this->m_serializationSettings->m_reporting = &Internal::VerifyCallback;
@@ -185,6 +221,7 @@ namespace JsonSerializationTests
this->m_jsonRegistrationContext->DisableRemoveReflection();
this->m_serializeContext->EnableRemoveReflection();
+ this->m_serializeContext->template Class()->Field("Value", &PointerWrapper::m_value);
descriptor->Reflect(this->m_serializeContext);
this->m_serializeContext->DisableRemoveReflection();
@@ -487,6 +524,41 @@ namespace JsonSerializationTests
}
}
+ TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeArrayWithDefaultValue_SucceedsAndReportPartialDefaults)
+ {
+ using namespace AZ::JsonSerializationResult;
+
+ if (this->m_features.SupportsJsonType(rapidjson::kArrayType))
+ {
+ this->m_jsonDocument->Parse(this->m_description.GetJsonFor_Load_DeserializeArrayWithDefaultValue().data());
+ ASSERT_FALSE(this->m_jsonDocument->HasParseError());
+
+ auto serializer = this->m_description.CreateSerializer();
+ auto instance = this->m_description.CreateDefaultInstance();
+
+ this->m_jsonDeserializationContext->PushPath(DefaultPath);
+
+ ResultCode result =
+ serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext);
+
+ if (this->m_features.m_fixedSizeArray)
+ {
+ EXPECT_EQ(Outcomes::Unsupported, result.GetOutcome());
+ EXPECT_EQ(Processing::Altered, result.GetProcessing());
+ }
+ else
+ {
+ EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
+ EXPECT_EQ(Processing::Completed, result.GetProcessing());
+
+ auto compare = this->m_description.CreateSingleArrayDefaultInstance();
+ ASSERT_NE(nullptr, compare)
+ << "Conformity tests for variably sized arrays require an implementation of CreateSingleArrayDefaultInstance";
+ EXPECT_TRUE(this->m_description.AreEqual(*compare, *instance));
+ }
+ }
+ }
+
TYPED_TEST_P(JsonSerializerConformityTests, Load_InterruptClearingTarget_ContainerIsNotCleared)
{
using namespace AZ::JsonSerializationResult;
@@ -548,7 +620,6 @@ namespace JsonSerializationTests
this->m_jsonDocument->Parse(json.data());
ASSERT_FALSE(this->m_jsonDocument->HasParseError());
- auto serializer = this->m_description.CreateSerializer();
auto instance = this->m_description.CreateDefaultConstructedInstance();
auto compare = this->m_description.CreateFullySetInstance();
@@ -622,6 +693,94 @@ namespace JsonSerializationTests
}
}
+ TYPED_TEST_P(JsonSerializerConformityTests, Load_DeserializeFullInstanceOnTopOfPartialDefaulted_SucceedsAndObjectMatchesParialInstance)
+ {
+ using namespace AZ::JsonSerializationResult;
+
+ if (this->m_features.m_supportsPartialInitialization)
+ {
+ AZStd::string_view json = this->m_description.GetJsonFor_Load_DeserializeFullInstanceOnTopOfPartialDefaulted();
+ // If tests for partial initialization are enabled than json for the partial initialization is needed.
+ ASSERT_FALSE(json.empty());
+ this->m_jsonDocument->Parse(json.data());
+ ASSERT_FALSE(this->m_jsonDocument->HasParseError());
+
+ auto serializer = this->m_description.CreateSerializer();
+ auto instance = this->m_description.CreatePartialDefaultInstance();
+ auto compare = this->m_description.CreateFullySetInstance();
+ ASSERT_NE(nullptr, compare);
+
+ // Clear containers which should effectively turn them into default containers.
+ this->m_deserializationSettings->m_clearContainers = true;
+ this->ResetJsonContexts();
+ this->m_jsonDeserializationContext->PushPath(DefaultPath);
+
+ ResultCode result =
+ serializer->Load(instance.get(), azrtti_typeid(*instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext);
+
+ EXPECT_EQ(Outcomes::Success, result.GetOutcome());
+ EXPECT_EQ(Processing::Completed, result.GetProcessing());
+ EXPECT_TRUE(this->m_description.AreEqual(*instance, *compare));
+ }
+ }
+
+ TYPED_TEST_P(JsonSerializerConformityTests, Load_DefaultToPointer_SucceedsAndValueIsInitialized)
+ {
+ using namespace AZ::JsonSerializationResult;
+
+ if (this->m_features.m_enableNewInstanceTests && this->m_features.m_mandatoryFields.empty())
+ {
+ AZ::SerializeContext* serializeContext = this->m_jsonDeserializationContext->GetSerializeContext();
+ const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(azrtti_typeid());
+ ASSERT_NE(nullptr, classData);
+ // Skip this test if the target type doesn't have a factor to create a new instance with or if the factor explicit
+ // prohibits construction.
+ if (classData->m_factory && classData->m_factory != AZ::Internal::NullFactory::GetInstance())
+ {
+ typename JsonSerializerConformityTests::PointerWrapper instance;
+ auto compare = this->m_description.CreateDefaultInstance();
+
+ this->m_jsonDocument->Parse(R"({ "Value": {}})");
+ ASSERT_FALSE(this->m_jsonDocument->HasParseError());
+
+ AZ::JsonDeserializerSettings settings;
+ settings.m_serializeContext = serializeContext;
+ settings.m_registrationContext = this->m_jsonDeserializationContext->GetRegistrationContext();
+ ResultCode result = AZ::JsonSerialization::Load(instance, *this->m_jsonDocument, settings);
+
+ EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
+ EXPECT_EQ(Processing::Completed, result.GetProcessing());
+ ASSERT_NE(nullptr, instance.m_value);
+ EXPECT_TRUE(this->m_description.AreEqual(*instance.m_value, *compare));
+ }
+ }
+ }
+
+ TYPED_TEST_P(JsonSerializerConformityTests, Load_InitializeNewInstance_SucceedsAndValueIsInitialized)
+ {
+ using namespace AZ;
+ using namespace AZ::JsonSerializationResult;
+
+ if (this->m_features.m_enableNewInstanceTests && this->m_features.m_mandatoryFields.empty())
+ {
+ auto serializer = this->m_description.CreateSerializer();
+ if ((serializer->GetOperationsFlags() & BaseJsonSerializer::OperationFlags::InitializeNewInstance) ==
+ BaseJsonSerializer::OperationFlags::InitializeNewInstance)
+ {
+ typename TypeParam::Type instance;
+ auto compare = this->m_description.CreateDefaultInstance();
+ this->m_jsonDocument->SetObject();
+
+ ResultCode result =
+ serializer->Load(&instance, azrtti_typeid(instance), *this->m_jsonDocument, *this->m_jsonDeserializationContext);
+
+ EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
+ EXPECT_EQ(Processing::Completed, result.GetProcessing());
+ EXPECT_TRUE(this->m_description.AreEqual(instance, *compare));
+ }
+ }
+ }
+
TYPED_TEST_P(JsonSerializerConformityTests, Load_HaltedThroughCallback_LoadFailsAndHaltReported)
{
using namespace AZ::JsonSerializationResult;
@@ -909,6 +1068,28 @@ namespace JsonSerializationTests
}
}
+ TYPED_TEST_P(JsonSerializerConformityTests, Store_SerializeArrayWithSingleDefaultValue_StoredSuccessfullyAndJsonMatches)
+ {
+ using namespace AZ::JsonSerializationResult;
+
+ if (this->m_features.SupportsJsonType(rapidjson::kArrayType) && !this->m_features.m_fixedSizeArray)
+ {
+ this->m_jsonSerializationContext->PushPath(DefaultPath);
+
+ auto serializer = this->m_description.CreateSerializer();
+ auto instance = this->m_description.CreateSingleArrayDefaultInstance();
+ ASSERT_NE(nullptr, instance)
+ << "Conformity tests for variably sized arrays require an implementation of CreateSingleArrayDefaultInstance";
+
+ ResultCode result = serializer->Store(
+ *this->m_jsonDocument, instance.get(), instance.get(), azrtti_typeid(*instance), *this->m_jsonSerializationContext);
+
+ EXPECT_EQ(Processing::Completed, result.GetProcessing());
+ EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
+ this->Expect_DocStrEq(this->m_description.GetJsonFor_Store_SerializeArrayWithSingleDefaultValue());
+ }
+ }
+
TYPED_TEST_P(JsonSerializerConformityTests, Store_HaltedThroughCallback_StoreFailsAndHaltReported)
{
using namespace AZ::JsonSerializationResult;
@@ -1017,7 +1198,29 @@ namespace JsonSerializationTests
}
}
- TYPED_TEST_P(JsonSerializerConformityTests, GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared)
+ TYPED_TEST_P(JsonSerializerConformityTests, GetOperationFlags_RequiresExplicitInit_ObjectsThatDoNotConstructHaveExplicitInitOption)
+ {
+ using namespace AZ;
+ using namespace AZ::JsonSerializationResult;
+
+ if (this->m_features.m_enableInitializationTest)
+ {
+ auto instance = this->m_description.CreateDefaultInstance();
+ typename TypeParam::Type compare = typename TypeParam::Type{};
+ if (!this->m_description.AreEqual(*instance, compare))
+ {
+ auto serializer = this->m_description.CreateSerializer();
+ BaseJsonSerializer::OperationFlags flags = serializer->GetOperationsFlags();
+ bool hasManualDefaultSet =
+ (flags & BaseJsonSerializer::OperationFlags::ManualDefault) == BaseJsonSerializer::OperationFlags::ManualDefault ||
+ (flags & BaseJsonSerializer::OperationFlags::InitializeNewInstance) ==
+ BaseJsonSerializer::OperationFlags::InitializeNewInstance;
+ EXPECT_TRUE(hasManualDefaultSet);
+ }
+ }
+ }
+
+ TYPED_TEST_P(JsonSerializerConformityTests, GetOperationFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared)
{
if (this->m_features.SupportsJsonType(rapidjson::kObjectType))
{
@@ -1048,10 +1251,14 @@ namespace JsonSerializationTests
Load_DeserializeEmptyArray_SucceedsAndObjectMatchesDefaults,
Load_DeserializeEmptyArrayWithClearEnabled_SucceedsAndObjectMatchesDefaults,
Load_DeserializeEmptyArrayWithClearedTarget_SucceedsAndObjectMatchesDefaults,
+ Load_DeserializeArrayWithDefaultValue_SucceedsAndReportPartialDefaults,
Load_InterruptClearingTarget_ContainerIsNotCleared,
Load_DeserializeFullySetInstance_SucceedsAndObjectMatchesFullySetInstance,
Load_DeserializeFullySetInstanceThroughMainLoad_SucceedsAndObjectMatchesFullySetInstance,
Load_DeserializePartialInstance_SucceedsAndObjectMatchesParialInstance,
+ Load_DeserializeFullInstanceOnTopOfPartialDefaulted_SucceedsAndObjectMatchesParialInstance,
+ Load_DefaultToPointer_SucceedsAndValueIsInitialized,
+ Load_InitializeNewInstance_SucceedsAndValueIsInitialized,
Load_DeserializeWithMissingMandatoryField_LoadFailedAndUnsupportedReported,
Load_InsertAdditionalData_SucceedsAndObjectMatchesFullySetInstance,
Load_HaltedThroughCallback_LoadFailsAndHaltReported,
@@ -1066,13 +1273,15 @@ namespace JsonSerializationTests
Store_SerializeWithoutDefaultAndDefaultsKept_StoredSuccessfullyAndJsonMatches,
Store_SerializePartialInstance_StoredSuccessfullyAndJsonMatches,
Store_SerializeEmptyArray_StoredSuccessfullyAndJsonMatches,
+ Store_SerializeArrayWithSingleDefaultValue_StoredSuccessfullyAndJsonMatches,
Store_HaltedThroughCallback_StoreFailsAndHaltReported,
StoreLoad_RoundTripWithPartialDefault_IdenticalInstances,
StoreLoad_RoundTripWithFullSet_IdenticalInstances,
StoreLoad_RoundTripWithDefaultsKept_IdenticalInstances,
- GetOperationsFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared);
+ GetOperationFlags_RequiresExplicitInit_ObjectsThatDoNotConstructHaveExplicitInitOption,
+ GetOperationFlags_ManualDefaultSetIfNeeded_ManualDefaultOperationSetIfMandatoryFieldsAreDeclared);
} // namespace JsonSerializationTests
namespace AZ
diff --git a/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp
index 5dec394351..7ec5ca3b9a 100644
--- a/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp
+++ b/Code/Framework/AzCore/Tests/Serialization/Json/MapSerializerTests.cpp
@@ -35,6 +35,11 @@ namespace JsonSerializationTests
return AZStd::make_shared