Merge branch 'stabilization/2106' into Helios_TransformImporterFixV2_stabilization_2106
This commit is contained in:
@@ -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.
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
+31
-31
@@ -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)
|
||||
|
||||
|
||||
+97
-66
@@ -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
|
||||
# )
|
||||
+4
-3
@@ -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.'
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f0f4d4e0155feaa76c80a14128000a0fd9570ab76e79f4847eaef9006324a4d2
|
||||
size 9084
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
<Environment />
|
||||
@@ -0,0 +1 @@
|
||||
<TimeOfDay Time="12"/>
|
||||
@@ -0,0 +1,6 @@
|
||||
<download name="ClientAuth" type="Map">
|
||||
<index src="filelist.xml" dest="filelist.xml"/>
|
||||
<files>
|
||||
<file src="level.pak" dest="level.pak" size="ED0" md5="dbf5115226e4b0ea38ebdc3967ba3aa9"/>
|
||||
</files>
|
||||
</download>
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:da041115014f11696d5878d5c21247c17b8d694fa9674e30692259261a7223a2
|
||||
size 3792
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:43b1a23b62fe2ffa05545ac99524f40b6fff49d6e35925b9d6138c00d8082e86
|
||||
size 9073
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
<download name="ClientAuthPasswordSignIn" type="Map">
|
||||
<index src="filelist.xml" dest="filelist.xml"/>
|
||||
<files>
|
||||
<file src="level.pak" dest="level.pak" size="DDF" md5="ebe91ae5f1ea1ec735b6650b14f3f95b"/>
|
||||
</files>
|
||||
</download>
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a58292341785cb260dc0ccf346259e35e2817ee48fc401a21ab528f6afb97b52
|
||||
size 3551
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f3d5121b26608b02747e245071ccff29ac57358cb6349ec9495a7a003ac12467
|
||||
size 8942
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
<download name="ClientAuthPasswordSignUp" type="Map">
|
||||
<index src="filelist.xml" dest="filelist.xml"/>
|
||||
<files>
|
||||
<file src="level.pak" dest="level.pak" size="DDA" md5="aa6df891d505d6d9175beee4b55626db"/>
|
||||
</files>
|
||||
</download>
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:605391d415b828b100bada11d108099520c0b6a020f17588887b610475805d90
|
||||
size 3546
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:023992998ab5a1d64b38dacd1d5e1a9dc930ff704289c0656ed6eaba6951d660
|
||||
size 9066
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
<download name="Metrics" type="Map">
|
||||
<index src="filelist.xml" dest="filelist.xml"/>
|
||||
<files>
|
||||
<file src="level.pak" dest="level.pak" size="E09" md5="f16fff2970a4037af5909b269ceece4b"/>
|
||||
</files>
|
||||
</download>
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e7c0c07b13bb64db344b94d5712e1e802e607a9dee506768b34481f4a76d8505
|
||||
size 3593
|
||||
@@ -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
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e15d484113e8151072b410924747a8ad304f6f12457fad577308c0491693ab34
|
||||
size 5472
|
||||
oid sha256:6517300fb1ce70c4696286e14715c547cfd175eabbb2042f7f2a456b15054224
|
||||
size 5253
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<download name="C18977329_NvCloth_AddClothSimulationToMesh" type="Map">
|
||||
<index src="filelist.xml" dest="filelist.xml"/>
|
||||
<files>
|
||||
<file src="level.pak" dest="level.pak" size="97C8" md5="64e64e1e3345dacace01dde152c72250"/>
|
||||
<file src="level.pak" dest="level.pak" size="96A3" md5="db8a235878128076005ade018587f536"/>
|
||||
</files>
|
||||
</download>
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:64de37c805b0be77cdb7a85b5406af58b7f845e7d97fec1721ac5d789bb641db
|
||||
size 38856
|
||||
oid sha256:ce32a7cdf3ed37751385b3bb18f05206702978363f325d06727b5eb20d40b7eb
|
||||
size 38563
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7b595323d4d51211463dea0338abb6ce2a4a0a8d41efb12ac3c9dccd1f972171
|
||||
size 5504
|
||||
oid sha256:89dbcec013cb819e52ec0f8fed0a9e417fd32eac8aeb67d3958266bb6089ec21
|
||||
size 5505
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<download name="C18977330_NvCloth_AddClothSimulationToActor" type="Map">
|
||||
<index src="filelist.xml" dest="filelist.xml"/>
|
||||
<files>
|
||||
<file src="level.pak" dest="level.pak" size="9941" md5="297730934d657d7ca57a7357ee9cd566"/>
|
||||
<file src="level.pak" dest="level.pak" size="E16" md5="036b4a87cbb256f76823549ab4b18c05"/>
|
||||
</files>
|
||||
</download>
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:617c455668fc41cb7fd69de690e4aa3c80f2cb36deaa371902b79de18fcd1cb2
|
||||
size 39233
|
||||
oid sha256:622c2624b04e07b704520f32c458b50d5a50de1ef116b7bc9c3c0ccb6f4a4ecc
|
||||
size 3606
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b6e408095c15a388768b7f70b6049f33c894aab3e51f2d744bc1ae1d18668ee4
|
||||
size 9694
|
||||
oid sha256:824a51a375f19274d5698ff08af0fdc3dc18204505c73a943de748455d108b01
|
||||
size 6181
|
||||
|
||||
+115
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+115
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+115
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1303
-1312
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,12 @@ namespace AZ
|
||||
Color* color = reinterpret_cast<Color*>(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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace AZ::JsonMathMatrixSerializerInternal
|
||||
|
||||
template<typename MatrixType, size_t RowCount, size_t ColumnCount>
|
||||
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<MatrixType*>(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<Matrix3x3, 3, 3>(
|
||||
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<Matrix3x3>(
|
||||
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<Matrix3x4, 3, 4>(
|
||||
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<Matrix3x4>(
|
||||
outputValue,
|
||||
inputValue,
|
||||
defaultValue,
|
||||
valueTypeId,
|
||||
context);
|
||||
auto result =
|
||||
JsonMathMatrixSerializerInternal::StoreRotationAndScale<Matrix3x4>(outputValue, inputValue, defaultValue, valueTypeId, context);
|
||||
|
||||
auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation<Matrix3x4>(
|
||||
outputValue,
|
||||
inputValue,
|
||||
defaultValue,
|
||||
valueTypeId,
|
||||
context);
|
||||
auto resultTranslation =
|
||||
JsonMathMatrixSerializerInternal::StoreTranslation<Matrix3x4>(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<Matrix4x4, 4, 4>(
|
||||
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<Matrix4x4>(
|
||||
outputValue,
|
||||
inputValue,
|
||||
defaultValue,
|
||||
valueTypeId,
|
||||
context);
|
||||
auto result =
|
||||
JsonMathMatrixSerializerInternal::StoreRotationAndScale<Matrix4x4>(outputValue, inputValue, defaultValue, valueTypeId, context);
|
||||
|
||||
auto resultTranslation = JsonMathMatrixSerializerInternal::StoreTranslation<Matrix4x4>(
|
||||
outputValue,
|
||||
inputValue,
|
||||
defaultValue,
|
||||
valueTypeId,
|
||||
context);
|
||||
auto resultTranslation =
|
||||
JsonMathMatrixSerializerInternal::StoreTranslation<Matrix4x4>(outputValue, inputValue, defaultValue, valueTypeId, context);
|
||||
|
||||
result.GetResultCode().Combine(resultTranslation);
|
||||
return result;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace AZ
|
||||
|
||||
template<typename VectorType, size_t ElementCount>
|
||||
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<VectorType*>(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<VectorType, ElementCount>(*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<Vector2, 2>(outputValue, outputValueTypeId, inputValue, context);
|
||||
return JsonMathVectorSerializerInternal::Load<Vector2, 2>(
|
||||
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<Vector3, 3>(outputValue, outputValueTypeId, inputValue, context);
|
||||
return JsonMathVectorSerializerInternal::Load<Vector3, 3>(
|
||||
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<Vector4, 4>(outputValue, outputValueTypeId, inputValue, context);
|
||||
return JsonMathVectorSerializerInternal::Load<Vector4, 4>(
|
||||
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<Quaternion*>(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<Quaternion, 4>(outputValue, outputValueTypeId, inputValue, context);
|
||||
return JsonMathVectorSerializerInternal::Load<Quaternion, 4>(outputValue, outputValueTypeId, inputValue, context, false);
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonQuaternionSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -33,6 +33,12 @@ namespace AZ
|
||||
AZ::Transform* transformInstance = reinterpret_cast<AZ::Transform*>(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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<Uuid*>(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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<size_t>::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." :
|
||||
|
||||
@@ -82,12 +82,18 @@ namespace AZ
|
||||
|
||||
bool* valAsBool = reinterpret_cast<bool*>(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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -62,19 +62,26 @@ namespace AZ
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<T>::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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerFloatingPointInternal::Load(reinterpret_cast<double*>(outputValue), inputValue, context);
|
||||
return SerializerFloatingPointInternal::Load(
|
||||
reinterpret_cast<double*>(outputValue), inputValue, context, IsExplicitDefault(inputValue));
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonDoubleSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
|
||||
@@ -156,6 +164,11 @@ namespace AZ
|
||||
return SerializerFloatingPointInternal::Store<double>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerFloatingPointInternal::Load(reinterpret_cast<float*>(outputValue), inputValue, context);
|
||||
return SerializerFloatingPointInternal::Load(
|
||||
reinterpret_cast<float*>(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<float>(outputValue, inputValue, defaultValue, context);
|
||||
}
|
||||
|
||||
auto JsonFloatSerializer::GetOperationsFlags() const -> OperationFlags
|
||||
{
|
||||
return OperationFlags::InitializeNewInstance;
|
||||
}
|
||||
} // namespace AZ
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <typename T>
|
||||
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<T>(), "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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<char*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<char*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<short*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<short*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<int*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<int*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<long*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<long*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<long long*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<long long*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<unsigned char*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(
|
||||
reinterpret_cast<unsigned char*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<unsigned short*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(
|
||||
reinterpret_cast<unsigned short*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<unsigned int*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(
|
||||
reinterpret_cast<unsigned int*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<unsigned long*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(
|
||||
reinterpret_cast<unsigned long*>(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<AZStd::string>().c_str());
|
||||
AZ_UNUSED(outputValueTypeId);
|
||||
return SerializerInternal::LoadInt(reinterpret_cast<unsigned long long*>(outputValue), inputValue, context);
|
||||
return SerializerInternal::LoadInt(
|
||||
reinterpret_cast<unsigned long long*>(outputValue), inputValue, context, IsExplicitDefault(inputValue));
|
||||
}
|
||||
|
||||
JsonSerializationResult::Result JsonUnsignedLongLongSerializer::Store(rapidjson::Value& outputValue, const void* inputValue,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -19,25 +19,30 @@
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <AzCore/Serialization/Json/StackedString.h>
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
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<ReporterString>().c_str()));
|
||||
return ResolvePointerResult::FullyProcessed;
|
||||
}
|
||||
objectType = loadedTypeId.m_typeId;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<void**>(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<void**>(valueAddress) = nullptr;
|
||||
}
|
||||
JSR::ResultCode valueResult = ContinueLoading(valueAddress, valueElement->m_typeId, value, context, valueLoadFlags);
|
||||
|
||||
@@ -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<const SerializeContext::ClassElement*> 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
#include <AzCore/IO/Path/Path_fwd.h>
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class CommandLine;
|
||||
}
|
||||
#include <AzCore/Settings/CommandLine.h>
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -32,6 +32,11 @@ namespace JsonSerializationTests
|
||||
AZ::NameDictionary::Destroy();
|
||||
}
|
||||
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context)
|
||||
{
|
||||
AZ::Name::Reflect(context.get());
|
||||
}
|
||||
|
||||
void Reflect(AZStd::unique_ptr<AZ::JsonRegistrationContext>& context)
|
||||
{
|
||||
AZ::Name::Reflect(context.get());
|
||||
|
||||
@@ -126,9 +126,9 @@ namespace JsonSerializationTests
|
||||
{
|
||||
auto array = AZStd::shared_ptr<Array>(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<AZ::SerializeContext>& 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<const MultipleInheritence*>(lhs[i])->Equals(*static_cast<const MultipleInheritence*>(rhs[i]), true))
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -54,6 +54,11 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<Container>(Container{ 188, 288, 388 });
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Container> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Container>(Container{ 0 });
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForFullySetInstance() override
|
||||
{
|
||||
return "[188, 288, 388]";
|
||||
@@ -120,6 +125,13 @@ namespace JsonSerializationTests
|
||||
&SimplePointerTestDescription::Delete);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Container> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
int* value = reinterpret_cast<int*>(azmalloc(sizeof(int), alignof(int)));
|
||||
*value = 0;
|
||||
return AZStd::shared_ptr<Container>(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<Container> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
auto instance = AZStd::make_shared<Container>();
|
||||
*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"}])");
|
||||
}
|
||||
|
||||
|
||||
@@ -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<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<BoolPointerWrapper>()
|
||||
->Field("Value", &BoolPointerWrapper::m_value);
|
||||
}
|
||||
|
||||
void Load(rapidjson::Value& testVal, bool expectedBool, AZ::JsonSerializationResult::Outcomes expectedOutcome)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace JsonSerializationTests
|
||||
|
||||
AZStd::shared_ptr<FloatingPointType> CreateDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<FloatingPointType>(-2.0f);
|
||||
return AZStd::make_shared<FloatingPointType>(0.0f);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<FloatingPointType> 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<AZ::SerializeContext>& serializeContext) override
|
||||
{
|
||||
serializeContext->Class<DoublePointerWrapper>()
|
||||
->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;
|
||||
|
||||
@@ -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<AZ::BaseJsonSerializer> CreateSerializer() = 0;
|
||||
@@ -104,13 +113,21 @@ namespace JsonSerializationTests
|
||||
virtual AZStd::shared_ptr<T> CreatePartialDefaultInstance() { return nullptr; }
|
||||
//! Create an instance where all values are set to non-default values.
|
||||
virtual AZStd::shared_ptr<T> 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<T> 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<typename T>
|
||||
@@ -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<PointerWrapper>()->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<PointerWrapper>()->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<typename TypeParam::Type>());
|
||||
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<TypeParam>::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
|
||||
|
||||
@@ -35,6 +35,11 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<Map>();
|
||||
}
|
||||
|
||||
AZStd::string_view GetJsonForSingleArrayDefaultInstance() override
|
||||
{
|
||||
return R"({ "{}": {} })";
|
||||
}
|
||||
|
||||
void ConfigureFeatures(JsonSerializerConformityTestDescriptorFeatures& features) override
|
||||
{
|
||||
features.EnableJsonType(rapidjson::kArrayType);
|
||||
@@ -61,6 +66,13 @@ namespace JsonSerializationTests
|
||||
public:
|
||||
using Map = T<int, double>;
|
||||
|
||||
AZStd::shared_ptr<Map> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
auto instance = AZStd::make_shared<Map>();
|
||||
instance->emplace(AZStd::make_pair(0, 0.0));
|
||||
return instance;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Map> CreateFullySetInstance() override
|
||||
{
|
||||
auto instance = AZStd::make_shared<Map>();
|
||||
@@ -100,6 +112,13 @@ namespace JsonSerializationTests
|
||||
public:
|
||||
using Map = T<AZStd::string, double>;
|
||||
|
||||
AZStd::shared_ptr<Map> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
auto instance = AZStd::make_shared<Map>();
|
||||
instance->emplace(AZStd::make_pair(AZStd::string(), 0.0));
|
||||
return instance;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Map> CreateFullySetInstance() override
|
||||
{
|
||||
auto instance = AZStd::make_shared<Map>();
|
||||
@@ -163,6 +182,14 @@ namespace JsonSerializationTests
|
||||
return instance;
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Map> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
auto instance = AZStd::shared_ptr<Map>(new Map{}, &Delete);
|
||||
instance->emplace(AZStd::make_pair(aznew SimpleClass(), aznew SimpleClass()));
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
AZStd::string_view GetJsonForPartialDefaultInstance() override
|
||||
{
|
||||
if constexpr (IsMultiMap)
|
||||
@@ -237,13 +264,23 @@ namespace JsonSerializationTests
|
||||
return false;
|
||||
}
|
||||
|
||||
auto compare = [](typename Map::const_reference lhs, typename Map::const_reference rhs) -> bool
|
||||
// Naive compare to avoid having to split up the test because comparing for ordered and unordered maps would need to be
|
||||
// different.
|
||||
for (auto&& [key, value] : lhs)
|
||||
{
|
||||
return
|
||||
lhs.first->Equals(*rhs.first, true) &&
|
||||
lhs.second->Equals(*rhs.second, true);
|
||||
};
|
||||
return AZStd::equal(lhs.begin(), lhs.end(), rhs.begin(), compare);
|
||||
for (auto&& [keyCompare, valueCompare] : rhs)
|
||||
{
|
||||
if (key->Equals(*keyCompare, true))
|
||||
{
|
||||
if (!value->Equals(*valueCompare, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -393,6 +430,29 @@ namespace JsonSerializationTests
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
m_jsonDocument->Parse(R"(
|
||||
{
|
||||
"{}": {}
|
||||
})");
|
||||
ASSERT_FALSE(m_jsonDocument->HasParseError());
|
||||
|
||||
TestStringMap values;
|
||||
ResultCode result = m_unorderedMapSerializer.Load(&values, azrtti_typeid(&values), *m_jsonDocument, *m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
|
||||
EXPECT_EQ(1, values.size());
|
||||
|
||||
auto defaultKey = values.find(TestString());
|
||||
EXPECT_NE(values.end(), defaultKey);
|
||||
EXPECT_STRCASEEQ(TestString().m_value.c_str(), defaultKey->second.m_value.c_str());
|
||||
}
|
||||
|
||||
TEST_F(JsonMapSerializerTests, Load_DefaultForStringKeyAndAdditionalValue_LoadedBackWithDefaults)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
m_jsonDocument->Parse(R"(
|
||||
{
|
||||
"{}": {},
|
||||
@@ -563,13 +623,13 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(Outcomes::Catastrophic, result.GetOutcome());
|
||||
}
|
||||
|
||||
TEST_F(JsonMapSerializerTests, Load_DefaultValueInMultiMap_DefaultUsed)
|
||||
TEST_F(JsonMapSerializerTests, Load_DefaultObjectInMultiMap_DefaultUsed)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
m_jsonDocument->Parse(R"(
|
||||
{
|
||||
"Hello": {}
|
||||
"World": {}
|
||||
})");
|
||||
ASSERT_FALSE(m_jsonDocument->HasParseError());
|
||||
|
||||
@@ -581,17 +641,40 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
|
||||
ASSERT_FALSE(values.empty());
|
||||
EXPECT_STREQ("Hello", values.begin()->first.m_value.c_str());
|
||||
EXPECT_STREQ("World", values.begin()->first.m_value.c_str());
|
||||
EXPECT_STREQ(TestString().m_value.c_str(), values.begin()->second.m_value.c_str());
|
||||
}
|
||||
|
||||
TEST_F(JsonMapSerializerTests, Load_DefaultArrayValueInMultiMap_DefaultUsed)
|
||||
TEST_F(JsonMapSerializerTests, Load_FullDefaultObjectInMultiMap_DefaultUsed)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
m_jsonDocument->Parse(R"(
|
||||
{
|
||||
"Hello": [{}]
|
||||
"{}": {}
|
||||
})");
|
||||
ASSERT_FALSE(m_jsonDocument->HasParseError());
|
||||
|
||||
TestStringMultiMap values;
|
||||
ResultCode result =
|
||||
m_unorderedMultiMapSerializer.Load(&values, azrtti_typeid(&values), *m_jsonDocument, *m_jsonDeserializationContext);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
|
||||
ASSERT_FALSE(values.empty());
|
||||
EXPECT_STREQ("Hello", values.begin()->first.m_value.c_str());
|
||||
EXPECT_STREQ("Hello", values.begin()->second.m_value.c_str());
|
||||
EXPECT_STREQ(TestString().m_value.c_str(), values.begin()->second.m_value.c_str());
|
||||
}
|
||||
|
||||
TEST_F(JsonMapSerializerTests, Load_DefaultObjectValueInMultiMap_DefaultUsed)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
m_jsonDocument->Parse(R"(
|
||||
{
|
||||
"World": [{}]
|
||||
})");
|
||||
ASSERT_FALSE(m_jsonDocument->HasParseError());
|
||||
|
||||
@@ -603,7 +686,8 @@ namespace JsonSerializationTests
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
|
||||
ASSERT_FALSE(values.empty());
|
||||
EXPECT_STREQ("Hello", values.begin()->first.m_value.c_str());
|
||||
EXPECT_STREQ("World", values.begin()->first.m_value.c_str());
|
||||
EXPECT_STREQ("Hello", values.begin()->second.m_value.c_str());
|
||||
EXPECT_STREQ(TestString().m_value.c_str(), values.begin()->second.m_value.c_str());
|
||||
}
|
||||
|
||||
@@ -636,7 +720,7 @@ namespace JsonSerializationTests
|
||||
azrtti_typeid(&values), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
Expect_DocStrEq(R"(
|
||||
{
|
||||
"{}": {}
|
||||
@@ -654,7 +738,25 @@ namespace JsonSerializationTests
|
||||
azrtti_typeid(&values), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
EXPECT_EQ(Outcomes::DefaultsUsed, result.GetOutcome());
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
Expect_DocStrEq(R"(
|
||||
{
|
||||
"{}": {}
|
||||
})");
|
||||
}
|
||||
|
||||
TEST_F(JsonMapSerializerTests, Store_SingleAllDefaulValue_InitializedWithDefaults)
|
||||
{
|
||||
using namespace AZ::JsonSerializationResult;
|
||||
|
||||
SimpleClassMap values;
|
||||
values.emplace(SimpleClass(), SimpleClass());
|
||||
|
||||
ResultCode result =
|
||||
m_unorderedMapSerializer.Store(*m_jsonDocument, &values, nullptr, azrtti_typeid(&values), *m_jsonSerializationContext);
|
||||
|
||||
EXPECT_EQ(Processing::Completed, result.GetProcessing());
|
||||
EXPECT_EQ(Outcomes::PartialDefaults, result.GetOutcome());
|
||||
Expect_DocStrEq(R"(
|
||||
{
|
||||
"{}": {}
|
||||
|
||||
@@ -48,12 +48,12 @@ namespace JsonSerializationTests
|
||||
|
||||
AZStd::shared_ptr<Pair> CreateDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Pair>(142, 242.0);
|
||||
return AZStd::make_shared<Pair>(0, 0.0);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Pair> CreatePartialDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Pair>(142, 288.0);
|
||||
return AZStd::make_shared<Pair>(0, 288.0);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Pair> CreateFullySetInstance() override
|
||||
@@ -102,12 +102,12 @@ namespace JsonSerializationTests
|
||||
|
||||
AZStd::shared_ptr<Tuple> CreateDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Tuple>(142, 242.0, 342.0f);
|
||||
return AZStd::make_shared<Tuple>(0, 0.0, 0.0f);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Tuple> CreatePartialDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Tuple>(142, 288.0, 342.0f);
|
||||
return AZStd::make_shared<Tuple>(0, 288.0, 0.0f);
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Tuple> CreateFullySetInstance() override
|
||||
@@ -345,6 +345,7 @@ namespace JsonSerializationTests
|
||||
{
|
||||
TupleSerializerTestsInternal::ConfigureFeatures(features);
|
||||
features.m_supportsPartialInitialization = true;
|
||||
features.m_enableNewInstanceTests = false;
|
||||
}
|
||||
|
||||
void Reflect(AZStd::unique_ptr<AZ::SerializeContext>& context) override
|
||||
@@ -447,14 +448,14 @@ namespace JsonSerializationTests
|
||||
{
|
||||
return AZStd::make_shared<Tuple>(
|
||||
AZStd::vector<int>(),
|
||||
AZStd::make_pair(442, ""));
|
||||
AZStd::make_pair(0, ""));
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Tuple> CreatePartialDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Tuple>(
|
||||
AZStd::vector<int>(),
|
||||
AZStd::make_pair(442, "hello"));
|
||||
AZStd::make_pair(0, "hello"));
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Tuple> CreateFullySetInstance() override
|
||||
|
||||
@@ -36,6 +36,11 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<Set>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Set> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Set>(Set{ 0 });
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<Set> CreateFullySetInstance() override
|
||||
{
|
||||
return AZStd::make_shared<Set>(Set{42, -88, 342});
|
||||
@@ -80,6 +85,11 @@ namespace JsonSerializationTests
|
||||
return AZStd::make_shared<MultiSet>();
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<MultiSet> CreateSingleArrayDefaultInstance() override
|
||||
{
|
||||
return AZStd::make_shared<MultiSet>(MultiSet{ 0 });
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<MultiSet> CreateFullySetInstance() override
|
||||
{
|
||||
return AZStd::make_shared<MultiSet>(MultiSet{ 42, -88, 42, 342 });
|
||||
|
||||
@@ -48,7 +48,8 @@ namespace AzPhysics
|
||||
using OnPresimulateEvent = AZ::Event<float>;
|
||||
|
||||
//! Event triggers at the end of the SystemInterface::Simulate call.
|
||||
using OnPostsimulateEvent = AZ::Event<>;
|
||||
//! Parameter is the total time that the physics system will run for during the Simulate call.
|
||||
using OnPostsimulateEvent = AZ::Event<float>;
|
||||
|
||||
//! Event trigger when a Scene is added to the simulation.
|
||||
//! When triggered will send the handle to the new Scene.
|
||||
|
||||
@@ -402,7 +402,7 @@ namespace Physics
|
||||
->Attribute(AZ_CRC_CE("EditButton"), "")
|
||||
->Attribute(AZ_CRC_CE("EditDescription"), "Open in Asset Editor")
|
||||
->Attribute(AZ::Edit::Attributes::DefaultAsset, &MaterialSelection::GetMaterialLibraryId)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "", "")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &MaterialSelection::m_materialIdsAssignedToSlots, "Slots", "")
|
||||
->ElementAttribute(Attributes::MaterialLibraryAssetId, &MaterialSelection::GetMaterialLibraryId)
|
||||
->Attribute(AZ::Edit::Attributes::IndexedChildNameLabelOverride, &MaterialSelection::GetMaterialSlotLabel)
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace AzPhysics
|
||||
const AZ::BehaviorAzEventDescription postsimulateEventDescription =
|
||||
{
|
||||
"Postsimulate event",
|
||||
{} // Parameters
|
||||
{"Tick time"} // Parameters
|
||||
};
|
||||
|
||||
behaviorContext->Class<SystemInterface>("System Interface")
|
||||
|
||||
@@ -44,6 +44,11 @@ namespace AzNetworking
|
||||
|
||||
//! @class IConnection
|
||||
//! @brief interface class for network connections.
|
||||
//!
|
||||
//! IConnection provides a pure-virtual interface for all network connection types. IConnections provide access to
|
||||
//! a ConnectionMetrics object which provides a variety of metrics on the connection itself such as data rate, RTT and
|
||||
//! packet statistics.
|
||||
|
||||
class IConnection
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -22,6 +22,12 @@ namespace AzNetworking
|
||||
{
|
||||
//! @class IConnectionListener
|
||||
//! @brief interface class for application layer dealing with connection level events.
|
||||
//!
|
||||
//! IConnectionListener defines an abstract interface that the user of AzNetworking is expected to implement to react and
|
||||
//! handle all IConnection related events, including the handling of any received IPacket derived packets. The AzNetworking
|
||||
//! user should derive a handler class from IConnectionListener, and provide an instance of that handler to any
|
||||
//! INetworkInterface the user instantiates. The lifetime of the IConnectionListener must outlive the lifetime of the
|
||||
//! INetworkInterface.
|
||||
class IConnectionListener
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -18,6 +18,11 @@ namespace AzNetworking
|
||||
{
|
||||
//! @class IConnectionSet
|
||||
//! @brief interface class for managing a set of connections.
|
||||
//!
|
||||
//! IConnectionSet defines a simple interface for working with an abstract set of IConnections bound to an
|
||||
//! INetworkInterface. Generally users of AzNetworking will not have reason to interact directly with the IConnectionSet,
|
||||
//! as its interface is completely wrapped by INetworkInterface.
|
||||
|
||||
class IConnectionSet
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -23,10 +23,10 @@ namespace AzNetworking
|
||||
//! Collection of compression related error codes
|
||||
enum class CompressorError
|
||||
{
|
||||
Ok, ///< No error, operation finished successfully
|
||||
InsufficientBuffer, ///< Buffer size is insufficient for the operation to complete, increase the size and try again
|
||||
CorruptData, ///< Malformed or hacked packet, potentially security issue
|
||||
Uninitialized ///< Compressor or supplied buffers are uninitialized
|
||||
Ok, //!< No error, operation finished successfully
|
||||
InsufficientBuffer, //!< Buffer size is insufficient for the operation to complete, increase the size and try again
|
||||
CorruptData, //!< Malformed or hacked packet, potentially security issue
|
||||
Uninitialized //!< Compressor or supplied buffers are uninitialized
|
||||
};
|
||||
|
||||
//! Unique identifier of a given compressor
|
||||
@@ -34,6 +34,12 @@ namespace AzNetworking
|
||||
|
||||
//! @class ICompressor
|
||||
//! @brief Packet data compressor interface.
|
||||
//!
|
||||
//! ICompressor is an abstract compression interface meant for user provided GEMs to implement (such as the [Multiplayer
|
||||
//! Compression Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression)).
|
||||
//! Compression is supported for both TCP and UDP connections. Instantiation of a compressor is controlled by the
|
||||
//! `net_UdpCompressor` or `net_TcpCompressor` cvar for their respective protocols.
|
||||
|
||||
class ICompressor
|
||||
{
|
||||
public:
|
||||
@@ -87,8 +93,16 @@ namespace AzNetworking
|
||||
) = 0;
|
||||
};
|
||||
|
||||
//! Abstract factory to instantiate compressors.
|
||||
//! Used by the network interface to create a compressor
|
||||
//! @class ICompressorFactory
|
||||
//! @brief Abstract factory to instantiate compressors.
|
||||
//!
|
||||
//! ICompressorFactory is an abstract compression interface meant for user provided GEMs to implement. ICompressorFactory
|
||||
//! implementations can be registered to classes implementing INetworking. Registered factories can then be used to create
|
||||
//! ICompressor implementations on demand. The [Multiplayer Compression
|
||||
//! Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression) is an example of an ICompressorFactory
|
||||
//! for an LZ4 Compressor. In it, MultiplayerCompressionSystemComponent registers its ICompressorFactory with
|
||||
//! NetworkingSystemComponent, which is an implementation of INetworking. Registered factories are keyed by their AZ Name
|
||||
//! which is accessed through the factory's GetFactoryName method.
|
||||
class ICompressorFactory
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -22,7 +22,16 @@
|
||||
namespace AzNetworking
|
||||
{
|
||||
//! @class INetworkInterface
|
||||
//! @brief pure virtual network interface class to abstract client/server and tcp/udp concerns from application code.
|
||||
//! @brief Network interface class to abstract client/server and protocol concerns from application code.
|
||||
//!
|
||||
//! INetworkInterface provides an abstract API capable of receiving and opening IConnection objects, sending IPacket objects with optional
|
||||
//! reliability, and determining the delivery status of packets that have been sent unreliably (delivery of reliable packets
|
||||
//! is guaranteed as long as the associated connection remains open). INetworkInterface must be provided an
|
||||
//! IConnectionListener instance that outlives the INetworkInterface itself. The INetworkInterface also creates and manages
|
||||
//! the IConnectionSet, which tracks all open connections bound to the interface. INetworkInterface also provides GetMetrics
|
||||
//! functions which can be used to fetch a struct detailing a variety of metrics relating to send and receive rates for both
|
||||
//! packets and bytes in addition to the effect of features on those rates (such as packet size reduction due to compression.)
|
||||
|
||||
class INetworkInterface
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -23,6 +23,17 @@ namespace AzNetworking
|
||||
|
||||
//! @class INetworking
|
||||
//! @brief The interface for creating and working with network interfaces.
|
||||
//!
|
||||
//! INetworking is an Az::Interface<T> that provides applications access to higher level networking abstractions.
|
||||
//! AzNetworking::INetworking can be used to instantiate new INetworkInterfaces that can be configured to operate over
|
||||
//! either TCP or UDP, enable or disable encryption, and be assigned a trust level.
|
||||
//!
|
||||
//! INetworking is also responsible for registering ICompressorFactory implementations. This allows a developer to have
|
||||
//! access to multiple ICompressorFactory implementations by name. The [MultiplayerCompressor
|
||||
//! Gem](http://docs.o3de.org/docs/user-guide/gems/reference/multiplayer-compression) is an example of this using the
|
||||
//! [LZ4](https://wikipedia.org/wiki/LZ4_%28compression_algorithm%29) algorithm.
|
||||
//!
|
||||
|
||||
class INetworking
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -24,6 +24,15 @@ namespace AzNetworking
|
||||
|
||||
//! @class IPacket
|
||||
//! @brief Base class for all packets.
|
||||
//!
|
||||
//! IPacket defines an abstract interface that all packets transmitted using AzNetworking must conform to. While there are
|
||||
//! a number of core packets used internally by AzNetworking, it is fully possible for end-users to define their own custom
|
||||
//! packets using this interface. PacketType should be distinct, and should be greater than
|
||||
//! AzNetworking::CorePackets::MAX. The Serialize method allows the IPacket to be used by an
|
||||
//! ISerializer to move data between hosts safely and efficiently.
|
||||
//!
|
||||
//! For more information on the packet format and best practices for extending the packet system, read
|
||||
//! [Networking Packets](http://docs.o3de.org/docs/user-guide/networking/packets) on the O3DE documentation site.
|
||||
class IPacket
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -28,6 +28,19 @@ namespace AzNetworking
|
||||
|
||||
//! @class IPacketHeader
|
||||
//! @brief A packet header that lets us deduce packet type for any incoming packet.
|
||||
//!
|
||||
//! IPacketHeader defines an abstract interface for a descriptor of all AzNetworking::IPacket sent through AzNetworking. The
|
||||
//! PacketHeader is used to identify and describe the contents of a Packet so that transport logic can identify what
|
||||
//! additional processing steps need to be taken (if any) and what type of Packet is being inspected.
|
||||
//!
|
||||
//! The PacketFlags portion of the header represents the first byte of the header. While it can be encrypted it is
|
||||
//! otherwise not exposed to additional processing (such as an AzNetworking::ICompressor). PacketFlags are a bitfield use to provide up
|
||||
//! front information about the state of the packet. Currently there is only one flag to indicate if the Packet is
|
||||
//! compressed or not.
|
||||
//!
|
||||
//! The remainder of the header contains the PacketType and the PacketId. While the PacketFlags byte is exempt from most
|
||||
//! additional forms of processing, the remainder of the header is not.
|
||||
|
||||
class IPacketHeader
|
||||
{
|
||||
public:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user